go/src/github.com: add gopsutil library.

Also add the following dependencies:
- github.com/stretchr/testify
- github.com/davecgh/go-spew
- github.com/pmezard/go-difflib
- github.com/stretchr/objx

gopsutil will be used to collect system metrics.

Change-Id: I0e2872c45b21498eb239709249df3be73c59f10a
diff --git a/go/src/github.com/davecgh/go-spew/.gitignore b/go/src/github.com/davecgh/go-spew/.gitignore
new file mode 100644
index 0000000..0026861
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/.gitignore
@@ -0,0 +1,22 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
diff --git a/go/src/github.com/davecgh/go-spew/.travis.yml b/go/src/github.com/davecgh/go-spew/.travis.yml
new file mode 100644
index 0000000..10f469a
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/.travis.yml
@@ -0,0 +1,11 @@
+language: go
+go: 1.2
+install:
+    - go get -v code.google.com/p/go.tools/cmd/cover
+script:
+    - go test -v -tags=disableunsafe ./spew
+    - go test -v -tags=testcgo ./spew -covermode=count -coverprofile=profile.cov
+after_success:
+    - go get -v github.com/mattn/goveralls
+    - export PATH=$PATH:$HOME/gopath/bin
+    - goveralls -coverprofile=profile.cov -service=travis-ci
diff --git a/go/src/github.com/davecgh/go-spew/LICENSE b/go/src/github.com/davecgh/go-spew/LICENSE
new file mode 100644
index 0000000..2a7cfd2
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2012-2013 Dave Collins <dave@davec.name>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/go/src/github.com/davecgh/go-spew/README.google b/go/src/github.com/davecgh/go-spew/README.google
new file mode 100644
index 0000000..dadaead
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/README.google
@@ -0,0 +1,10 @@
+URL: https://github.com/davecgh/go-spew/archive/5215b55f46b2b919f50a1df0eaa5886afe4e3b3d.zip
+Version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
+License: MIT
+License File: LICENSE
+
+Description:
+Go-spew implements a deep pretty printer for Go data structures to aid in debugging.
+
+Local Modifications:
+None.
diff --git a/go/src/github.com/davecgh/go-spew/README.md b/go/src/github.com/davecgh/go-spew/README.md
new file mode 100644
index 0000000..777a8e1
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/README.md
@@ -0,0 +1,194 @@
+go-spew
+=======
+
+[![Build Status](https://travis-ci.org/davecgh/go-spew.png?branch=master)]
+(https://travis-ci.org/davecgh/go-spew) [![Coverage Status]
+(https://coveralls.io/repos/davecgh/go-spew/badge.png?branch=master)]
+(https://coveralls.io/r/davecgh/go-spew?branch=master)
+
+Go-spew implements a deep pretty printer for Go data structures to aid in
+debugging.  A comprehensive suite of tests with 100% test coverage is provided
+to ensure proper functionality.  See `test_coverage.txt` for the gocov coverage
+report.  Go-spew is licensed under the liberal ISC license, so it may be used in
+open source or commercial projects.
+
+If you're interested in reading about how this package came to life and some
+of the challenges involved in providing a deep pretty printer, there is a blog
+post about it
+[here](https://blog.cyphertite.com/go-spew-a-journey-into-dumping-go-data-structures/).
+
+## Documentation
+
+[![GoDoc](https://godoc.org/github.com/davecgh/go-spew/spew?status.png)]
+(http://godoc.org/github.com/davecgh/go-spew/spew)
+
+Full `go doc` style documentation for the project can be viewed online without
+installing this package by using the excellent GoDoc site here:
+http://godoc.org/github.com/davecgh/go-spew/spew
+
+You can also view the documentation locally once the package is installed with
+the `godoc` tool by running `godoc -http=":6060"` and pointing your browser to
+http://localhost:6060/pkg/github.com/davecgh/go-spew/spew
+
+## Installation
+
+```bash
+$ go get -u github.com/davecgh/go-spew/spew
+```
+
+## Quick Start
+
+Add this import line to the file you're working in:
+
+```Go
+import "github.com/davecgh/go-spew/spew"
+```
+
+To dump a variable with full newlines, indentation, type, and pointer
+information use Dump, Fdump, or Sdump:
+
+```Go
+spew.Dump(myVar1, myVar2, ...)
+spew.Fdump(someWriter, myVar1, myVar2, ...)
+str := spew.Sdump(myVar1, myVar2, ...)
+```
+
+Alternatively, if you would prefer to use format strings with a compacted inline
+printing style, use the convenience wrappers Printf, Fprintf, etc with %v (most
+compact), %+v (adds pointer addresses), %#v (adds types), or %#+v (adds types
+and pointer addresses): 
+
+```Go
+spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+```
+
+## Debugging a Web Application Example
+
+Here is an example of how you can use `spew.Sdump()` to help debug a web application. Please be sure to wrap your output using the `html.EscapeString()` function for safety reasons. You should also only use this debugging technique in a development environment, never in production.
+
+```Go
+package main
+
+import (
+    "fmt"
+    "html"
+    "net/http"
+
+    "github.com/davecgh/go-spew/spew"
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+    w.Header().Set("Content-Type", "text/html")
+    fmt.Fprintf(w, "Hi there, %s!", r.URL.Path[1:])
+    fmt.Fprintf(w, "<!--\n" + html.EscapeString(spew.Sdump(w)) + "\n-->")
+}
+
+func main() {
+    http.HandleFunc("/", handler)
+    http.ListenAndServe(":8080", nil)
+}
+```
+
+## Sample Dump Output
+
+```
+(main.Foo) {
+ unexportedField: (*main.Bar)(0xf84002e210)({
+  flag: (main.Flag) flagTwo,
+  data: (uintptr) <nil>
+ }),
+ ExportedField: (map[interface {}]interface {}) {
+  (string) "one": (bool) true
+ }
+}
+([]uint8) {
+ 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... |
+ 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0|
+ 00000020  31 32                                             |12|
+}
+```
+
+## Sample Formatter Output
+
+Double pointer to a uint8:
+```
+	  %v: <**>5
+	 %+v: <**>(0xf8400420d0->0xf8400420c8)5
+	 %#v: (**uint8)5
+	%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
+```
+
+Pointer to circular struct with a uint8 field and a pointer to itself:
+```
+	  %v: <*>{1 <*><shown>}
+	 %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
+	 %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
+	%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}
+```
+
+## Configuration Options
+
+Configuration of spew is handled by fields in the ConfigState type. For
+convenience, all of the top-level functions use a global state available via the
+spew.Config global.
+
+It is also possible to create a ConfigState instance that provides methods
+equivalent to the top-level functions. This allows concurrent configuration
+options. See the ConfigState documentation for more details.
+
+```
+* Indent
+	String to use for each indentation level for Dump functions.
+	It is a single space by default.  A popular alternative is "\t".
+
+* MaxDepth
+	Maximum number of levels to descend into nested data structures.
+	There is no limit by default.
+
+* DisableMethods
+	Disables invocation of error and Stringer interface methods.
+	Method invocation is enabled by default.
+
+* DisablePointerMethods
+	Disables invocation of error and Stringer interface methods on types
+	which only accept pointer receivers from non-pointer variables.  This option
+	relies on access to the unsafe package, so it will not have any effect when
+	running in environments without access to the unsafe package such as Google
+	App Engine or with the "disableunsafe" build tag specified.
+	Pointer method invocation is enabled by default.
+
+* ContinueOnMethod
+	Enables recursion into types after invoking error and Stringer interface
+	methods. Recursion after method invocation is disabled by default.
+
+* SortKeys
+	Specifies map keys should be sorted before being printed. Use
+	this to have a more deterministic, diffable output.  Note that
+	only native types (bool, int, uint, floats, uintptr and string)
+	and types which implement error or Stringer interfaces are supported,
+	with other types sorted according to the reflect.Value.String() output
+	which guarantees display stability.  Natural map order is used by
+	default.
+
+* SpewKeys
+	SpewKeys specifies that, as a last resort attempt, map keys should be
+	spewed to strings and sorted by those strings.  This is only considered
+	if SortKeys is true.
+
+```
+
+## Unsafe Package Dependency
+
+This package relies on the unsafe package to perform some of the more advanced
+features, however it also supports a "limited" mode which allows it to work in
+environments where the unsafe package is not available.  By default, it will
+operate in this mode on Google App Engine.  The "disableunsafe" build tag may
+also be specified to force the package to build without using the unsafe
+package.
+
+## License
+
+Go-spew is licensed under the liberal ISC License.
diff --git a/go/src/github.com/davecgh/go-spew/cov_report.sh b/go/src/github.com/davecgh/go-spew/cov_report.sh
new file mode 100644
index 0000000..9579497
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/cov_report.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# This script uses gocov to generate a test coverage report.
+# The gocov tool my be obtained with the following command:
+#   go get github.com/axw/gocov/gocov
+#
+# It will be installed to $GOPATH/bin, so ensure that location is in your $PATH.
+
+# Check for gocov.
+if ! type gocov >/dev/null 2>&1; then
+	echo >&2 "This script requires the gocov tool."
+	echo >&2 "You may obtain it with the following command:"
+	echo >&2 "go get github.com/axw/gocov/gocov"
+	exit 1
+fi
+
+# Only run the cgo tests if gcc is installed.
+if type gcc >/dev/null 2>&1; then
+	(cd spew && gocov test -tags testcgo | gocov report)
+else
+	(cd spew && gocov test | gocov report)
+fi
diff --git a/go/src/github.com/davecgh/go-spew/spew/bypass.go b/go/src/github.com/davecgh/go-spew/spew/bypass.go
new file mode 100644
index 0000000..565bf58
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/bypass.go
@@ -0,0 +1,151 @@
+// Copyright (c) 2015 Dave Collins <dave@davec.name>
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+// NOTE: Due to the following build constraints, this file will only be compiled
+// when the code is not running on Google App Engine and "-tags disableunsafe"
+// is not added to the go build command line.
+// +build !appengine,!disableunsafe
+
+package spew
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+const (
+	// UnsafeDisabled is a build-time constant which specifies whether or
+	// not access to the unsafe package is available.
+	UnsafeDisabled = false
+
+	// ptrSize is the size of a pointer on the current arch.
+	ptrSize = unsafe.Sizeof((*byte)(nil))
+)
+
+var (
+	// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
+	// internal reflect.Value fields.  These values are valid before golang
+	// commit ecccf07e7f9d which changed the format.  The are also valid
+	// after commit 82f48826c6c7 which changed the format again to mirror
+	// the original format.  Code in the init function updates these offsets
+	// as necessary.
+	offsetPtr    = uintptr(ptrSize)
+	offsetScalar = uintptr(0)
+	offsetFlag   = uintptr(ptrSize * 2)
+
+	// flagKindWidth and flagKindShift indicate various bits that the
+	// reflect package uses internally to track kind information.
+	//
+	// flagRO indicates whether or not the value field of a reflect.Value is
+	// read-only.
+	//
+	// flagIndir indicates whether the value field of a reflect.Value is
+	// the actual data or a pointer to the data.
+	//
+	// These values are valid before golang commit 90a7c3c86944 which
+	// changed their positions.  Code in the init function updates these
+	// flags as necessary.
+	flagKindWidth = uintptr(5)
+	flagKindShift = uintptr(flagKindWidth - 1)
+	flagRO        = uintptr(1 << 0)
+	flagIndir     = uintptr(1 << 1)
+)
+
+func init() {
+	// Older versions of reflect.Value stored small integers directly in the
+	// ptr field (which is named val in the older versions).  Versions
+	// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
+	// scalar for this purpose which unfortunately came before the flag
+	// field, so the offset of the flag field is different for those
+	// versions.
+	//
+	// This code constructs a new reflect.Value from a known small integer
+	// and checks if the size of the reflect.Value struct indicates it has
+	// the scalar field. When it does, the offsets are updated accordingly.
+	vv := reflect.ValueOf(0xf00)
+	if unsafe.Sizeof(vv) == (ptrSize * 4) {
+		offsetScalar = ptrSize * 2
+		offsetFlag = ptrSize * 3
+	}
+
+	// Commit 90a7c3c86944 changed the flag positions such that the low
+	// order bits are the kind.  This code extracts the kind from the flags
+	// field and ensures it's the correct type.  When it's not, the flag
+	// order has been changed to the newer format, so the flags are updated
+	// accordingly.
+	upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
+	upfv := *(*uintptr)(upf)
+	flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
+	if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
+		flagKindShift = 0
+		flagRO = 1 << 5
+		flagIndir = 1 << 6
+
+		// Commit adf9b30e5594 modified the flags to separate the
+		// flagRO flag into two bits which specifies whether or not the
+		// field is embedded.  This causes flagIndir to move over a bit
+		// and means that flagRO is the combination of either of the
+		// original flagRO bit and the new bit.
+		//
+		// This code detects the change by extracting what used to be
+		// the indirect bit to ensure it's set.  When it's not, the flag
+		// order has been changed to the newer format, so the flags are
+		// updated accordingly.
+		if upfv&flagIndir == 0 {
+			flagRO = 3 << 5
+			flagIndir = 1 << 7
+		}
+	}
+}
+
+// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
+// the typical safety restrictions preventing access to unaddressable and
+// unexported data.  It works by digging the raw pointer to the underlying
+// value out of the protected value and generating a new unprotected (unsafe)
+// reflect.Value to it.
+//
+// This allows us to check for implementations of the Stringer and error
+// interfaces to be used for pretty printing ordinarily unaddressable and
+// inaccessible values such as unexported struct fields.
+func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
+	indirects := 1
+	vt := v.Type()
+	upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
+	rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
+	if rvf&flagIndir != 0 {
+		vt = reflect.PtrTo(v.Type())
+		indirects++
+	} else if offsetScalar != 0 {
+		// The value is in the scalar field when it's not one of the
+		// reference types.
+		switch vt.Kind() {
+		case reflect.Uintptr:
+		case reflect.Chan:
+		case reflect.Func:
+		case reflect.Map:
+		case reflect.Ptr:
+		case reflect.UnsafePointer:
+		default:
+			upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
+				offsetScalar)
+		}
+	}
+
+	pv := reflect.NewAt(vt, upv)
+	rv = pv
+	for i := 0; i < indirects; i++ {
+		rv = rv.Elem()
+	}
+	return rv
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/bypasssafe.go b/go/src/github.com/davecgh/go-spew/spew/bypasssafe.go
new file mode 100644
index 0000000..457e412
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/bypasssafe.go
@@ -0,0 +1,37 @@
+// Copyright (c) 2015 Dave Collins <dave@davec.name>
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+// NOTE: Due to the following build constraints, this file will only be compiled
+// when either the code is running on Google App Engine or "-tags disableunsafe"
+// is added to the go build command line.
+// +build appengine disableunsafe
+
+package spew
+
+import "reflect"
+
+const (
+	// UnsafeDisabled is a build-time constant which specifies whether or
+	// not access to the unsafe package is available.
+	UnsafeDisabled = true
+)
+
+// unsafeReflectValue typically converts the passed reflect.Value into a one
+// that bypasses the typical safety restrictions preventing access to
+// unaddressable and unexported data.  However, doing this relies on access to
+// the unsafe package.  This is a stub version which simply returns the passed
+// reflect.Value when the unsafe package is not available.
+func unsafeReflectValue(v reflect.Value) reflect.Value {
+	return v
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/common.go b/go/src/github.com/davecgh/go-spew/spew/common.go
new file mode 100644
index 0000000..14f02dc
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/common.go
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"reflect"
+	"sort"
+	"strconv"
+)
+
+// Some constants in the form of bytes to avoid string overhead.  This mirrors
+// the technique used in the fmt package.
+var (
+	panicBytes            = []byte("(PANIC=")
+	plusBytes             = []byte("+")
+	iBytes                = []byte("i")
+	trueBytes             = []byte("true")
+	falseBytes            = []byte("false")
+	interfaceBytes        = []byte("(interface {})")
+	commaNewlineBytes     = []byte(",\n")
+	newlineBytes          = []byte("\n")
+	openBraceBytes        = []byte("{")
+	openBraceNewlineBytes = []byte("{\n")
+	closeBraceBytes       = []byte("}")
+	asteriskBytes         = []byte("*")
+	colonBytes            = []byte(":")
+	colonSpaceBytes       = []byte(": ")
+	openParenBytes        = []byte("(")
+	closeParenBytes       = []byte(")")
+	spaceBytes            = []byte(" ")
+	pointerChainBytes     = []byte("->")
+	nilAngleBytes         = []byte("<nil>")
+	maxNewlineBytes       = []byte("<max depth reached>\n")
+	maxShortBytes         = []byte("<max>")
+	circularBytes         = []byte("<already shown>")
+	circularShortBytes    = []byte("<shown>")
+	invalidAngleBytes     = []byte("<invalid>")
+	openBracketBytes      = []byte("[")
+	closeBracketBytes     = []byte("]")
+	percentBytes          = []byte("%")
+	precisionBytes        = []byte(".")
+	openAngleBytes        = []byte("<")
+	closeAngleBytes       = []byte(">")
+	openMapBytes          = []byte("map[")
+	closeMapBytes         = []byte("]")
+	lenEqualsBytes        = []byte("len=")
+	capEqualsBytes        = []byte("cap=")
+)
+
+// hexDigits is used to map a decimal value to a hex digit.
+var hexDigits = "0123456789abcdef"
+
+// catchPanic handles any panics that might occur during the handleMethods
+// calls.
+func catchPanic(w io.Writer, v reflect.Value) {
+	if err := recover(); err != nil {
+		w.Write(panicBytes)
+		fmt.Fprintf(w, "%v", err)
+		w.Write(closeParenBytes)
+	}
+}
+
+// handleMethods attempts to call the Error and String methods on the underlying
+// type the passed reflect.Value represents and outputes the result to Writer w.
+//
+// It handles panics in any called methods by catching and displaying the error
+// as the formatted value.
+func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
+	// We need an interface to check if the type implements the error or
+	// Stringer interface.  However, the reflect package won't give us an
+	// interface on certain things like unexported struct fields in order
+	// to enforce visibility rules.  We use unsafe, when it's available,
+	// to bypass these restrictions since this package does not mutate the
+	// values.
+	if !v.CanInterface() {
+		if UnsafeDisabled {
+			return false
+		}
+
+		v = unsafeReflectValue(v)
+	}
+
+	// Choose whether or not to do error and Stringer interface lookups against
+	// the base type or a pointer to the base type depending on settings.
+	// Technically calling one of these methods with a pointer receiver can
+	// mutate the value, however, types which choose to satisify an error or
+	// Stringer interface with a pointer receiver should not be mutating their
+	// state inside these interface methods.
+	if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
+		v = unsafeReflectValue(v)
+	}
+	if v.CanAddr() {
+		v = v.Addr()
+	}
+
+	// Is it an error or Stringer?
+	switch iface := v.Interface().(type) {
+	case error:
+		defer catchPanic(w, v)
+		if cs.ContinueOnMethod {
+			w.Write(openParenBytes)
+			w.Write([]byte(iface.Error()))
+			w.Write(closeParenBytes)
+			w.Write(spaceBytes)
+			return false
+		}
+
+		w.Write([]byte(iface.Error()))
+		return true
+
+	case fmt.Stringer:
+		defer catchPanic(w, v)
+		if cs.ContinueOnMethod {
+			w.Write(openParenBytes)
+			w.Write([]byte(iface.String()))
+			w.Write(closeParenBytes)
+			w.Write(spaceBytes)
+			return false
+		}
+		w.Write([]byte(iface.String()))
+		return true
+	}
+	return false
+}
+
+// printBool outputs a boolean value as true or false to Writer w.
+func printBool(w io.Writer, val bool) {
+	if val {
+		w.Write(trueBytes)
+	} else {
+		w.Write(falseBytes)
+	}
+}
+
+// printInt outputs a signed integer value to Writer w.
+func printInt(w io.Writer, val int64, base int) {
+	w.Write([]byte(strconv.FormatInt(val, base)))
+}
+
+// printUint outputs an unsigned integer value to Writer w.
+func printUint(w io.Writer, val uint64, base int) {
+	w.Write([]byte(strconv.FormatUint(val, base)))
+}
+
+// printFloat outputs a floating point value using the specified precision,
+// which is expected to be 32 or 64bit, to Writer w.
+func printFloat(w io.Writer, val float64, precision int) {
+	w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
+}
+
+// printComplex outputs a complex value using the specified float precision
+// for the real and imaginary parts to Writer w.
+func printComplex(w io.Writer, c complex128, floatPrecision int) {
+	r := real(c)
+	w.Write(openParenBytes)
+	w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
+	i := imag(c)
+	if i >= 0 {
+		w.Write(plusBytes)
+	}
+	w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
+	w.Write(iBytes)
+	w.Write(closeParenBytes)
+}
+
+// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
+// prefix to Writer w.
+func printHexPtr(w io.Writer, p uintptr) {
+	// Null pointer.
+	num := uint64(p)
+	if num == 0 {
+		w.Write(nilAngleBytes)
+		return
+	}
+
+	// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
+	buf := make([]byte, 18)
+
+	// It's simpler to construct the hex string right to left.
+	base := uint64(16)
+	i := len(buf) - 1
+	for num >= base {
+		buf[i] = hexDigits[num%base]
+		num /= base
+		i--
+	}
+	buf[i] = hexDigits[num]
+
+	// Add '0x' prefix.
+	i--
+	buf[i] = 'x'
+	i--
+	buf[i] = '0'
+
+	// Strip unused leading bytes.
+	buf = buf[i:]
+	w.Write(buf)
+}
+
+// valuesSorter implements sort.Interface to allow a slice of reflect.Value
+// elements to be sorted.
+type valuesSorter struct {
+	values  []reflect.Value
+	strings []string // either nil or same len and values
+	cs      *ConfigState
+}
+
+// newValuesSorter initializes a valuesSorter instance, which holds a set of
+// surrogate keys on which the data should be sorted.  It uses flags in
+// ConfigState to decide if and how to populate those surrogate keys.
+func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
+	vs := &valuesSorter{values: values, cs: cs}
+	if canSortSimply(vs.values[0].Kind()) {
+		return vs
+	}
+	if !cs.DisableMethods {
+		vs.strings = make([]string, len(values))
+		for i := range vs.values {
+			b := bytes.Buffer{}
+			if !handleMethods(cs, &b, vs.values[i]) {
+				vs.strings = nil
+				break
+			}
+			vs.strings[i] = b.String()
+		}
+	}
+	if vs.strings == nil && cs.SpewKeys {
+		vs.strings = make([]string, len(values))
+		for i := range vs.values {
+			vs.strings[i] = Sprintf("%#v", vs.values[i].Interface())
+		}
+	}
+	return vs
+}
+
+// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
+// directly, or whether it should be considered for sorting by surrogate keys
+// (if the ConfigState allows it).
+func canSortSimply(kind reflect.Kind) bool {
+	// This switch parallels valueSortLess, except for the default case.
+	switch kind {
+	case reflect.Bool:
+		return true
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+		return true
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+		return true
+	case reflect.Float32, reflect.Float64:
+		return true
+	case reflect.String:
+		return true
+	case reflect.Uintptr:
+		return true
+	case reflect.Array:
+		return true
+	}
+	return false
+}
+
+// Len returns the number of values in the slice.  It is part of the
+// sort.Interface implementation.
+func (s *valuesSorter) Len() int {
+	return len(s.values)
+}
+
+// Swap swaps the values at the passed indices.  It is part of the
+// sort.Interface implementation.
+func (s *valuesSorter) Swap(i, j int) {
+	s.values[i], s.values[j] = s.values[j], s.values[i]
+	if s.strings != nil {
+		s.strings[i], s.strings[j] = s.strings[j], s.strings[i]
+	}
+}
+
+// valueSortLess returns whether the first value should sort before the second
+// value.  It is used by valueSorter.Less as part of the sort.Interface
+// implementation.
+func valueSortLess(a, b reflect.Value) bool {
+	switch a.Kind() {
+	case reflect.Bool:
+		return !a.Bool() && b.Bool()
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+		return a.Int() < b.Int()
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+		return a.Uint() < b.Uint()
+	case reflect.Float32, reflect.Float64:
+		return a.Float() < b.Float()
+	case reflect.String:
+		return a.String() < b.String()
+	case reflect.Uintptr:
+		return a.Uint() < b.Uint()
+	case reflect.Array:
+		// Compare the contents of both arrays.
+		l := a.Len()
+		for i := 0; i < l; i++ {
+			av := a.Index(i)
+			bv := b.Index(i)
+			if av.Interface() == bv.Interface() {
+				continue
+			}
+			return valueSortLess(av, bv)
+		}
+	}
+	return a.String() < b.String()
+}
+
+// Less returns whether the value at index i should sort before the
+// value at index j.  It is part of the sort.Interface implementation.
+func (s *valuesSorter) Less(i, j int) bool {
+	if s.strings == nil {
+		return valueSortLess(s.values[i], s.values[j])
+	}
+	return s.strings[i] < s.strings[j]
+}
+
+// sortValues is a sort function that handles both native types and any type that
+// can be converted to error or Stringer.  Other inputs are sorted according to
+// their Value.String() value to ensure display stability.
+func sortValues(values []reflect.Value, cs *ConfigState) {
+	if len(values) == 0 {
+		return
+	}
+	sort.Sort(newValuesSorter(values, cs))
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/common_test.go b/go/src/github.com/davecgh/go-spew/spew/common_test.go
new file mode 100644
index 0000000..39b7525
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/common_test.go
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew_test
+
+import (
+	"fmt"
+	"reflect"
+	"testing"
+
+	"github.com/davecgh/go-spew/spew"
+)
+
+// custom type to test Stinger interface on non-pointer receiver.
+type stringer string
+
+// String implements the Stringer interface for testing invocation of custom
+// stringers on types with non-pointer receivers.
+func (s stringer) String() string {
+	return "stringer " + string(s)
+}
+
+// custom type to test Stinger interface on pointer receiver.
+type pstringer string
+
+// String implements the Stringer interface for testing invocation of custom
+// stringers on types with only pointer receivers.
+func (s *pstringer) String() string {
+	return "stringer " + string(*s)
+}
+
+// xref1 and xref2 are cross referencing structs for testing circular reference
+// detection.
+type xref1 struct {
+	ps2 *xref2
+}
+type xref2 struct {
+	ps1 *xref1
+}
+
+// indirCir1, indirCir2, and indirCir3 are used to generate an indirect circular
+// reference for testing detection.
+type indirCir1 struct {
+	ps2 *indirCir2
+}
+type indirCir2 struct {
+	ps3 *indirCir3
+}
+type indirCir3 struct {
+	ps1 *indirCir1
+}
+
+// embed is used to test embedded structures.
+type embed struct {
+	a string
+}
+
+// embedwrap is used to test embedded structures.
+type embedwrap struct {
+	*embed
+	e *embed
+}
+
+// panicer is used to intentionally cause a panic for testing spew properly
+// handles them
+type panicer int
+
+func (p panicer) String() string {
+	panic("test panic")
+}
+
+// customError is used to test custom error interface invocation.
+type customError int
+
+func (e customError) Error() string {
+	return fmt.Sprintf("error: %d", int(e))
+}
+
+// stringizeWants converts a slice of wanted test output into a format suitable
+// for a test error message.
+func stringizeWants(wants []string) string {
+	s := ""
+	for i, want := range wants {
+		if i > 0 {
+			s += fmt.Sprintf("want%d: %s", i+1, want)
+		} else {
+			s += "want: " + want
+		}
+	}
+	return s
+}
+
+// testFailed returns whether or not a test failed by checking if the result
+// of the test is in the slice of wanted strings.
+func testFailed(result string, wants []string) bool {
+	for _, want := range wants {
+		if result == want {
+			return false
+		}
+	}
+	return true
+}
+
+type sortableStruct struct {
+	x int
+}
+
+func (ss sortableStruct) String() string {
+	return fmt.Sprintf("ss.%d", ss.x)
+}
+
+type unsortableStruct struct {
+	x int
+}
+
+type sortTestCase struct {
+	input    []reflect.Value
+	expected []reflect.Value
+}
+
+func helpTestSortValues(tests []sortTestCase, cs *spew.ConfigState, t *testing.T) {
+	getInterfaces := func(values []reflect.Value) []interface{} {
+		interfaces := []interface{}{}
+		for _, v := range values {
+			interfaces = append(interfaces, v.Interface())
+		}
+		return interfaces
+	}
+
+	for _, test := range tests {
+		spew.SortValues(test.input, cs)
+		// reflect.DeepEqual cannot really make sense of reflect.Value,
+		// probably because of all the pointer tricks. For instance,
+		// v(2.0) != v(2.0) on a 32-bits system. Turn them into interface{}
+		// instead.
+		input := getInterfaces(test.input)
+		expected := getInterfaces(test.expected)
+		if !reflect.DeepEqual(input, expected) {
+			t.Errorf("Sort mismatch:\n %v != %v", input, expected)
+		}
+	}
+}
+
+// TestSortValues ensures the sort functionality for relect.Value based sorting
+// works as intended.
+func TestSortValues(t *testing.T) {
+	v := reflect.ValueOf
+
+	a := v("a")
+	b := v("b")
+	c := v("c")
+	embedA := v(embed{"a"})
+	embedB := v(embed{"b"})
+	embedC := v(embed{"c"})
+	tests := []sortTestCase{
+		// No values.
+		{
+			[]reflect.Value{},
+			[]reflect.Value{},
+		},
+		// Bools.
+		{
+			[]reflect.Value{v(false), v(true), v(false)},
+			[]reflect.Value{v(false), v(false), v(true)},
+		},
+		// Ints.
+		{
+			[]reflect.Value{v(2), v(1), v(3)},
+			[]reflect.Value{v(1), v(2), v(3)},
+		},
+		// Uints.
+		{
+			[]reflect.Value{v(uint8(2)), v(uint8(1)), v(uint8(3))},
+			[]reflect.Value{v(uint8(1)), v(uint8(2)), v(uint8(3))},
+		},
+		// Floats.
+		{
+			[]reflect.Value{v(2.0), v(1.0), v(3.0)},
+			[]reflect.Value{v(1.0), v(2.0), v(3.0)},
+		},
+		// Strings.
+		{
+			[]reflect.Value{b, a, c},
+			[]reflect.Value{a, b, c},
+		},
+		// Array
+		{
+			[]reflect.Value{v([3]int{3, 2, 1}), v([3]int{1, 3, 2}), v([3]int{1, 2, 3})},
+			[]reflect.Value{v([3]int{1, 2, 3}), v([3]int{1, 3, 2}), v([3]int{3, 2, 1})},
+		},
+		// Uintptrs.
+		{
+			[]reflect.Value{v(uintptr(2)), v(uintptr(1)), v(uintptr(3))},
+			[]reflect.Value{v(uintptr(1)), v(uintptr(2)), v(uintptr(3))},
+		},
+		// SortableStructs.
+		{
+			// Note: not sorted - DisableMethods is set.
+			[]reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
+			[]reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
+		},
+		// UnsortableStructs.
+		{
+			// Note: not sorted - SpewKeys is false.
+			[]reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
+			[]reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
+		},
+		// Invalid.
+		{
+			[]reflect.Value{embedB, embedA, embedC},
+			[]reflect.Value{embedB, embedA, embedC},
+		},
+	}
+	cs := spew.ConfigState{DisableMethods: true, SpewKeys: false}
+	helpTestSortValues(tests, &cs, t)
+}
+
+// TestSortValuesWithMethods ensures the sort functionality for relect.Value
+// based sorting works as intended when using string methods.
+func TestSortValuesWithMethods(t *testing.T) {
+	v := reflect.ValueOf
+
+	a := v("a")
+	b := v("b")
+	c := v("c")
+	tests := []sortTestCase{
+		// Ints.
+		{
+			[]reflect.Value{v(2), v(1), v(3)},
+			[]reflect.Value{v(1), v(2), v(3)},
+		},
+		// Strings.
+		{
+			[]reflect.Value{b, a, c},
+			[]reflect.Value{a, b, c},
+		},
+		// SortableStructs.
+		{
+			[]reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
+			[]reflect.Value{v(sortableStruct{1}), v(sortableStruct{2}), v(sortableStruct{3})},
+		},
+		// UnsortableStructs.
+		{
+			// Note: not sorted - SpewKeys is false.
+			[]reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
+			[]reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
+		},
+	}
+	cs := spew.ConfigState{DisableMethods: false, SpewKeys: false}
+	helpTestSortValues(tests, &cs, t)
+}
+
+// TestSortValuesWithSpew ensures the sort functionality for relect.Value
+// based sorting works as intended when using spew to stringify keys.
+func TestSortValuesWithSpew(t *testing.T) {
+	v := reflect.ValueOf
+
+	a := v("a")
+	b := v("b")
+	c := v("c")
+	tests := []sortTestCase{
+		// Ints.
+		{
+			[]reflect.Value{v(2), v(1), v(3)},
+			[]reflect.Value{v(1), v(2), v(3)},
+		},
+		// Strings.
+		{
+			[]reflect.Value{b, a, c},
+			[]reflect.Value{a, b, c},
+		},
+		// SortableStructs.
+		{
+			[]reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
+			[]reflect.Value{v(sortableStruct{1}), v(sortableStruct{2}), v(sortableStruct{3})},
+		},
+		// UnsortableStructs.
+		{
+			[]reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
+			[]reflect.Value{v(unsortableStruct{1}), v(unsortableStruct{2}), v(unsortableStruct{3})},
+		},
+	}
+	cs := spew.ConfigState{DisableMethods: true, SpewKeys: true}
+	helpTestSortValues(tests, &cs, t)
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/config.go b/go/src/github.com/davecgh/go-spew/spew/config.go
new file mode 100644
index 0000000..ee1ab07
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/config.go
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+)
+
+// ConfigState houses the configuration options used by spew to format and
+// display values.  There is a global instance, Config, that is used to control
+// all top-level Formatter and Dump functionality.  Each ConfigState instance
+// provides methods equivalent to the top-level functions.
+//
+// The zero value for ConfigState provides no indentation.  You would typically
+// want to set it to a space or a tab.
+//
+// Alternatively, you can use NewDefaultConfig to get a ConfigState instance
+// with default settings.  See the documentation of NewDefaultConfig for default
+// values.
+type ConfigState struct {
+	// Indent specifies the string to use for each indentation level.  The
+	// global config instance that all top-level functions use set this to a
+	// single space by default.  If you would like more indentation, you might
+	// set this to a tab with "\t" or perhaps two spaces with "  ".
+	Indent string
+
+	// MaxDepth controls the maximum number of levels to descend into nested
+	// data structures.  The default, 0, means there is no limit.
+	//
+	// NOTE: Circular data structures are properly detected, so it is not
+	// necessary to set this value unless you specifically want to limit deeply
+	// nested data structures.
+	MaxDepth int
+
+	// DisableMethods specifies whether or not error and Stringer interfaces are
+	// invoked for types that implement them.
+	DisableMethods bool
+
+	// DisablePointerMethods specifies whether or not to check for and invoke
+	// error and Stringer interfaces on types which only accept a pointer
+	// receiver when the current type is not a pointer.
+	//
+	// NOTE: This might be an unsafe action since calling one of these methods
+	// with a pointer receiver could technically mutate the value, however,
+	// in practice, types which choose to satisify an error or Stringer
+	// interface with a pointer receiver should not be mutating their state
+	// inside these interface methods.  As a result, this option relies on
+	// access to the unsafe package, so it will not have any effect when
+	// running in environments without access to the unsafe package such as
+	// Google App Engine or with the "disableunsafe" build tag specified.
+	DisablePointerMethods bool
+
+	// ContinueOnMethod specifies whether or not recursion should continue once
+	// a custom error or Stringer interface is invoked.  The default, false,
+	// means it will print the results of invoking the custom error or Stringer
+	// interface and return immediately instead of continuing to recurse into
+	// the internals of the data type.
+	//
+	// NOTE: This flag does not have any effect if method invocation is disabled
+	// via the DisableMethods or DisablePointerMethods options.
+	ContinueOnMethod bool
+
+	// SortKeys specifies map keys should be sorted before being printed. Use
+	// this to have a more deterministic, diffable output.  Note that only
+	// native types (bool, int, uint, floats, uintptr and string) and types
+	// that support the error or Stringer interfaces (if methods are
+	// enabled) are supported, with other types sorted according to the
+	// reflect.Value.String() output which guarantees display stability.
+	SortKeys bool
+
+	// SpewKeys specifies that, as a last resort attempt, map keys should
+	// be spewed to strings and sorted by those strings.  This is only
+	// considered if SortKeys is true.
+	SpewKeys bool
+}
+
+// Config is the active configuration of the top-level functions.
+// The configuration can be changed by modifying the contents of spew.Config.
+var Config = ConfigState{Indent: " "}
+
+// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the formatted string as a value that satisfies error.  See NewFormatter
+// for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {
+	return fmt.Errorf(format, c.convertArgs(a)...)
+}
+
+// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
+	return fmt.Fprint(w, c.convertArgs(a)...)
+}
+
+// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
+	return fmt.Fprintf(w, format, c.convertArgs(a)...)
+}
+
+// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
+// passed with a Formatter interface returned by c.NewFormatter.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
+	return fmt.Fprintln(w, c.convertArgs(a)...)
+}
+
+// Print is a wrapper for fmt.Print that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
+	return fmt.Print(c.convertArgs(a)...)
+}
+
+// Printf is a wrapper for fmt.Printf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {
+	return fmt.Printf(format, c.convertArgs(a)...)
+}
+
+// Println is a wrapper for fmt.Println that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
+	return fmt.Println(c.convertArgs(a)...)
+}
+
+// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Sprint(a ...interface{}) string {
+	return fmt.Sprint(c.convertArgs(a)...)
+}
+
+// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
+	return fmt.Sprintf(format, c.convertArgs(a)...)
+}
+
+// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
+// were passed with a Formatter interface returned by c.NewFormatter.  It
+// returns the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Sprintln(a ...interface{}) string {
+	return fmt.Sprintln(c.convertArgs(a)...)
+}
+
+/*
+NewFormatter returns a custom formatter that satisfies the fmt.Formatter
+interface.  As a result, it integrates cleanly with standard fmt package
+printing functions.  The formatter is useful for inline printing of smaller data
+types similar to the standard %v format specifier.
+
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
+addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
+combinations.  Any other verbs such as %x and %q will be sent to the the
+standard fmt package for formatting.  In addition, the custom formatter ignores
+the width and precision arguments (however they will still work on the format
+specifiers not handled by the custom formatter).
+
+Typically this function shouldn't be called directly.  It is much easier to make
+use of the custom formatter by calling one of the convenience functions such as
+c.Printf, c.Println, or c.Printf.
+*/
+func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
+	return newFormatter(c, v)
+}
+
+// Fdump formats and displays the passed arguments to io.Writer w.  It formats
+// exactly the same as Dump.
+func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
+	fdump(c, w, a...)
+}
+
+/*
+Dump displays the passed parameters to standard out with newlines, customizable
+indentation, and additional debug information such as complete types and all
+pointer addresses used to indirect to the final value.  It provides the
+following features over the built-in printing facilities provided by the fmt
+package:
+
+	* Pointers are dereferenced and followed
+	* Circular data structures are detected and handled properly
+	* Custom Stringer/error interfaces are optionally invoked, including
+	  on unexported types
+	* Custom types which only implement the Stringer/error interfaces via
+	  a pointer receiver are optionally invoked when passing non-pointer
+	  variables
+	* Byte arrays and slices are dumped like the hexdump -C command which
+	  includes offsets, byte values in hex, and ASCII output
+
+The configuration options are controlled by modifying the public members
+of c.  See ConfigState for options documentation.
+
+See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
+get the formatted result as a string.
+*/
+func (c *ConfigState) Dump(a ...interface{}) {
+	fdump(c, os.Stdout, a...)
+}
+
+// Sdump returns a string with the passed arguments formatted exactly the same
+// as Dump.
+func (c *ConfigState) Sdump(a ...interface{}) string {
+	var buf bytes.Buffer
+	fdump(c, &buf, a...)
+	return buf.String()
+}
+
+// convertArgs accepts a slice of arguments and returns a slice of the same
+// length with each argument converted to a spew Formatter interface using
+// the ConfigState associated with s.
+func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {
+	formatters = make([]interface{}, len(args))
+	for index, arg := range args {
+		formatters[index] = newFormatter(c, arg)
+	}
+	return formatters
+}
+
+// NewDefaultConfig returns a ConfigState with the following default settings.
+//
+// 	Indent: " "
+// 	MaxDepth: 0
+// 	DisableMethods: false
+// 	DisablePointerMethods: false
+// 	ContinueOnMethod: false
+// 	SortKeys: false
+func NewDefaultConfig() *ConfigState {
+	return &ConfigState{Indent: " "}
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/doc.go b/go/src/github.com/davecgh/go-spew/spew/doc.go
new file mode 100644
index 0000000..5be0c40
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/doc.go
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+Package spew implements a deep pretty printer for Go data structures to aid in
+debugging.
+
+A quick overview of the additional features spew provides over the built-in
+printing facilities for Go data types are as follows:
+
+	* Pointers are dereferenced and followed
+	* Circular data structures are detected and handled properly
+	* Custom Stringer/error interfaces are optionally invoked, including
+	  on unexported types
+	* Custom types which only implement the Stringer/error interfaces via
+	  a pointer receiver are optionally invoked when passing non-pointer
+	  variables
+	* Byte arrays and slices are dumped like the hexdump -C command which
+	  includes offsets, byte values in hex, and ASCII output (only when using
+	  Dump style)
+
+There are two different approaches spew allows for dumping Go data structures:
+
+	* Dump style which prints with newlines, customizable indentation,
+	  and additional debug information such as types and all pointer addresses
+	  used to indirect to the final value
+	* A custom Formatter interface that integrates cleanly with the standard fmt
+	  package and replaces %v, %+v, %#v, and %#+v to provide inline printing
+	  similar to the default %v while providing the additional functionality
+	  outlined above and passing unsupported format verbs such as %x and %q
+	  along to fmt
+
+Quick Start
+
+This section demonstrates how to quickly get started with spew.  See the
+sections below for further details on formatting and configuration options.
+
+To dump a variable with full newlines, indentation, type, and pointer
+information use Dump, Fdump, or Sdump:
+	spew.Dump(myVar1, myVar2, ...)
+	spew.Fdump(someWriter, myVar1, myVar2, ...)
+	str := spew.Sdump(myVar1, myVar2, ...)
+
+Alternatively, if you would prefer to use format strings with a compacted inline
+printing style, use the convenience wrappers Printf, Fprintf, etc with
+%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
+%#+v (adds types and pointer addresses):
+	spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+	spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+	spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+	spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+
+Configuration Options
+
+Configuration of spew is handled by fields in the ConfigState type.  For
+convenience, all of the top-level functions use a global state available
+via the spew.Config global.
+
+It is also possible to create a ConfigState instance that provides methods
+equivalent to the top-level functions.  This allows concurrent configuration
+options.  See the ConfigState documentation for more details.
+
+The following configuration options are available:
+	* Indent
+		String to use for each indentation level for Dump functions.
+		It is a single space by default.  A popular alternative is "\t".
+
+	* MaxDepth
+		Maximum number of levels to descend into nested data structures.
+		There is no limit by default.
+
+	* DisableMethods
+		Disables invocation of error and Stringer interface methods.
+		Method invocation is enabled by default.
+
+	* DisablePointerMethods
+		Disables invocation of error and Stringer interface methods on types
+		which only accept pointer receivers from non-pointer variables.
+		Pointer method invocation is enabled by default.
+
+	* ContinueOnMethod
+		Enables recursion into types after invoking error and Stringer interface
+		methods. Recursion after method invocation is disabled by default.
+
+	* SortKeys
+		Specifies map keys should be sorted before being printed. Use
+		this to have a more deterministic, diffable output.  Note that
+		only native types (bool, int, uint, floats, uintptr and string)
+		and types which implement error or Stringer interfaces are
+		supported with other types sorted according to the
+		reflect.Value.String() output which guarantees display
+		stability.  Natural map order is used by default.
+
+	* SpewKeys
+		Specifies that, as a last resort attempt, map keys should be
+		spewed to strings and sorted by those strings.  This is only
+		considered if SortKeys is true.
+
+Dump Usage
+
+Simply call spew.Dump with a list of variables you want to dump:
+
+	spew.Dump(myVar1, myVar2, ...)
+
+You may also call spew.Fdump if you would prefer to output to an arbitrary
+io.Writer.  For example, to dump to standard error:
+
+	spew.Fdump(os.Stderr, myVar1, myVar2, ...)
+
+A third option is to call spew.Sdump to get the formatted output as a string:
+
+	str := spew.Sdump(myVar1, myVar2, ...)
+
+Sample Dump Output
+
+See the Dump example for details on the setup of the types and variables being
+shown here.
+
+	(main.Foo) {
+	 unexportedField: (*main.Bar)(0xf84002e210)({
+	  flag: (main.Flag) flagTwo,
+	  data: (uintptr) <nil>
+	 }),
+	 ExportedField: (map[interface {}]interface {}) (len=1) {
+	  (string) (len=3) "one": (bool) true
+	 }
+	}
+
+Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
+command as shown.
+	([]uint8) (len=32 cap=32) {
+	 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... |
+	 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0|
+	 00000020  31 32                                             |12|
+	}
+
+Custom Formatter
+
+Spew provides a custom formatter that implements the fmt.Formatter interface
+so that it integrates cleanly with standard fmt package printing functions. The
+formatter is useful for inline printing of smaller data types similar to the
+standard %v format specifier.
+
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
+addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
+combinations.  Any other verbs such as %x and %q will be sent to the the
+standard fmt package for formatting.  In addition, the custom formatter ignores
+the width and precision arguments (however they will still work on the format
+specifiers not handled by the custom formatter).
+
+Custom Formatter Usage
+
+The simplest way to make use of the spew custom formatter is to call one of the
+convenience functions such as spew.Printf, spew.Println, or spew.Printf.  The
+functions have syntax you are most likely already familiar with:
+
+	spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+	spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+	spew.Println(myVar, myVar2)
+	spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+	spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+
+See the Index for the full list convenience functions.
+
+Sample Formatter Output
+
+Double pointer to a uint8:
+	  %v: <**>5
+	 %+v: <**>(0xf8400420d0->0xf8400420c8)5
+	 %#v: (**uint8)5
+	%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
+
+Pointer to circular struct with a uint8 field and a pointer to itself:
+	  %v: <*>{1 <*><shown>}
+	 %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
+	 %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
+	%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}
+
+See the Printf example for details on the setup of variables being shown
+here.
+
+Errors
+
+Since it is possible for custom Stringer/error interfaces to panic, spew
+detects them and handles them internally by printing the panic information
+inline with the output.  Since spew is intended to provide deep pretty printing
+capabilities on structures, it intentionally does not return any errors.
+*/
+package spew
diff --git a/go/src/github.com/davecgh/go-spew/spew/dump.go b/go/src/github.com/davecgh/go-spew/spew/dump.go
new file mode 100644
index 0000000..a0ff95e
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/dump.go
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+	"bytes"
+	"encoding/hex"
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+var (
+	// uint8Type is a reflect.Type representing a uint8.  It is used to
+	// convert cgo types to uint8 slices for hexdumping.
+	uint8Type = reflect.TypeOf(uint8(0))
+
+	// cCharRE is a regular expression that matches a cgo char.
+	// It is used to detect character arrays to hexdump them.
+	cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
+
+	// cUnsignedCharRE is a regular expression that matches a cgo unsigned
+	// char.  It is used to detect unsigned character arrays to hexdump
+	// them.
+	cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
+
+	// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
+	// It is used to detect uint8_t arrays to hexdump them.
+	cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
+)
+
+// dumpState contains information about the state of a dump operation.
+type dumpState struct {
+	w                io.Writer
+	depth            int
+	pointers         map[uintptr]int
+	ignoreNextType   bool
+	ignoreNextIndent bool
+	cs               *ConfigState
+}
+
+// indent performs indentation according to the depth level and cs.Indent
+// option.
+func (d *dumpState) indent() {
+	if d.ignoreNextIndent {
+		d.ignoreNextIndent = false
+		return
+	}
+	d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
+}
+
+// unpackValue returns values inside of non-nil interfaces when possible.
+// This is useful for data types like structs, arrays, slices, and maps which
+// can contain varying types packed inside an interface.
+func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
+	if v.Kind() == reflect.Interface && !v.IsNil() {
+		v = v.Elem()
+	}
+	return v
+}
+
+// dumpPtr handles formatting of pointers by indirecting them as necessary.
+func (d *dumpState) dumpPtr(v reflect.Value) {
+	// Remove pointers at or below the current depth from map used to detect
+	// circular refs.
+	for k, depth := range d.pointers {
+		if depth >= d.depth {
+			delete(d.pointers, k)
+		}
+	}
+
+	// Keep list of all dereferenced pointers to show later.
+	pointerChain := make([]uintptr, 0)
+
+	// Figure out how many levels of indirection there are by dereferencing
+	// pointers and unpacking interfaces down the chain while detecting circular
+	// references.
+	nilFound := false
+	cycleFound := false
+	indirects := 0
+	ve := v
+	for ve.Kind() == reflect.Ptr {
+		if ve.IsNil() {
+			nilFound = true
+			break
+		}
+		indirects++
+		addr := ve.Pointer()
+		pointerChain = append(pointerChain, addr)
+		if pd, ok := d.pointers[addr]; ok && pd < d.depth {
+			cycleFound = true
+			indirects--
+			break
+		}
+		d.pointers[addr] = d.depth
+
+		ve = ve.Elem()
+		if ve.Kind() == reflect.Interface {
+			if ve.IsNil() {
+				nilFound = true
+				break
+			}
+			ve = ve.Elem()
+		}
+	}
+
+	// Display type information.
+	d.w.Write(openParenBytes)
+	d.w.Write(bytes.Repeat(asteriskBytes, indirects))
+	d.w.Write([]byte(ve.Type().String()))
+	d.w.Write(closeParenBytes)
+
+	// Display pointer information.
+	if len(pointerChain) > 0 {
+		d.w.Write(openParenBytes)
+		for i, addr := range pointerChain {
+			if i > 0 {
+				d.w.Write(pointerChainBytes)
+			}
+			printHexPtr(d.w, addr)
+		}
+		d.w.Write(closeParenBytes)
+	}
+
+	// Display dereferenced value.
+	d.w.Write(openParenBytes)
+	switch {
+	case nilFound == true:
+		d.w.Write(nilAngleBytes)
+
+	case cycleFound == true:
+		d.w.Write(circularBytes)
+
+	default:
+		d.ignoreNextType = true
+		d.dump(ve)
+	}
+	d.w.Write(closeParenBytes)
+}
+
+// dumpSlice handles formatting of arrays and slices.  Byte (uint8 under
+// reflection) arrays and slices are dumped in hexdump -C fashion.
+func (d *dumpState) dumpSlice(v reflect.Value) {
+	// Determine whether this type should be hex dumped or not.  Also,
+	// for types which should be hexdumped, try to use the underlying data
+	// first, then fall back to trying to convert them to a uint8 slice.
+	var buf []uint8
+	doConvert := false
+	doHexDump := false
+	numEntries := v.Len()
+	if numEntries > 0 {
+		vt := v.Index(0).Type()
+		vts := vt.String()
+		switch {
+		// C types that need to be converted.
+		case cCharRE.MatchString(vts):
+			fallthrough
+		case cUnsignedCharRE.MatchString(vts):
+			fallthrough
+		case cUint8tCharRE.MatchString(vts):
+			doConvert = true
+
+		// Try to use existing uint8 slices and fall back to converting
+		// and copying if that fails.
+		case vt.Kind() == reflect.Uint8:
+			// We need an addressable interface to convert the type
+			// to a byte slice.  However, the reflect package won't
+			// give us an interface on certain things like
+			// unexported struct fields in order to enforce
+			// visibility rules.  We use unsafe, when available, to
+			// bypass these restrictions since this package does not
+			// mutate the values.
+			vs := v
+			if !vs.CanInterface() || !vs.CanAddr() {
+				vs = unsafeReflectValue(vs)
+			}
+			if !UnsafeDisabled {
+				vs = vs.Slice(0, numEntries)
+
+				// Use the existing uint8 slice if it can be
+				// type asserted.
+				iface := vs.Interface()
+				if slice, ok := iface.([]uint8); ok {
+					buf = slice
+					doHexDump = true
+					break
+				}
+			}
+
+			// The underlying data needs to be converted if it can't
+			// be type asserted to a uint8 slice.
+			doConvert = true
+		}
+
+		// Copy and convert the underlying type if needed.
+		if doConvert && vt.ConvertibleTo(uint8Type) {
+			// Convert and copy each element into a uint8 byte
+			// slice.
+			buf = make([]uint8, numEntries)
+			for i := 0; i < numEntries; i++ {
+				vv := v.Index(i)
+				buf[i] = uint8(vv.Convert(uint8Type).Uint())
+			}
+			doHexDump = true
+		}
+	}
+
+	// Hexdump the entire slice as needed.
+	if doHexDump {
+		indent := strings.Repeat(d.cs.Indent, d.depth)
+		str := indent + hex.Dump(buf)
+		str = strings.Replace(str, "\n", "\n"+indent, -1)
+		str = strings.TrimRight(str, d.cs.Indent)
+		d.w.Write([]byte(str))
+		return
+	}
+
+	// Recursively call dump for each item.
+	for i := 0; i < numEntries; i++ {
+		d.dump(d.unpackValue(v.Index(i)))
+		if i < (numEntries - 1) {
+			d.w.Write(commaNewlineBytes)
+		} else {
+			d.w.Write(newlineBytes)
+		}
+	}
+}
+
+// dump is the main workhorse for dumping a value.  It uses the passed reflect
+// value to figure out what kind of object we are dealing with and formats it
+// appropriately.  It is a recursive function, however circular data structures
+// are detected and handled properly.
+func (d *dumpState) dump(v reflect.Value) {
+	// Handle invalid reflect values immediately.
+	kind := v.Kind()
+	if kind == reflect.Invalid {
+		d.w.Write(invalidAngleBytes)
+		return
+	}
+
+	// Handle pointers specially.
+	if kind == reflect.Ptr {
+		d.indent()
+		d.dumpPtr(v)
+		return
+	}
+
+	// Print type information unless already handled elsewhere.
+	if !d.ignoreNextType {
+		d.indent()
+		d.w.Write(openParenBytes)
+		d.w.Write([]byte(v.Type().String()))
+		d.w.Write(closeParenBytes)
+		d.w.Write(spaceBytes)
+	}
+	d.ignoreNextType = false
+
+	// Display length and capacity if the built-in len and cap functions
+	// work with the value's kind and the len/cap itself is non-zero.
+	valueLen, valueCap := 0, 0
+	switch v.Kind() {
+	case reflect.Array, reflect.Slice, reflect.Chan:
+		valueLen, valueCap = v.Len(), v.Cap()
+	case reflect.Map, reflect.String:
+		valueLen = v.Len()
+	}
+	if valueLen != 0 || valueCap != 0 {
+		d.w.Write(openParenBytes)
+		if valueLen != 0 {
+			d.w.Write(lenEqualsBytes)
+			printInt(d.w, int64(valueLen), 10)
+		}
+		if valueCap != 0 {
+			if valueLen != 0 {
+				d.w.Write(spaceBytes)
+			}
+			d.w.Write(capEqualsBytes)
+			printInt(d.w, int64(valueCap), 10)
+		}
+		d.w.Write(closeParenBytes)
+		d.w.Write(spaceBytes)
+	}
+
+	// Call Stringer/error interfaces if they exist and the handle methods flag
+	// is enabled
+	if !d.cs.DisableMethods {
+		if (kind != reflect.Invalid) && (kind != reflect.Interface) {
+			if handled := handleMethods(d.cs, d.w, v); handled {
+				return
+			}
+		}
+	}
+
+	switch kind {
+	case reflect.Invalid:
+		// Do nothing.  We should never get here since invalid has already
+		// been handled above.
+
+	case reflect.Bool:
+		printBool(d.w, v.Bool())
+
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+		printInt(d.w, v.Int(), 10)
+
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+		printUint(d.w, v.Uint(), 10)
+
+	case reflect.Float32:
+		printFloat(d.w, v.Float(), 32)
+
+	case reflect.Float64:
+		printFloat(d.w, v.Float(), 64)
+
+	case reflect.Complex64:
+		printComplex(d.w, v.Complex(), 32)
+
+	case reflect.Complex128:
+		printComplex(d.w, v.Complex(), 64)
+
+	case reflect.Slice:
+		if v.IsNil() {
+			d.w.Write(nilAngleBytes)
+			break
+		}
+		fallthrough
+
+	case reflect.Array:
+		d.w.Write(openBraceNewlineBytes)
+		d.depth++
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
+			d.indent()
+			d.w.Write(maxNewlineBytes)
+		} else {
+			d.dumpSlice(v)
+		}
+		d.depth--
+		d.indent()
+		d.w.Write(closeBraceBytes)
+
+	case reflect.String:
+		d.w.Write([]byte(strconv.Quote(v.String())))
+
+	case reflect.Interface:
+		// The only time we should get here is for nil interfaces due to
+		// unpackValue calls.
+		if v.IsNil() {
+			d.w.Write(nilAngleBytes)
+		}
+
+	case reflect.Ptr:
+		// Do nothing.  We should never get here since pointers have already
+		// been handled above.
+
+	case reflect.Map:
+		// nil maps should be indicated as different than empty maps
+		if v.IsNil() {
+			d.w.Write(nilAngleBytes)
+			break
+		}
+
+		d.w.Write(openBraceNewlineBytes)
+		d.depth++
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
+			d.indent()
+			d.w.Write(maxNewlineBytes)
+		} else {
+			numEntries := v.Len()
+			keys := v.MapKeys()
+			if d.cs.SortKeys {
+				sortValues(keys, d.cs)
+			}
+			for i, key := range keys {
+				d.dump(d.unpackValue(key))
+				d.w.Write(colonSpaceBytes)
+				d.ignoreNextIndent = true
+				d.dump(d.unpackValue(v.MapIndex(key)))
+				if i < (numEntries - 1) {
+					d.w.Write(commaNewlineBytes)
+				} else {
+					d.w.Write(newlineBytes)
+				}
+			}
+		}
+		d.depth--
+		d.indent()
+		d.w.Write(closeBraceBytes)
+
+	case reflect.Struct:
+		d.w.Write(openBraceNewlineBytes)
+		d.depth++
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
+			d.indent()
+			d.w.Write(maxNewlineBytes)
+		} else {
+			vt := v.Type()
+			numFields := v.NumField()
+			for i := 0; i < numFields; i++ {
+				d.indent()
+				vtf := vt.Field(i)
+				d.w.Write([]byte(vtf.Name))
+				d.w.Write(colonSpaceBytes)
+				d.ignoreNextIndent = true
+				d.dump(d.unpackValue(v.Field(i)))
+				if i < (numFields - 1) {
+					d.w.Write(commaNewlineBytes)
+				} else {
+					d.w.Write(newlineBytes)
+				}
+			}
+		}
+		d.depth--
+		d.indent()
+		d.w.Write(closeBraceBytes)
+
+	case reflect.Uintptr:
+		printHexPtr(d.w, uintptr(v.Uint()))
+
+	case reflect.UnsafePointer, reflect.Chan, reflect.Func:
+		printHexPtr(d.w, v.Pointer())
+
+	// There were not any other types at the time this code was written, but
+	// fall back to letting the default fmt package handle it in case any new
+	// types are added.
+	default:
+		if v.CanInterface() {
+			fmt.Fprintf(d.w, "%v", v.Interface())
+		} else {
+			fmt.Fprintf(d.w, "%v", v.String())
+		}
+	}
+}
+
+// fdump is a helper function to consolidate the logic from the various public
+// methods which take varying writers and config states.
+func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
+	for _, arg := range a {
+		if arg == nil {
+			w.Write(interfaceBytes)
+			w.Write(spaceBytes)
+			w.Write(nilAngleBytes)
+			w.Write(newlineBytes)
+			continue
+		}
+
+		d := dumpState{w: w, cs: cs}
+		d.pointers = make(map[uintptr]int)
+		d.dump(reflect.ValueOf(arg))
+		d.w.Write(newlineBytes)
+	}
+}
+
+// Fdump formats and displays the passed arguments to io.Writer w.  It formats
+// exactly the same as Dump.
+func Fdump(w io.Writer, a ...interface{}) {
+	fdump(&Config, w, a...)
+}
+
+// Sdump returns a string with the passed arguments formatted exactly the same
+// as Dump.
+func Sdump(a ...interface{}) string {
+	var buf bytes.Buffer
+	fdump(&Config, &buf, a...)
+	return buf.String()
+}
+
+/*
+Dump displays the passed parameters to standard out with newlines, customizable
+indentation, and additional debug information such as complete types and all
+pointer addresses used to indirect to the final value.  It provides the
+following features over the built-in printing facilities provided by the fmt
+package:
+
+	* Pointers are dereferenced and followed
+	* Circular data structures are detected and handled properly
+	* Custom Stringer/error interfaces are optionally invoked, including
+	  on unexported types
+	* Custom types which only implement the Stringer/error interfaces via
+	  a pointer receiver are optionally invoked when passing non-pointer
+	  variables
+	* Byte arrays and slices are dumped like the hexdump -C command which
+	  includes offsets, byte values in hex, and ASCII output
+
+The configuration options are controlled by an exported package global,
+spew.Config.  See ConfigState for options documentation.
+
+See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
+get the formatted result as a string.
+*/
+func Dump(a ...interface{}) {
+	fdump(&Config, os.Stdout, a...)
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/dump_test.go b/go/src/github.com/davecgh/go-spew/spew/dump_test.go
new file mode 100644
index 0000000..2b32040
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/dump_test.go
@@ -0,0 +1,1042 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+Test Summary:
+NOTE: For each test, a nil pointer, a single pointer and double pointer to the
+base test element are also tested to ensure proper indirection across all types.
+
+- Max int8, int16, int32, int64, int
+- Max uint8, uint16, uint32, uint64, uint
+- Boolean true and false
+- Standard complex64 and complex128
+- Array containing standard ints
+- Array containing type with custom formatter on pointer receiver only
+- Array containing interfaces
+- Array containing bytes
+- Slice containing standard float32 values
+- Slice containing type with custom formatter on pointer receiver only
+- Slice containing interfaces
+- Slice containing bytes
+- Nil slice
+- Standard string
+- Nil interface
+- Sub-interface
+- Map with string keys and int vals
+- Map with custom formatter type on pointer receiver only keys and vals
+- Map with interface keys and values
+- Map with nil interface value
+- Struct with primitives
+- Struct that contains another struct
+- Struct that contains custom type with Stringer pointer interface via both
+  exported and unexported fields
+- Struct that contains embedded struct and field to same struct
+- Uintptr to 0 (null pointer)
+- Uintptr address of real variable
+- Unsafe.Pointer to 0 (null pointer)
+- Unsafe.Pointer to address of real variable
+- Nil channel
+- Standard int channel
+- Function with no params and no returns
+- Function with param and no returns
+- Function with multiple params and multiple returns
+- Struct that is circular through self referencing
+- Structs that are circular through cross referencing
+- Structs that are indirectly circular
+- Type that panics in its Stringer interface
+*/
+
+package spew_test
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+	"unsafe"
+
+	"github.com/davecgh/go-spew/spew"
+)
+
+// dumpTest is used to describe a test to be perfomed against the Dump method.
+type dumpTest struct {
+	in    interface{}
+	wants []string
+}
+
+// dumpTests houses all of the tests to be performed against the Dump method.
+var dumpTests = make([]dumpTest, 0)
+
+// addDumpTest is a helper method to append the passed input and desired result
+// to dumpTests
+func addDumpTest(in interface{}, wants ...string) {
+	test := dumpTest{in, wants}
+	dumpTests = append(dumpTests, test)
+}
+
+func addIntDumpTests() {
+	// Max int8.
+	v := int8(127)
+	nv := (*int8)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "int8"
+	vs := "127"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+
+	// Max int16.
+	v2 := int16(32767)
+	nv2 := (*int16)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "int16"
+	v2s := "32767"
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+	addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
+
+	// Max int32.
+	v3 := int32(2147483647)
+	nv3 := (*int32)(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "int32"
+	v3s := "2147483647"
+	addDumpTest(v3, "("+v3t+") "+v3s+"\n")
+	addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
+	addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
+	addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
+
+	// Max int64.
+	v4 := int64(9223372036854775807)
+	nv4 := (*int64)(nil)
+	pv4 := &v4
+	v4Addr := fmt.Sprintf("%p", pv4)
+	pv4Addr := fmt.Sprintf("%p", &pv4)
+	v4t := "int64"
+	v4s := "9223372036854775807"
+	addDumpTest(v4, "("+v4t+") "+v4s+"\n")
+	addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
+	addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
+	addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
+
+	// Max int.
+	v5 := int(2147483647)
+	nv5 := (*int)(nil)
+	pv5 := &v5
+	v5Addr := fmt.Sprintf("%p", pv5)
+	pv5Addr := fmt.Sprintf("%p", &pv5)
+	v5t := "int"
+	v5s := "2147483647"
+	addDumpTest(v5, "("+v5t+") "+v5s+"\n")
+	addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
+	addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
+	addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
+}
+
+func addUintDumpTests() {
+	// Max uint8.
+	v := uint8(255)
+	nv := (*uint8)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "uint8"
+	vs := "255"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+
+	// Max uint16.
+	v2 := uint16(65535)
+	nv2 := (*uint16)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "uint16"
+	v2s := "65535"
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+	addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
+
+	// Max uint32.
+	v3 := uint32(4294967295)
+	nv3 := (*uint32)(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "uint32"
+	v3s := "4294967295"
+	addDumpTest(v3, "("+v3t+") "+v3s+"\n")
+	addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
+	addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
+	addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
+
+	// Max uint64.
+	v4 := uint64(18446744073709551615)
+	nv4 := (*uint64)(nil)
+	pv4 := &v4
+	v4Addr := fmt.Sprintf("%p", pv4)
+	pv4Addr := fmt.Sprintf("%p", &pv4)
+	v4t := "uint64"
+	v4s := "18446744073709551615"
+	addDumpTest(v4, "("+v4t+") "+v4s+"\n")
+	addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
+	addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
+	addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
+
+	// Max uint.
+	v5 := uint(4294967295)
+	nv5 := (*uint)(nil)
+	pv5 := &v5
+	v5Addr := fmt.Sprintf("%p", pv5)
+	pv5Addr := fmt.Sprintf("%p", &pv5)
+	v5t := "uint"
+	v5s := "4294967295"
+	addDumpTest(v5, "("+v5t+") "+v5s+"\n")
+	addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
+	addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
+	addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
+}
+
+func addBoolDumpTests() {
+	// Boolean true.
+	v := bool(true)
+	nv := (*bool)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "bool"
+	vs := "true"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+
+	// Boolean false.
+	v2 := bool(false)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "bool"
+	v2s := "false"
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+}
+
+func addFloatDumpTests() {
+	// Standard float32.
+	v := float32(3.1415)
+	nv := (*float32)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "float32"
+	vs := "3.1415"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+
+	// Standard float64.
+	v2 := float64(3.1415926)
+	nv2 := (*float64)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "float64"
+	v2s := "3.1415926"
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+	addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
+}
+
+func addComplexDumpTests() {
+	// Standard complex64.
+	v := complex(float32(6), -2)
+	nv := (*complex64)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "complex64"
+	vs := "(6-2i)"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+
+	// Standard complex128.
+	v2 := complex(float64(-6), 2)
+	nv2 := (*complex128)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "complex128"
+	v2s := "(-6+2i)"
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+	addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
+}
+
+func addArrayDumpTests() {
+	// Array containing standard ints.
+	v := [3]int{1, 2, 3}
+	vLen := fmt.Sprintf("%d", len(v))
+	vCap := fmt.Sprintf("%d", cap(v))
+	nv := (*[3]int)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "int"
+	vs := "(len=" + vLen + " cap=" + vCap + ") {\n (" + vt + ") 1,\n (" +
+		vt + ") 2,\n (" + vt + ") 3\n}"
+	addDumpTest(v, "([3]"+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*[3]"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**[3]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*[3]"+vt+")(<nil>)\n")
+
+	// Array containing type with custom formatter on pointer receiver only.
+	v2i0 := pstringer("1")
+	v2i1 := pstringer("2")
+	v2i2 := pstringer("3")
+	v2 := [3]pstringer{v2i0, v2i1, v2i2}
+	v2i0Len := fmt.Sprintf("%d", len(v2i0))
+	v2i1Len := fmt.Sprintf("%d", len(v2i1))
+	v2i2Len := fmt.Sprintf("%d", len(v2i2))
+	v2Len := fmt.Sprintf("%d", len(v2))
+	v2Cap := fmt.Sprintf("%d", cap(v2))
+	nv2 := (*[3]pstringer)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "spew_test.pstringer"
+	v2sp := "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t +
+		") (len=" + v2i0Len + ") stringer 1,\n (" + v2t +
+		") (len=" + v2i1Len + ") stringer 2,\n (" + v2t +
+		") (len=" + v2i2Len + ") " + "stringer 3\n}"
+	v2s := v2sp
+	if spew.UnsafeDisabled {
+		v2s = "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t +
+			") (len=" + v2i0Len + ") \"1\",\n (" + v2t + ") (len=" +
+			v2i1Len + ") \"2\",\n (" + v2t + ") (len=" + v2i2Len +
+			") " + "\"3\"\n}"
+	}
+	addDumpTest(v2, "([3]"+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*[3]"+v2t+")("+v2Addr+")("+v2sp+")\n")
+	addDumpTest(&pv2, "(**[3]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2sp+")\n")
+	addDumpTest(nv2, "(*[3]"+v2t+")(<nil>)\n")
+
+	// Array containing interfaces.
+	v3i0 := "one"
+	v3 := [3]interface{}{v3i0, int(2), uint(3)}
+	v3i0Len := fmt.Sprintf("%d", len(v3i0))
+	v3Len := fmt.Sprintf("%d", len(v3))
+	v3Cap := fmt.Sprintf("%d", cap(v3))
+	nv3 := (*[3]interface{})(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "[3]interface {}"
+	v3t2 := "string"
+	v3t3 := "int"
+	v3t4 := "uint"
+	v3s := "(len=" + v3Len + " cap=" + v3Cap + ") {\n (" + v3t2 + ") " +
+		"(len=" + v3i0Len + ") \"one\",\n (" + v3t3 + ") 2,\n (" +
+		v3t4 + ") 3\n}"
+	addDumpTest(v3, "("+v3t+") "+v3s+"\n")
+	addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
+	addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
+	addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
+
+	// Array containing bytes.
+	v4 := [34]byte{
+		0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+		0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+		0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+		0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+		0x31, 0x32,
+	}
+	v4Len := fmt.Sprintf("%d", len(v4))
+	v4Cap := fmt.Sprintf("%d", cap(v4))
+	nv4 := (*[34]byte)(nil)
+	pv4 := &v4
+	v4Addr := fmt.Sprintf("%p", pv4)
+	pv4Addr := fmt.Sprintf("%p", &pv4)
+	v4t := "[34]uint8"
+	v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
+		"{\n 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20" +
+		"  |............... |\n" +
+		" 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30" +
+		"  |!\"#$%&'()*+,-./0|\n" +
+		" 00000020  31 32                                           " +
+		"  |12|\n}"
+	addDumpTest(v4, "("+v4t+") "+v4s+"\n")
+	addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
+	addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
+	addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
+}
+
+func addSliceDumpTests() {
+	// Slice containing standard float32 values.
+	v := []float32{3.14, 6.28, 12.56}
+	vLen := fmt.Sprintf("%d", len(v))
+	vCap := fmt.Sprintf("%d", cap(v))
+	nv := (*[]float32)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "float32"
+	vs := "(len=" + vLen + " cap=" + vCap + ") {\n (" + vt + ") 3.14,\n (" +
+		vt + ") 6.28,\n (" + vt + ") 12.56\n}"
+	addDumpTest(v, "([]"+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*[]"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**[]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*[]"+vt+")(<nil>)\n")
+
+	// Slice containing type with custom formatter on pointer receiver only.
+	v2i0 := pstringer("1")
+	v2i1 := pstringer("2")
+	v2i2 := pstringer("3")
+	v2 := []pstringer{v2i0, v2i1, v2i2}
+	v2i0Len := fmt.Sprintf("%d", len(v2i0))
+	v2i1Len := fmt.Sprintf("%d", len(v2i1))
+	v2i2Len := fmt.Sprintf("%d", len(v2i2))
+	v2Len := fmt.Sprintf("%d", len(v2))
+	v2Cap := fmt.Sprintf("%d", cap(v2))
+	nv2 := (*[]pstringer)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "spew_test.pstringer"
+	v2s := "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t + ") (len=" +
+		v2i0Len + ") stringer 1,\n (" + v2t + ") (len=" + v2i1Len +
+		") stringer 2,\n (" + v2t + ") (len=" + v2i2Len + ") " +
+		"stringer 3\n}"
+	addDumpTest(v2, "([]"+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*[]"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**[]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+	addDumpTest(nv2, "(*[]"+v2t+")(<nil>)\n")
+
+	// Slice containing interfaces.
+	v3i0 := "one"
+	v3 := []interface{}{v3i0, int(2), uint(3), nil}
+	v3i0Len := fmt.Sprintf("%d", len(v3i0))
+	v3Len := fmt.Sprintf("%d", len(v3))
+	v3Cap := fmt.Sprintf("%d", cap(v3))
+	nv3 := (*[]interface{})(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "[]interface {}"
+	v3t2 := "string"
+	v3t3 := "int"
+	v3t4 := "uint"
+	v3t5 := "interface {}"
+	v3s := "(len=" + v3Len + " cap=" + v3Cap + ") {\n (" + v3t2 + ") " +
+		"(len=" + v3i0Len + ") \"one\",\n (" + v3t3 + ") 2,\n (" +
+		v3t4 + ") 3,\n (" + v3t5 + ") <nil>\n}"
+	addDumpTest(v3, "("+v3t+") "+v3s+"\n")
+	addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
+	addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
+	addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
+
+	// Slice containing bytes.
+	v4 := []byte{
+		0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+		0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+		0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+		0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+		0x31, 0x32,
+	}
+	v4Len := fmt.Sprintf("%d", len(v4))
+	v4Cap := fmt.Sprintf("%d", cap(v4))
+	nv4 := (*[]byte)(nil)
+	pv4 := &v4
+	v4Addr := fmt.Sprintf("%p", pv4)
+	pv4Addr := fmt.Sprintf("%p", &pv4)
+	v4t := "[]uint8"
+	v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
+		"{\n 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20" +
+		"  |............... |\n" +
+		" 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30" +
+		"  |!\"#$%&'()*+,-./0|\n" +
+		" 00000020  31 32                                           " +
+		"  |12|\n}"
+	addDumpTest(v4, "("+v4t+") "+v4s+"\n")
+	addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
+	addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
+	addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
+
+	// Nil slice.
+	v5 := []int(nil)
+	nv5 := (*[]int)(nil)
+	pv5 := &v5
+	v5Addr := fmt.Sprintf("%p", pv5)
+	pv5Addr := fmt.Sprintf("%p", &pv5)
+	v5t := "[]int"
+	v5s := "<nil>"
+	addDumpTest(v5, "("+v5t+") "+v5s+"\n")
+	addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
+	addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
+	addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
+}
+
+func addStringDumpTests() {
+	// Standard string.
+	v := "test"
+	vLen := fmt.Sprintf("%d", len(v))
+	nv := (*string)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "string"
+	vs := "(len=" + vLen + ") \"test\""
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+}
+
+func addInterfaceDumpTests() {
+	// Nil interface.
+	var v interface{}
+	nv := (*interface{})(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "interface {}"
+	vs := "<nil>"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+
+	// Sub-interface.
+	v2 := interface{}(uint16(65535))
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "uint16"
+	v2s := "65535"
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+}
+
+func addMapDumpTests() {
+	// Map with string keys and int vals.
+	k := "one"
+	kk := "two"
+	m := map[string]int{k: 1, kk: 2}
+	klen := fmt.Sprintf("%d", len(k)) // not kLen to shut golint up
+	kkLen := fmt.Sprintf("%d", len(kk))
+	mLen := fmt.Sprintf("%d", len(m))
+	nilMap := map[string]int(nil)
+	nm := (*map[string]int)(nil)
+	pm := &m
+	mAddr := fmt.Sprintf("%p", pm)
+	pmAddr := fmt.Sprintf("%p", &pm)
+	mt := "map[string]int"
+	mt1 := "string"
+	mt2 := "int"
+	ms := "(len=" + mLen + ") {\n (" + mt1 + ") (len=" + klen + ") " +
+		"\"one\": (" + mt2 + ") 1,\n (" + mt1 + ") (len=" + kkLen +
+		") \"two\": (" + mt2 + ") 2\n}"
+	ms2 := "(len=" + mLen + ") {\n (" + mt1 + ") (len=" + kkLen + ") " +
+		"\"two\": (" + mt2 + ") 2,\n (" + mt1 + ") (len=" + klen +
+		") \"one\": (" + mt2 + ") 1\n}"
+	addDumpTest(m, "("+mt+") "+ms+"\n", "("+mt+") "+ms2+"\n")
+	addDumpTest(pm, "(*"+mt+")("+mAddr+")("+ms+")\n",
+		"(*"+mt+")("+mAddr+")("+ms2+")\n")
+	addDumpTest(&pm, "(**"+mt+")("+pmAddr+"->"+mAddr+")("+ms+")\n",
+		"(**"+mt+")("+pmAddr+"->"+mAddr+")("+ms2+")\n")
+	addDumpTest(nm, "(*"+mt+")(<nil>)\n")
+	addDumpTest(nilMap, "("+mt+") <nil>\n")
+
+	// Map with custom formatter type on pointer receiver only keys and vals.
+	k2 := pstringer("one")
+	v2 := pstringer("1")
+	m2 := map[pstringer]pstringer{k2: v2}
+	k2Len := fmt.Sprintf("%d", len(k2))
+	v2Len := fmt.Sprintf("%d", len(v2))
+	m2Len := fmt.Sprintf("%d", len(m2))
+	nilMap2 := map[pstringer]pstringer(nil)
+	nm2 := (*map[pstringer]pstringer)(nil)
+	pm2 := &m2
+	m2Addr := fmt.Sprintf("%p", pm2)
+	pm2Addr := fmt.Sprintf("%p", &pm2)
+	m2t := "map[spew_test.pstringer]spew_test.pstringer"
+	m2t1 := "spew_test.pstringer"
+	m2t2 := "spew_test.pstringer"
+	m2s := "(len=" + m2Len + ") {\n (" + m2t1 + ") (len=" + k2Len + ") " +
+		"stringer one: (" + m2t2 + ") (len=" + v2Len + ") stringer 1\n}"
+	if spew.UnsafeDisabled {
+		m2s = "(len=" + m2Len + ") {\n (" + m2t1 + ") (len=" + k2Len +
+			") " + "\"one\": (" + m2t2 + ") (len=" + v2Len +
+			") \"1\"\n}"
+	}
+	addDumpTest(m2, "("+m2t+") "+m2s+"\n")
+	addDumpTest(pm2, "(*"+m2t+")("+m2Addr+")("+m2s+")\n")
+	addDumpTest(&pm2, "(**"+m2t+")("+pm2Addr+"->"+m2Addr+")("+m2s+")\n")
+	addDumpTest(nm2, "(*"+m2t+")(<nil>)\n")
+	addDumpTest(nilMap2, "("+m2t+") <nil>\n")
+
+	// Map with interface keys and values.
+	k3 := "one"
+	k3Len := fmt.Sprintf("%d", len(k3))
+	m3 := map[interface{}]interface{}{k3: 1}
+	m3Len := fmt.Sprintf("%d", len(m3))
+	nilMap3 := map[interface{}]interface{}(nil)
+	nm3 := (*map[interface{}]interface{})(nil)
+	pm3 := &m3
+	m3Addr := fmt.Sprintf("%p", pm3)
+	pm3Addr := fmt.Sprintf("%p", &pm3)
+	m3t := "map[interface {}]interface {}"
+	m3t1 := "string"
+	m3t2 := "int"
+	m3s := "(len=" + m3Len + ") {\n (" + m3t1 + ") (len=" + k3Len + ") " +
+		"\"one\": (" + m3t2 + ") 1\n}"
+	addDumpTest(m3, "("+m3t+") "+m3s+"\n")
+	addDumpTest(pm3, "(*"+m3t+")("+m3Addr+")("+m3s+")\n")
+	addDumpTest(&pm3, "(**"+m3t+")("+pm3Addr+"->"+m3Addr+")("+m3s+")\n")
+	addDumpTest(nm3, "(*"+m3t+")(<nil>)\n")
+	addDumpTest(nilMap3, "("+m3t+") <nil>\n")
+
+	// Map with nil interface value.
+	k4 := "nil"
+	k4Len := fmt.Sprintf("%d", len(k4))
+	m4 := map[string]interface{}{k4: nil}
+	m4Len := fmt.Sprintf("%d", len(m4))
+	nilMap4 := map[string]interface{}(nil)
+	nm4 := (*map[string]interface{})(nil)
+	pm4 := &m4
+	m4Addr := fmt.Sprintf("%p", pm4)
+	pm4Addr := fmt.Sprintf("%p", &pm4)
+	m4t := "map[string]interface {}"
+	m4t1 := "string"
+	m4t2 := "interface {}"
+	m4s := "(len=" + m4Len + ") {\n (" + m4t1 + ") (len=" + k4Len + ")" +
+		" \"nil\": (" + m4t2 + ") <nil>\n}"
+	addDumpTest(m4, "("+m4t+") "+m4s+"\n")
+	addDumpTest(pm4, "(*"+m4t+")("+m4Addr+")("+m4s+")\n")
+	addDumpTest(&pm4, "(**"+m4t+")("+pm4Addr+"->"+m4Addr+")("+m4s+")\n")
+	addDumpTest(nm4, "(*"+m4t+")(<nil>)\n")
+	addDumpTest(nilMap4, "("+m4t+") <nil>\n")
+}
+
+func addStructDumpTests() {
+	// Struct with primitives.
+	type s1 struct {
+		a int8
+		b uint8
+	}
+	v := s1{127, 255}
+	nv := (*s1)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "spew_test.s1"
+	vt2 := "int8"
+	vt3 := "uint8"
+	vs := "{\n a: (" + vt2 + ") 127,\n b: (" + vt3 + ") 255\n}"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+
+	// Struct that contains another struct.
+	type s2 struct {
+		s1 s1
+		b  bool
+	}
+	v2 := s2{s1{127, 255}, true}
+	nv2 := (*s2)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "spew_test.s2"
+	v2t2 := "spew_test.s1"
+	v2t3 := "int8"
+	v2t4 := "uint8"
+	v2t5 := "bool"
+	v2s := "{\n s1: (" + v2t2 + ") {\n  a: (" + v2t3 + ") 127,\n  b: (" +
+		v2t4 + ") 255\n },\n b: (" + v2t5 + ") true\n}"
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+	addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
+
+	// Struct that contains custom type with Stringer pointer interface via both
+	// exported and unexported fields.
+	type s3 struct {
+		s pstringer
+		S pstringer
+	}
+	v3 := s3{"test", "test2"}
+	nv3 := (*s3)(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "spew_test.s3"
+	v3t2 := "spew_test.pstringer"
+	v3s := "{\n s: (" + v3t2 + ") (len=4) stringer test,\n S: (" + v3t2 +
+		") (len=5) stringer test2\n}"
+	v3sp := v3s
+	if spew.UnsafeDisabled {
+		v3s = "{\n s: (" + v3t2 + ") (len=4) \"test\",\n S: (" +
+			v3t2 + ") (len=5) \"test2\"\n}"
+		v3sp = "{\n s: (" + v3t2 + ") (len=4) \"test\",\n S: (" +
+			v3t2 + ") (len=5) stringer test2\n}"
+	}
+	addDumpTest(v3, "("+v3t+") "+v3s+"\n")
+	addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3sp+")\n")
+	addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3sp+")\n")
+	addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
+
+	// Struct that contains embedded struct and field to same struct.
+	e := embed{"embedstr"}
+	eLen := fmt.Sprintf("%d", len("embedstr"))
+	v4 := embedwrap{embed: &e, e: &e}
+	nv4 := (*embedwrap)(nil)
+	pv4 := &v4
+	eAddr := fmt.Sprintf("%p", &e)
+	v4Addr := fmt.Sprintf("%p", pv4)
+	pv4Addr := fmt.Sprintf("%p", &pv4)
+	v4t := "spew_test.embedwrap"
+	v4t2 := "spew_test.embed"
+	v4t3 := "string"
+	v4s := "{\n embed: (*" + v4t2 + ")(" + eAddr + ")({\n  a: (" + v4t3 +
+		") (len=" + eLen + ") \"embedstr\"\n }),\n e: (*" + v4t2 +
+		")(" + eAddr + ")({\n  a: (" + v4t3 + ") (len=" + eLen + ")" +
+		" \"embedstr\"\n })\n}"
+	addDumpTest(v4, "("+v4t+") "+v4s+"\n")
+	addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
+	addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
+	addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
+}
+
+func addUintptrDumpTests() {
+	// Null pointer.
+	v := uintptr(0)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "uintptr"
+	vs := "<nil>"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+
+	// Address of real variable.
+	i := 1
+	v2 := uintptr(unsafe.Pointer(&i))
+	nv2 := (*uintptr)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "uintptr"
+	v2s := fmt.Sprintf("%p", &i)
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+	addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
+}
+
+func addUnsafePointerDumpTests() {
+	// Null pointer.
+	v := unsafe.Pointer(uintptr(0))
+	nv := (*unsafe.Pointer)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "unsafe.Pointer"
+	vs := "<nil>"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+
+	// Address of real variable.
+	i := 1
+	v2 := unsafe.Pointer(&i)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "unsafe.Pointer"
+	v2s := fmt.Sprintf("%p", &i)
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+}
+
+func addChanDumpTests() {
+	// Nil channel.
+	var v chan int
+	pv := &v
+	nv := (*chan int)(nil)
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "chan int"
+	vs := "<nil>"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+
+	// Real channel.
+	v2 := make(chan int)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "chan int"
+	v2s := fmt.Sprintf("%p", v2)
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+}
+
+func addFuncDumpTests() {
+	// Function with no params and no returns.
+	v := addIntDumpTests
+	nv := (*func())(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "func()"
+	vs := fmt.Sprintf("%p", v)
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+
+	// Function with param and no returns.
+	v2 := TestDump
+	nv2 := (*func(*testing.T))(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "func(*testing.T)"
+	v2s := fmt.Sprintf("%p", v2)
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
+	addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
+
+	// Function with multiple params and multiple returns.
+	var v3 = func(i int, s string) (b bool, err error) {
+		return true, nil
+	}
+	nv3 := (*func(int, string) (bool, error))(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "func(int, string) (bool, error)"
+	v3s := fmt.Sprintf("%p", v3)
+	addDumpTest(v3, "("+v3t+") "+v3s+"\n")
+	addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
+	addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
+	addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
+}
+
+func addCircularDumpTests() {
+	// Struct that is circular through self referencing.
+	type circular struct {
+		c *circular
+	}
+	v := circular{nil}
+	v.c = &v
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "spew_test.circular"
+	vs := "{\n c: (*" + vt + ")(" + vAddr + ")({\n  c: (*" + vt + ")(" +
+		vAddr + ")(<already shown>)\n })\n}"
+	vs2 := "{\n c: (*" + vt + ")(" + vAddr + ")(<already shown>)\n}"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs2+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs2+")\n")
+
+	// Structs that are circular through cross referencing.
+	v2 := xref1{nil}
+	ts2 := xref2{&v2}
+	v2.ps2 = &ts2
+	pv2 := &v2
+	ts2Addr := fmt.Sprintf("%p", &ts2)
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "spew_test.xref1"
+	v2t2 := "spew_test.xref2"
+	v2s := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n  ps1: (*" + v2t +
+		")(" + v2Addr + ")({\n   ps2: (*" + v2t2 + ")(" + ts2Addr +
+		")(<already shown>)\n  })\n })\n}"
+	v2s2 := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n  ps1: (*" + v2t +
+		")(" + v2Addr + ")(<already shown>)\n })\n}"
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+	addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s2+")\n")
+	addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s2+")\n")
+
+	// Structs that are indirectly circular.
+	v3 := indirCir1{nil}
+	tic2 := indirCir2{nil}
+	tic3 := indirCir3{&v3}
+	tic2.ps3 = &tic3
+	v3.ps2 = &tic2
+	pv3 := &v3
+	tic2Addr := fmt.Sprintf("%p", &tic2)
+	tic3Addr := fmt.Sprintf("%p", &tic3)
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "spew_test.indirCir1"
+	v3t2 := "spew_test.indirCir2"
+	v3t3 := "spew_test.indirCir3"
+	v3s := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n  ps3: (*" + v3t3 +
+		")(" + tic3Addr + ")({\n   ps1: (*" + v3t + ")(" + v3Addr +
+		")({\n    ps2: (*" + v3t2 + ")(" + tic2Addr +
+		")(<already shown>)\n   })\n  })\n })\n}"
+	v3s2 := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n  ps3: (*" + v3t3 +
+		")(" + tic3Addr + ")({\n   ps1: (*" + v3t + ")(" + v3Addr +
+		")(<already shown>)\n  })\n })\n}"
+	addDumpTest(v3, "("+v3t+") "+v3s+"\n")
+	addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s2+")\n")
+	addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s2+")\n")
+}
+
+func addPanicDumpTests() {
+	// Type that panics in its Stringer interface.
+	v := panicer(127)
+	nv := (*panicer)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "spew_test.panicer"
+	vs := "(PANIC=test panic)127"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+}
+
+func addErrorDumpTests() {
+	// Type that has a custom Error interface.
+	v := customError(127)
+	nv := (*customError)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "spew_test.customError"
+	vs := "error: 127"
+	addDumpTest(v, "("+vt+") "+vs+"\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
+	addDumpTest(nv, "(*"+vt+")(<nil>)\n")
+}
+
+// TestDump executes all of the tests described by dumpTests.
+func TestDump(t *testing.T) {
+	// Setup tests.
+	addIntDumpTests()
+	addUintDumpTests()
+	addBoolDumpTests()
+	addFloatDumpTests()
+	addComplexDumpTests()
+	addArrayDumpTests()
+	addSliceDumpTests()
+	addStringDumpTests()
+	addInterfaceDumpTests()
+	addMapDumpTests()
+	addStructDumpTests()
+	addUintptrDumpTests()
+	addUnsafePointerDumpTests()
+	addChanDumpTests()
+	addFuncDumpTests()
+	addCircularDumpTests()
+	addPanicDumpTests()
+	addErrorDumpTests()
+	addCgoDumpTests()
+
+	t.Logf("Running %d tests", len(dumpTests))
+	for i, test := range dumpTests {
+		buf := new(bytes.Buffer)
+		spew.Fdump(buf, test.in)
+		s := buf.String()
+		if testFailed(s, test.wants) {
+			t.Errorf("Dump #%d\n got: %s %s", i, s, stringizeWants(test.wants))
+			continue
+		}
+	}
+}
+
+func TestDumpSortedKeys(t *testing.T) {
+	cfg := spew.ConfigState{SortKeys: true}
+	s := cfg.Sdump(map[int]string{1: "1", 3: "3", 2: "2"})
+	expected := "(map[int]string) (len=3) {\n(int) 1: (string) (len=1) " +
+		"\"1\",\n(int) 2: (string) (len=1) \"2\",\n(int) 3: (string) " +
+		"(len=1) \"3\"\n" +
+		"}\n"
+	if s != expected {
+		t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
+	}
+
+	s = cfg.Sdump(map[stringer]int{"1": 1, "3": 3, "2": 2})
+	expected = "(map[spew_test.stringer]int) (len=3) {\n" +
+		"(spew_test.stringer) (len=1) stringer 1: (int) 1,\n" +
+		"(spew_test.stringer) (len=1) stringer 2: (int) 2,\n" +
+		"(spew_test.stringer) (len=1) stringer 3: (int) 3\n" +
+		"}\n"
+	if s != expected {
+		t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
+	}
+
+	s = cfg.Sdump(map[pstringer]int{pstringer("1"): 1, pstringer("3"): 3, pstringer("2"): 2})
+	expected = "(map[spew_test.pstringer]int) (len=3) {\n" +
+		"(spew_test.pstringer) (len=1) stringer 1: (int) 1,\n" +
+		"(spew_test.pstringer) (len=1) stringer 2: (int) 2,\n" +
+		"(spew_test.pstringer) (len=1) stringer 3: (int) 3\n" +
+		"}\n"
+	if spew.UnsafeDisabled {
+		expected = "(map[spew_test.pstringer]int) (len=3) {\n" +
+			"(spew_test.pstringer) (len=1) \"1\": (int) 1,\n" +
+			"(spew_test.pstringer) (len=1) \"2\": (int) 2,\n" +
+			"(spew_test.pstringer) (len=1) \"3\": (int) 3\n" +
+			"}\n"
+	}
+	if s != expected {
+		t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
+	}
+
+	s = cfg.Sdump(map[customError]int{customError(1): 1, customError(3): 3, customError(2): 2})
+	expected = "(map[spew_test.customError]int) (len=3) {\n" +
+		"(spew_test.customError) error: 1: (int) 1,\n" +
+		"(spew_test.customError) error: 2: (int) 2,\n" +
+		"(spew_test.customError) error: 3: (int) 3\n" +
+		"}\n"
+	if s != expected {
+		t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
+	}
+
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/dumpcgo_test.go b/go/src/github.com/davecgh/go-spew/spew/dumpcgo_test.go
new file mode 100644
index 0000000..18a3835
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/dumpcgo_test.go
@@ -0,0 +1,98 @@
+// Copyright (c) 2013 Dave Collins <dave@davec.name>
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+// NOTE: Due to the following build constraints, this file will only be compiled
+// when both cgo is supported and "-tags testcgo" is added to the go test
+// command line.  This means the cgo tests are only added (and hence run) when
+// specifially requested.  This configuration is used because spew itself
+// does not require cgo to run even though it does handle certain cgo types
+// specially.  Rather than forcing all clients to require cgo and an external
+// C compiler just to run the tests, this scheme makes them optional.
+// +build cgo,testcgo
+
+package spew_test
+
+import (
+	"fmt"
+
+	"github.com/davecgh/go-spew/spew/testdata"
+)
+
+func addCgoDumpTests() {
+	// C char pointer.
+	v := testdata.GetCgoCharPointer()
+	nv := testdata.GetCgoNullCharPointer()
+	pv := &v
+	vcAddr := fmt.Sprintf("%p", v)
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "*testdata._Ctype_char"
+	vs := "116"
+	addDumpTest(v, "("+vt+")("+vcAddr+")("+vs+")\n")
+	addDumpTest(pv, "(*"+vt+")("+vAddr+"->"+vcAddr+")("+vs+")\n")
+	addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+"->"+vcAddr+")("+vs+")\n")
+	addDumpTest(nv, "("+vt+")(<nil>)\n")
+
+	// C char array.
+	v2, v2l, v2c := testdata.GetCgoCharArray()
+	v2Len := fmt.Sprintf("%d", v2l)
+	v2Cap := fmt.Sprintf("%d", v2c)
+	v2t := "[6]testdata._Ctype_char"
+	v2s := "(len=" + v2Len + " cap=" + v2Cap + ") " +
+		"{\n 00000000  74 65 73 74 32 00                               " +
+		"  |test2.|\n}"
+	addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+
+	// C unsigned char array.
+	v3, v3l, v3c := testdata.GetCgoUnsignedCharArray()
+	v3Len := fmt.Sprintf("%d", v3l)
+	v3Cap := fmt.Sprintf("%d", v3c)
+	v3t := "[6]testdata._Ctype_unsignedchar"
+	v3s := "(len=" + v3Len + " cap=" + v3Cap + ") " +
+		"{\n 00000000  74 65 73 74 33 00                               " +
+		"  |test3.|\n}"
+	addDumpTest(v3, "("+v3t+") "+v3s+"\n")
+
+	// C signed char array.
+	v4, v4l, v4c := testdata.GetCgoSignedCharArray()
+	v4Len := fmt.Sprintf("%d", v4l)
+	v4Cap := fmt.Sprintf("%d", v4c)
+	v4t := "[6]testdata._Ctype_schar"
+	v4t2 := "testdata._Ctype_schar"
+	v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
+		"{\n (" + v4t2 + ") 116,\n (" + v4t2 + ") 101,\n (" + v4t2 +
+		") 115,\n (" + v4t2 + ") 116,\n (" + v4t2 + ") 52,\n (" + v4t2 +
+		") 0\n}"
+	addDumpTest(v4, "("+v4t+") "+v4s+"\n")
+
+	// C uint8_t array.
+	v5, v5l, v5c := testdata.GetCgoUint8tArray()
+	v5Len := fmt.Sprintf("%d", v5l)
+	v5Cap := fmt.Sprintf("%d", v5c)
+	v5t := "[6]testdata._Ctype_uint8_t"
+	v5s := "(len=" + v5Len + " cap=" + v5Cap + ") " +
+		"{\n 00000000  74 65 73 74 35 00                               " +
+		"  |test5.|\n}"
+	addDumpTest(v5, "("+v5t+") "+v5s+"\n")
+
+	// C typedefed unsigned char array.
+	v6, v6l, v6c := testdata.GetCgoTypdefedUnsignedCharArray()
+	v6Len := fmt.Sprintf("%d", v6l)
+	v6Cap := fmt.Sprintf("%d", v6c)
+	v6t := "[6]testdata._Ctype_custom_uchar_t"
+	v6s := "(len=" + v6Len + " cap=" + v6Cap + ") " +
+		"{\n 00000000  74 65 73 74 36 00                               " +
+		"  |test6.|\n}"
+	addDumpTest(v6, "("+v6t+") "+v6s+"\n")
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/dumpnocgo_test.go b/go/src/github.com/davecgh/go-spew/spew/dumpnocgo_test.go
new file mode 100644
index 0000000..52a0971
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/dumpnocgo_test.go
@@ -0,0 +1,26 @@
+// Copyright (c) 2013 Dave Collins <dave@davec.name>
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+// NOTE: Due to the following build constraints, this file will only be compiled
+// when either cgo is not supported or "-tags testcgo" is not added to the go
+// test command line.  This file intentionally does not setup any cgo tests in
+// this scenario.
+// +build !cgo !testcgo
+
+package spew_test
+
+func addCgoDumpTests() {
+	// Don't add any tests for cgo since this file is only compiled when
+	// there should not be any cgo tests.
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/example_test.go b/go/src/github.com/davecgh/go-spew/spew/example_test.go
new file mode 100644
index 0000000..de6c4e3
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/example_test.go
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew_test
+
+import (
+	"fmt"
+
+	"github.com/davecgh/go-spew/spew"
+)
+
+type Flag int
+
+const (
+	flagOne Flag = iota
+	flagTwo
+)
+
+var flagStrings = map[Flag]string{
+	flagOne: "flagOne",
+	flagTwo: "flagTwo",
+}
+
+func (f Flag) String() string {
+	if s, ok := flagStrings[f]; ok {
+		return s
+	}
+	return fmt.Sprintf("Unknown flag (%d)", int(f))
+}
+
+type Bar struct {
+	data uintptr
+}
+
+type Foo struct {
+	unexportedField Bar
+	ExportedField   map[interface{}]interface{}
+}
+
+// This example demonstrates how to use Dump to dump variables to stdout.
+func ExampleDump() {
+	// The following package level declarations are assumed for this example:
+	/*
+		type Flag int
+
+		const (
+			flagOne Flag = iota
+			flagTwo
+		)
+
+		var flagStrings = map[Flag]string{
+			flagOne: "flagOne",
+			flagTwo: "flagTwo",
+		}
+
+		func (f Flag) String() string {
+			if s, ok := flagStrings[f]; ok {
+				return s
+			}
+			return fmt.Sprintf("Unknown flag (%d)", int(f))
+		}
+
+		type Bar struct {
+			data uintptr
+		}
+
+		type Foo struct {
+			unexportedField Bar
+			ExportedField   map[interface{}]interface{}
+		}
+	*/
+
+	// Setup some sample data structures for the example.
+	bar := Bar{uintptr(0)}
+	s1 := Foo{bar, map[interface{}]interface{}{"one": true}}
+	f := Flag(5)
+	b := []byte{
+		0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+		0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+		0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+		0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+		0x31, 0x32,
+	}
+
+	// Dump!
+	spew.Dump(s1, f, b)
+
+	// Output:
+	// (spew_test.Foo) {
+	//  unexportedField: (spew_test.Bar) {
+	//   data: (uintptr) <nil>
+	//  },
+	//  ExportedField: (map[interface {}]interface {}) (len=1) {
+	//   (string) (len=3) "one": (bool) true
+	//  }
+	// }
+	// (spew_test.Flag) Unknown flag (5)
+	// ([]uint8) (len=34 cap=34) {
+	//  00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... |
+	//  00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0|
+	//  00000020  31 32                                             |12|
+	// }
+	//
+}
+
+// This example demonstrates how to use Printf to display a variable with a
+// format string and inline formatting.
+func ExamplePrintf() {
+	// Create a double pointer to a uint 8.
+	ui8 := uint8(5)
+	pui8 := &ui8
+	ppui8 := &pui8
+
+	// Create a circular data type.
+	type circular struct {
+		ui8 uint8
+		c   *circular
+	}
+	c := circular{ui8: 1}
+	c.c = &c
+
+	// Print!
+	spew.Printf("ppui8: %v\n", ppui8)
+	spew.Printf("circular: %v\n", c)
+
+	// Output:
+	// ppui8: <**>5
+	// circular: {1 <*>{1 <*><shown>}}
+}
+
+// This example demonstrates how to use a ConfigState.
+func ExampleConfigState() {
+	// Modify the indent level of the ConfigState only.  The global
+	// configuration is not modified.
+	scs := spew.ConfigState{Indent: "\t"}
+
+	// Output using the ConfigState instance.
+	v := map[string]int{"one": 1}
+	scs.Printf("v: %v\n", v)
+	scs.Dump(v)
+
+	// Output:
+	// v: map[one:1]
+	// (map[string]int) (len=1) {
+	// 	(string) (len=3) "one": (int) 1
+	// }
+}
+
+// This example demonstrates how to use ConfigState.Dump to dump variables to
+// stdout
+func ExampleConfigState_Dump() {
+	// See the top-level Dump example for details on the types used in this
+	// example.
+
+	// Create two ConfigState instances with different indentation.
+	scs := spew.ConfigState{Indent: "\t"}
+	scs2 := spew.ConfigState{Indent: " "}
+
+	// Setup some sample data structures for the example.
+	bar := Bar{uintptr(0)}
+	s1 := Foo{bar, map[interface{}]interface{}{"one": true}}
+
+	// Dump using the ConfigState instances.
+	scs.Dump(s1)
+	scs2.Dump(s1)
+
+	// Output:
+	// (spew_test.Foo) {
+	// 	unexportedField: (spew_test.Bar) {
+	// 		data: (uintptr) <nil>
+	// 	},
+	// 	ExportedField: (map[interface {}]interface {}) (len=1) {
+	//		(string) (len=3) "one": (bool) true
+	// 	}
+	// }
+	// (spew_test.Foo) {
+	//  unexportedField: (spew_test.Bar) {
+	//   data: (uintptr) <nil>
+	//  },
+	//  ExportedField: (map[interface {}]interface {}) (len=1) {
+	//   (string) (len=3) "one": (bool) true
+	//  }
+	// }
+	//
+}
+
+// This example demonstrates how to use ConfigState.Printf to display a variable
+// with a format string and inline formatting.
+func ExampleConfigState_Printf() {
+	// See the top-level Dump example for details on the types used in this
+	// example.
+
+	// Create two ConfigState instances and modify the method handling of the
+	// first ConfigState only.
+	scs := spew.NewDefaultConfig()
+	scs2 := spew.NewDefaultConfig()
+	scs.DisableMethods = true
+
+	// Alternatively
+	// scs := spew.ConfigState{Indent: " ", DisableMethods: true}
+	// scs2 := spew.ConfigState{Indent: " "}
+
+	// This is of type Flag which implements a Stringer and has raw value 1.
+	f := flagTwo
+
+	// Dump using the ConfigState instances.
+	scs.Printf("f: %v\n", f)
+	scs2.Printf("f: %v\n", f)
+
+	// Output:
+	// f: 1
+	// f: flagTwo
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/format.go b/go/src/github.com/davecgh/go-spew/spew/format.go
new file mode 100644
index 0000000..ecf3b80
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/format.go
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+)
+
+// supportedFlags is a list of all the character flags supported by fmt package.
+const supportedFlags = "0-+# "
+
+// formatState implements the fmt.Formatter interface and contains information
+// about the state of a formatting operation.  The NewFormatter function can
+// be used to get a new Formatter which can be used directly as arguments
+// in standard fmt package printing calls.
+type formatState struct {
+	value          interface{}
+	fs             fmt.State
+	depth          int
+	pointers       map[uintptr]int
+	ignoreNextType bool
+	cs             *ConfigState
+}
+
+// buildDefaultFormat recreates the original format string without precision
+// and width information to pass in to fmt.Sprintf in the case of an
+// unrecognized type.  Unless new types are added to the language, this
+// function won't ever be called.
+func (f *formatState) buildDefaultFormat() (format string) {
+	buf := bytes.NewBuffer(percentBytes)
+
+	for _, flag := range supportedFlags {
+		if f.fs.Flag(int(flag)) {
+			buf.WriteRune(flag)
+		}
+	}
+
+	buf.WriteRune('v')
+
+	format = buf.String()
+	return format
+}
+
+// constructOrigFormat recreates the original format string including precision
+// and width information to pass along to the standard fmt package.  This allows
+// automatic deferral of all format strings this package doesn't support.
+func (f *formatState) constructOrigFormat(verb rune) (format string) {
+	buf := bytes.NewBuffer(percentBytes)
+
+	for _, flag := range supportedFlags {
+		if f.fs.Flag(int(flag)) {
+			buf.WriteRune(flag)
+		}
+	}
+
+	if width, ok := f.fs.Width(); ok {
+		buf.WriteString(strconv.Itoa(width))
+	}
+
+	if precision, ok := f.fs.Precision(); ok {
+		buf.Write(precisionBytes)
+		buf.WriteString(strconv.Itoa(precision))
+	}
+
+	buf.WriteRune(verb)
+
+	format = buf.String()
+	return format
+}
+
+// unpackValue returns values inside of non-nil interfaces when possible and
+// ensures that types for values which have been unpacked from an interface
+// are displayed when the show types flag is also set.
+// This is useful for data types like structs, arrays, slices, and maps which
+// can contain varying types packed inside an interface.
+func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
+	if v.Kind() == reflect.Interface {
+		f.ignoreNextType = false
+		if !v.IsNil() {
+			v = v.Elem()
+		}
+	}
+	return v
+}
+
+// formatPtr handles formatting of pointers by indirecting them as necessary.
+func (f *formatState) formatPtr(v reflect.Value) {
+	// Display nil if top level pointer is nil.
+	showTypes := f.fs.Flag('#')
+	if v.IsNil() && (!showTypes || f.ignoreNextType) {
+		f.fs.Write(nilAngleBytes)
+		return
+	}
+
+	// Remove pointers at or below the current depth from map used to detect
+	// circular refs.
+	for k, depth := range f.pointers {
+		if depth >= f.depth {
+			delete(f.pointers, k)
+		}
+	}
+
+	// Keep list of all dereferenced pointers to possibly show later.
+	pointerChain := make([]uintptr, 0)
+
+	// Figure out how many levels of indirection there are by derferencing
+	// pointers and unpacking interfaces down the chain while detecting circular
+	// references.
+	nilFound := false
+	cycleFound := false
+	indirects := 0
+	ve := v
+	for ve.Kind() == reflect.Ptr {
+		if ve.IsNil() {
+			nilFound = true
+			break
+		}
+		indirects++
+		addr := ve.Pointer()
+		pointerChain = append(pointerChain, addr)
+		if pd, ok := f.pointers[addr]; ok && pd < f.depth {
+			cycleFound = true
+			indirects--
+			break
+		}
+		f.pointers[addr] = f.depth
+
+		ve = ve.Elem()
+		if ve.Kind() == reflect.Interface {
+			if ve.IsNil() {
+				nilFound = true
+				break
+			}
+			ve = ve.Elem()
+		}
+	}
+
+	// Display type or indirection level depending on flags.
+	if showTypes && !f.ignoreNextType {
+		f.fs.Write(openParenBytes)
+		f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
+		f.fs.Write([]byte(ve.Type().String()))
+		f.fs.Write(closeParenBytes)
+	} else {
+		if nilFound || cycleFound {
+			indirects += strings.Count(ve.Type().String(), "*")
+		}
+		f.fs.Write(openAngleBytes)
+		f.fs.Write([]byte(strings.Repeat("*", indirects)))
+		f.fs.Write(closeAngleBytes)
+	}
+
+	// Display pointer information depending on flags.
+	if f.fs.Flag('+') && (len(pointerChain) > 0) {
+		f.fs.Write(openParenBytes)
+		for i, addr := range pointerChain {
+			if i > 0 {
+				f.fs.Write(pointerChainBytes)
+			}
+			printHexPtr(f.fs, addr)
+		}
+		f.fs.Write(closeParenBytes)
+	}
+
+	// Display dereferenced value.
+	switch {
+	case nilFound == true:
+		f.fs.Write(nilAngleBytes)
+
+	case cycleFound == true:
+		f.fs.Write(circularShortBytes)
+
+	default:
+		f.ignoreNextType = true
+		f.format(ve)
+	}
+}
+
+// format is the main workhorse for providing the Formatter interface.  It
+// uses the passed reflect value to figure out what kind of object we are
+// dealing with and formats it appropriately.  It is a recursive function,
+// however circular data structures are detected and handled properly.
+func (f *formatState) format(v reflect.Value) {
+	// Handle invalid reflect values immediately.
+	kind := v.Kind()
+	if kind == reflect.Invalid {
+		f.fs.Write(invalidAngleBytes)
+		return
+	}
+
+	// Handle pointers specially.
+	if kind == reflect.Ptr {
+		f.formatPtr(v)
+		return
+	}
+
+	// Print type information unless already handled elsewhere.
+	if !f.ignoreNextType && f.fs.Flag('#') {
+		f.fs.Write(openParenBytes)
+		f.fs.Write([]byte(v.Type().String()))
+		f.fs.Write(closeParenBytes)
+	}
+	f.ignoreNextType = false
+
+	// Call Stringer/error interfaces if they exist and the handle methods
+	// flag is enabled.
+	if !f.cs.DisableMethods {
+		if (kind != reflect.Invalid) && (kind != reflect.Interface) {
+			if handled := handleMethods(f.cs, f.fs, v); handled {
+				return
+			}
+		}
+	}
+
+	switch kind {
+	case reflect.Invalid:
+		// Do nothing.  We should never get here since invalid has already
+		// been handled above.
+
+	case reflect.Bool:
+		printBool(f.fs, v.Bool())
+
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+		printInt(f.fs, v.Int(), 10)
+
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+		printUint(f.fs, v.Uint(), 10)
+
+	case reflect.Float32:
+		printFloat(f.fs, v.Float(), 32)
+
+	case reflect.Float64:
+		printFloat(f.fs, v.Float(), 64)
+
+	case reflect.Complex64:
+		printComplex(f.fs, v.Complex(), 32)
+
+	case reflect.Complex128:
+		printComplex(f.fs, v.Complex(), 64)
+
+	case reflect.Slice:
+		if v.IsNil() {
+			f.fs.Write(nilAngleBytes)
+			break
+		}
+		fallthrough
+
+	case reflect.Array:
+		f.fs.Write(openBracketBytes)
+		f.depth++
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
+			f.fs.Write(maxShortBytes)
+		} else {
+			numEntries := v.Len()
+			for i := 0; i < numEntries; i++ {
+				if i > 0 {
+					f.fs.Write(spaceBytes)
+				}
+				f.ignoreNextType = true
+				f.format(f.unpackValue(v.Index(i)))
+			}
+		}
+		f.depth--
+		f.fs.Write(closeBracketBytes)
+
+	case reflect.String:
+		f.fs.Write([]byte(v.String()))
+
+	case reflect.Interface:
+		// The only time we should get here is for nil interfaces due to
+		// unpackValue calls.
+		if v.IsNil() {
+			f.fs.Write(nilAngleBytes)
+		}
+
+	case reflect.Ptr:
+		// Do nothing.  We should never get here since pointers have already
+		// been handled above.
+
+	case reflect.Map:
+		// nil maps should be indicated as different than empty maps
+		if v.IsNil() {
+			f.fs.Write(nilAngleBytes)
+			break
+		}
+
+		f.fs.Write(openMapBytes)
+		f.depth++
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
+			f.fs.Write(maxShortBytes)
+		} else {
+			keys := v.MapKeys()
+			if f.cs.SortKeys {
+				sortValues(keys, f.cs)
+			}
+			for i, key := range keys {
+				if i > 0 {
+					f.fs.Write(spaceBytes)
+				}
+				f.ignoreNextType = true
+				f.format(f.unpackValue(key))
+				f.fs.Write(colonBytes)
+				f.ignoreNextType = true
+				f.format(f.unpackValue(v.MapIndex(key)))
+			}
+		}
+		f.depth--
+		f.fs.Write(closeMapBytes)
+
+	case reflect.Struct:
+		numFields := v.NumField()
+		f.fs.Write(openBraceBytes)
+		f.depth++
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
+			f.fs.Write(maxShortBytes)
+		} else {
+			vt := v.Type()
+			for i := 0; i < numFields; i++ {
+				if i > 0 {
+					f.fs.Write(spaceBytes)
+				}
+				vtf := vt.Field(i)
+				if f.fs.Flag('+') || f.fs.Flag('#') {
+					f.fs.Write([]byte(vtf.Name))
+					f.fs.Write(colonBytes)
+				}
+				f.format(f.unpackValue(v.Field(i)))
+			}
+		}
+		f.depth--
+		f.fs.Write(closeBraceBytes)
+
+	case reflect.Uintptr:
+		printHexPtr(f.fs, uintptr(v.Uint()))
+
+	case reflect.UnsafePointer, reflect.Chan, reflect.Func:
+		printHexPtr(f.fs, v.Pointer())
+
+	// There were not any other types at the time this code was written, but
+	// fall back to letting the default fmt package handle it if any get added.
+	default:
+		format := f.buildDefaultFormat()
+		if v.CanInterface() {
+			fmt.Fprintf(f.fs, format, v.Interface())
+		} else {
+			fmt.Fprintf(f.fs, format, v.String())
+		}
+	}
+}
+
+// Format satisfies the fmt.Formatter interface. See NewFormatter for usage
+// details.
+func (f *formatState) Format(fs fmt.State, verb rune) {
+	f.fs = fs
+
+	// Use standard formatting for verbs that are not v.
+	if verb != 'v' {
+		format := f.constructOrigFormat(verb)
+		fmt.Fprintf(fs, format, f.value)
+		return
+	}
+
+	if f.value == nil {
+		if fs.Flag('#') {
+			fs.Write(interfaceBytes)
+		}
+		fs.Write(nilAngleBytes)
+		return
+	}
+
+	f.format(reflect.ValueOf(f.value))
+}
+
+// newFormatter is a helper function to consolidate the logic from the various
+// public methods which take varying config states.
+func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
+	fs := &formatState{value: v, cs: cs}
+	fs.pointers = make(map[uintptr]int)
+	return fs
+}
+
+/*
+NewFormatter returns a custom formatter that satisfies the fmt.Formatter
+interface.  As a result, it integrates cleanly with standard fmt package
+printing functions.  The formatter is useful for inline printing of smaller data
+types similar to the standard %v format specifier.
+
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
+addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
+combinations.  Any other verbs such as %x and %q will be sent to the the
+standard fmt package for formatting.  In addition, the custom formatter ignores
+the width and precision arguments (however they will still work on the format
+specifiers not handled by the custom formatter).
+
+Typically this function shouldn't be called directly.  It is much easier to make
+use of the custom formatter by calling one of the convenience functions such as
+Printf, Println, or Fprintf.
+*/
+func NewFormatter(v interface{}) fmt.Formatter {
+	return newFormatter(&Config, v)
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/format_test.go b/go/src/github.com/davecgh/go-spew/spew/format_test.go
new file mode 100644
index 0000000..b664b3f
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/format_test.go
@@ -0,0 +1,1558 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+Test Summary:
+NOTE: For each test, a nil pointer, a single pointer and double pointer to the
+base test element are also tested to ensure proper indirection across all types.
+
+- Max int8, int16, int32, int64, int
+- Max uint8, uint16, uint32, uint64, uint
+- Boolean true and false
+- Standard complex64 and complex128
+- Array containing standard ints
+- Array containing type with custom formatter on pointer receiver only
+- Array containing interfaces
+- Slice containing standard float32 values
+- Slice containing type with custom formatter on pointer receiver only
+- Slice containing interfaces
+- Nil slice
+- Standard string
+- Nil interface
+- Sub-interface
+- Map with string keys and int vals
+- Map with custom formatter type on pointer receiver only keys and vals
+- Map with interface keys and values
+- Map with nil interface value
+- Struct with primitives
+- Struct that contains another struct
+- Struct that contains custom type with Stringer pointer interface via both
+  exported and unexported fields
+- Struct that contains embedded struct and field to same struct
+- Uintptr to 0 (null pointer)
+- Uintptr address of real variable
+- Unsafe.Pointer to 0 (null pointer)
+- Unsafe.Pointer to address of real variable
+- Nil channel
+- Standard int channel
+- Function with no params and no returns
+- Function with param and no returns
+- Function with multiple params and multiple returns
+- Struct that is circular through self referencing
+- Structs that are circular through cross referencing
+- Structs that are indirectly circular
+- Type that panics in its Stringer interface
+- Type that has a custom Error interface
+- %x passthrough with uint
+- %#x passthrough with uint
+- %f passthrough with precision
+- %f passthrough with width and precision
+- %d passthrough with width
+- %q passthrough with string
+*/
+
+package spew_test
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+	"unsafe"
+
+	"github.com/davecgh/go-spew/spew"
+)
+
+// formatterTest is used to describe a test to be perfomed against NewFormatter.
+type formatterTest struct {
+	format string
+	in     interface{}
+	wants  []string
+}
+
+// formatterTests houses all of the tests to be performed against NewFormatter.
+var formatterTests = make([]formatterTest, 0)
+
+// addFormatterTest is a helper method to append the passed input and desired
+// result to formatterTests.
+func addFormatterTest(format string, in interface{}, wants ...string) {
+	test := formatterTest{format, in, wants}
+	formatterTests = append(formatterTests, test)
+}
+
+func addIntFormatterTests() {
+	// Max int8.
+	v := int8(127)
+	nv := (*int8)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "int8"
+	vs := "127"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Max int16.
+	v2 := int16(32767)
+	nv2 := (*int16)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "int16"
+	v2s := "32767"
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%v", nv2, "<nil>")
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+	// Max int32.
+	v3 := int32(2147483647)
+	nv3 := (*int32)(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "int32"
+	v3s := "2147483647"
+	addFormatterTest("%v", v3, v3s)
+	addFormatterTest("%v", pv3, "<*>"+v3s)
+	addFormatterTest("%v", &pv3, "<**>"+v3s)
+	addFormatterTest("%v", nv3, "<nil>")
+	addFormatterTest("%+v", v3, v3s)
+	addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+	addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%#v", v3, "("+v3t+")"+v3s)
+	addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s)
+	addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s)
+	addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+	addFormatterTest("%#+v", v3, "("+v3t+")"+v3s)
+	addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s)
+	addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s)
+	addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+
+	// Max int64.
+	v4 := int64(9223372036854775807)
+	nv4 := (*int64)(nil)
+	pv4 := &v4
+	v4Addr := fmt.Sprintf("%p", pv4)
+	pv4Addr := fmt.Sprintf("%p", &pv4)
+	v4t := "int64"
+	v4s := "9223372036854775807"
+	addFormatterTest("%v", v4, v4s)
+	addFormatterTest("%v", pv4, "<*>"+v4s)
+	addFormatterTest("%v", &pv4, "<**>"+v4s)
+	addFormatterTest("%v", nv4, "<nil>")
+	addFormatterTest("%+v", v4, v4s)
+	addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s)
+	addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s)
+	addFormatterTest("%+v", nv4, "<nil>")
+	addFormatterTest("%#v", v4, "("+v4t+")"+v4s)
+	addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s)
+	addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s)
+	addFormatterTest("%#v", nv4, "(*"+v4t+")"+"<nil>")
+	addFormatterTest("%#+v", v4, "("+v4t+")"+v4s)
+	addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s)
+	addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s)
+	addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"<nil>")
+
+	// Max int.
+	v5 := int(2147483647)
+	nv5 := (*int)(nil)
+	pv5 := &v5
+	v5Addr := fmt.Sprintf("%p", pv5)
+	pv5Addr := fmt.Sprintf("%p", &pv5)
+	v5t := "int"
+	v5s := "2147483647"
+	addFormatterTest("%v", v5, v5s)
+	addFormatterTest("%v", pv5, "<*>"+v5s)
+	addFormatterTest("%v", &pv5, "<**>"+v5s)
+	addFormatterTest("%v", nv5, "<nil>")
+	addFormatterTest("%+v", v5, v5s)
+	addFormatterTest("%+v", pv5, "<*>("+v5Addr+")"+v5s)
+	addFormatterTest("%+v", &pv5, "<**>("+pv5Addr+"->"+v5Addr+")"+v5s)
+	addFormatterTest("%+v", nv5, "<nil>")
+	addFormatterTest("%#v", v5, "("+v5t+")"+v5s)
+	addFormatterTest("%#v", pv5, "(*"+v5t+")"+v5s)
+	addFormatterTest("%#v", &pv5, "(**"+v5t+")"+v5s)
+	addFormatterTest("%#v", nv5, "(*"+v5t+")"+"<nil>")
+	addFormatterTest("%#+v", v5, "("+v5t+")"+v5s)
+	addFormatterTest("%#+v", pv5, "(*"+v5t+")("+v5Addr+")"+v5s)
+	addFormatterTest("%#+v", &pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")"+v5s)
+	addFormatterTest("%#+v", nv5, "(*"+v5t+")"+"<nil>")
+}
+
+func addUintFormatterTests() {
+	// Max uint8.
+	v := uint8(255)
+	nv := (*uint8)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "uint8"
+	vs := "255"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Max uint16.
+	v2 := uint16(65535)
+	nv2 := (*uint16)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "uint16"
+	v2s := "65535"
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%v", nv2, "<nil>")
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+	// Max uint32.
+	v3 := uint32(4294967295)
+	nv3 := (*uint32)(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "uint32"
+	v3s := "4294967295"
+	addFormatterTest("%v", v3, v3s)
+	addFormatterTest("%v", pv3, "<*>"+v3s)
+	addFormatterTest("%v", &pv3, "<**>"+v3s)
+	addFormatterTest("%v", nv3, "<nil>")
+	addFormatterTest("%+v", v3, v3s)
+	addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+	addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%#v", v3, "("+v3t+")"+v3s)
+	addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s)
+	addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s)
+	addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+	addFormatterTest("%#+v", v3, "("+v3t+")"+v3s)
+	addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s)
+	addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s)
+	addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+
+	// Max uint64.
+	v4 := uint64(18446744073709551615)
+	nv4 := (*uint64)(nil)
+	pv4 := &v4
+	v4Addr := fmt.Sprintf("%p", pv4)
+	pv4Addr := fmt.Sprintf("%p", &pv4)
+	v4t := "uint64"
+	v4s := "18446744073709551615"
+	addFormatterTest("%v", v4, v4s)
+	addFormatterTest("%v", pv4, "<*>"+v4s)
+	addFormatterTest("%v", &pv4, "<**>"+v4s)
+	addFormatterTest("%v", nv4, "<nil>")
+	addFormatterTest("%+v", v4, v4s)
+	addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s)
+	addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s)
+	addFormatterTest("%+v", nv4, "<nil>")
+	addFormatterTest("%#v", v4, "("+v4t+")"+v4s)
+	addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s)
+	addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s)
+	addFormatterTest("%#v", nv4, "(*"+v4t+")"+"<nil>")
+	addFormatterTest("%#+v", v4, "("+v4t+")"+v4s)
+	addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s)
+	addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s)
+	addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"<nil>")
+
+	// Max uint.
+	v5 := uint(4294967295)
+	nv5 := (*uint)(nil)
+	pv5 := &v5
+	v5Addr := fmt.Sprintf("%p", pv5)
+	pv5Addr := fmt.Sprintf("%p", &pv5)
+	v5t := "uint"
+	v5s := "4294967295"
+	addFormatterTest("%v", v5, v5s)
+	addFormatterTest("%v", pv5, "<*>"+v5s)
+	addFormatterTest("%v", &pv5, "<**>"+v5s)
+	addFormatterTest("%v", nv5, "<nil>")
+	addFormatterTest("%+v", v5, v5s)
+	addFormatterTest("%+v", pv5, "<*>("+v5Addr+")"+v5s)
+	addFormatterTest("%+v", &pv5, "<**>("+pv5Addr+"->"+v5Addr+")"+v5s)
+	addFormatterTest("%+v", nv5, "<nil>")
+	addFormatterTest("%#v", v5, "("+v5t+")"+v5s)
+	addFormatterTest("%#v", pv5, "(*"+v5t+")"+v5s)
+	addFormatterTest("%#v", &pv5, "(**"+v5t+")"+v5s)
+	addFormatterTest("%#v", nv5, "(*"+v5t+")"+"<nil>")
+	addFormatterTest("%#+v", v5, "("+v5t+")"+v5s)
+	addFormatterTest("%#+v", pv5, "(*"+v5t+")("+v5Addr+")"+v5s)
+	addFormatterTest("%#+v", &pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")"+v5s)
+	addFormatterTest("%#v", nv5, "(*"+v5t+")"+"<nil>")
+}
+
+func addBoolFormatterTests() {
+	// Boolean true.
+	v := bool(true)
+	nv := (*bool)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "bool"
+	vs := "true"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Boolean false.
+	v2 := bool(false)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "bool"
+	v2s := "false"
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+}
+
+func addFloatFormatterTests() {
+	// Standard float32.
+	v := float32(3.1415)
+	nv := (*float32)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "float32"
+	vs := "3.1415"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Standard float64.
+	v2 := float64(3.1415926)
+	nv2 := (*float64)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "float64"
+	v2s := "3.1415926"
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+}
+
+func addComplexFormatterTests() {
+	// Standard complex64.
+	v := complex(float32(6), -2)
+	nv := (*complex64)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "complex64"
+	vs := "(6-2i)"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Standard complex128.
+	v2 := complex(float64(-6), 2)
+	nv2 := (*complex128)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "complex128"
+	v2s := "(-6+2i)"
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+}
+
+func addArrayFormatterTests() {
+	// Array containing standard ints.
+	v := [3]int{1, 2, 3}
+	nv := (*[3]int)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "[3]int"
+	vs := "[1 2 3]"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Array containing type with custom formatter on pointer receiver only.
+	v2 := [3]pstringer{"1", "2", "3"}
+	nv2 := (*[3]pstringer)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "[3]spew_test.pstringer"
+	v2sp := "[stringer 1 stringer 2 stringer 3]"
+	v2s := v2sp
+	if spew.UnsafeDisabled {
+		v2s = "[1 2 3]"
+	}
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2sp)
+	addFormatterTest("%v", &pv2, "<**>"+v2sp)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2sp)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2sp)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2sp)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2sp)
+	addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2sp)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2sp)
+	addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+	// Array containing interfaces.
+	v3 := [3]interface{}{"one", int(2), uint(3)}
+	nv3 := (*[3]interface{})(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "[3]interface {}"
+	v3t2 := "string"
+	v3t3 := "int"
+	v3t4 := "uint"
+	v3s := "[one 2 3]"
+	v3s2 := "[(" + v3t2 + ")one (" + v3t3 + ")2 (" + v3t4 + ")3]"
+	addFormatterTest("%v", v3, v3s)
+	addFormatterTest("%v", pv3, "<*>"+v3s)
+	addFormatterTest("%v", &pv3, "<**>"+v3s)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%+v", v3, v3s)
+	addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+	addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%#v", v3, "("+v3t+")"+v3s2)
+	addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s2)
+	addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s2)
+	addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+	addFormatterTest("%#+v", v3, "("+v3t+")"+v3s2)
+	addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2)
+	addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2)
+	addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"<nil>")
+}
+
+func addSliceFormatterTests() {
+	// Slice containing standard float32 values.
+	v := []float32{3.14, 6.28, 12.56}
+	nv := (*[]float32)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "[]float32"
+	vs := "[3.14 6.28 12.56]"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Slice containing type with custom formatter on pointer receiver only.
+	v2 := []pstringer{"1", "2", "3"}
+	nv2 := (*[]pstringer)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "[]spew_test.pstringer"
+	v2s := "[stringer 1 stringer 2 stringer 3]"
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+	// Slice containing interfaces.
+	v3 := []interface{}{"one", int(2), uint(3), nil}
+	nv3 := (*[]interface{})(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "[]interface {}"
+	v3t2 := "string"
+	v3t3 := "int"
+	v3t4 := "uint"
+	v3t5 := "interface {}"
+	v3s := "[one 2 3 <nil>]"
+	v3s2 := "[(" + v3t2 + ")one (" + v3t3 + ")2 (" + v3t4 + ")3 (" + v3t5 +
+		")<nil>]"
+	addFormatterTest("%v", v3, v3s)
+	addFormatterTest("%v", pv3, "<*>"+v3s)
+	addFormatterTest("%v", &pv3, "<**>"+v3s)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%+v", v3, v3s)
+	addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+	addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%#v", v3, "("+v3t+")"+v3s2)
+	addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s2)
+	addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s2)
+	addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+	addFormatterTest("%#+v", v3, "("+v3t+")"+v3s2)
+	addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2)
+	addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2)
+	addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"<nil>")
+
+	// Nil slice.
+	var v4 []int
+	nv4 := (*[]int)(nil)
+	pv4 := &v4
+	v4Addr := fmt.Sprintf("%p", pv4)
+	pv4Addr := fmt.Sprintf("%p", &pv4)
+	v4t := "[]int"
+	v4s := "<nil>"
+	addFormatterTest("%v", v4, v4s)
+	addFormatterTest("%v", pv4, "<*>"+v4s)
+	addFormatterTest("%v", &pv4, "<**>"+v4s)
+	addFormatterTest("%+v", nv4, "<nil>")
+	addFormatterTest("%+v", v4, v4s)
+	addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s)
+	addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s)
+	addFormatterTest("%+v", nv4, "<nil>")
+	addFormatterTest("%#v", v4, "("+v4t+")"+v4s)
+	addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s)
+	addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s)
+	addFormatterTest("%#v", nv4, "(*"+v4t+")"+"<nil>")
+	addFormatterTest("%#+v", v4, "("+v4t+")"+v4s)
+	addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s)
+	addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s)
+	addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"<nil>")
+}
+
+func addStringFormatterTests() {
+	// Standard string.
+	v := "test"
+	nv := (*string)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "string"
+	vs := "test"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+}
+
+func addInterfaceFormatterTests() {
+	// Nil interface.
+	var v interface{}
+	nv := (*interface{})(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "interface {}"
+	vs := "<nil>"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Sub-interface.
+	v2 := interface{}(uint16(65535))
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "uint16"
+	v2s := "65535"
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+}
+
+func addMapFormatterTests() {
+	// Map with string keys and int vals.
+	v := map[string]int{"one": 1, "two": 2}
+	nilMap := map[string]int(nil)
+	nv := (*map[string]int)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "map[string]int"
+	vs := "map[one:1 two:2]"
+	vs2 := "map[two:2 one:1]"
+	addFormatterTest("%v", v, vs, vs2)
+	addFormatterTest("%v", pv, "<*>"+vs, "<*>"+vs2)
+	addFormatterTest("%v", &pv, "<**>"+vs, "<**>"+vs2)
+	addFormatterTest("%+v", nilMap, "<nil>")
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs, vs2)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs, "<*>("+vAddr+")"+vs2)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs,
+		"<**>("+pvAddr+"->"+vAddr+")"+vs2)
+	addFormatterTest("%+v", nilMap, "<nil>")
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs, "("+vt+")"+vs2)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs, "(*"+vt+")"+vs2)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs, "(**"+vt+")"+vs2)
+	addFormatterTest("%#v", nilMap, "("+vt+")"+"<nil>")
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs, "("+vt+")"+vs2)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs,
+		"(*"+vt+")("+vAddr+")"+vs2)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs,
+		"(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs2)
+	addFormatterTest("%#+v", nilMap, "("+vt+")"+"<nil>")
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Map with custom formatter type on pointer receiver only keys and vals.
+	v2 := map[pstringer]pstringer{"one": "1"}
+	nv2 := (*map[pstringer]pstringer)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "map[spew_test.pstringer]spew_test.pstringer"
+	v2s := "map[stringer one:stringer 1]"
+	if spew.UnsafeDisabled {
+		v2s = "map[one:1]"
+	}
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+	// Map with interface keys and values.
+	v3 := map[interface{}]interface{}{"one": 1}
+	nv3 := (*map[interface{}]interface{})(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "map[interface {}]interface {}"
+	v3t1 := "string"
+	v3t2 := "int"
+	v3s := "map[one:1]"
+	v3s2 := "map[(" + v3t1 + ")one:(" + v3t2 + ")1]"
+	addFormatterTest("%v", v3, v3s)
+	addFormatterTest("%v", pv3, "<*>"+v3s)
+	addFormatterTest("%v", &pv3, "<**>"+v3s)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%+v", v3, v3s)
+	addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+	addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%#v", v3, "("+v3t+")"+v3s2)
+	addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s2)
+	addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s2)
+	addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+	addFormatterTest("%#+v", v3, "("+v3t+")"+v3s2)
+	addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2)
+	addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2)
+	addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"<nil>")
+
+	// Map with nil interface value
+	v4 := map[string]interface{}{"nil": nil}
+	nv4 := (*map[string]interface{})(nil)
+	pv4 := &v4
+	v4Addr := fmt.Sprintf("%p", pv4)
+	pv4Addr := fmt.Sprintf("%p", &pv4)
+	v4t := "map[string]interface {}"
+	v4t1 := "interface {}"
+	v4s := "map[nil:<nil>]"
+	v4s2 := "map[nil:(" + v4t1 + ")<nil>]"
+	addFormatterTest("%v", v4, v4s)
+	addFormatterTest("%v", pv4, "<*>"+v4s)
+	addFormatterTest("%v", &pv4, "<**>"+v4s)
+	addFormatterTest("%+v", nv4, "<nil>")
+	addFormatterTest("%+v", v4, v4s)
+	addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s)
+	addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s)
+	addFormatterTest("%+v", nv4, "<nil>")
+	addFormatterTest("%#v", v4, "("+v4t+")"+v4s2)
+	addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s2)
+	addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s2)
+	addFormatterTest("%#v", nv4, "(*"+v4t+")"+"<nil>")
+	addFormatterTest("%#+v", v4, "("+v4t+")"+v4s2)
+	addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s2)
+	addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s2)
+	addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"<nil>")
+}
+
+func addStructFormatterTests() {
+	// Struct with primitives.
+	type s1 struct {
+		a int8
+		b uint8
+	}
+	v := s1{127, 255}
+	nv := (*s1)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "spew_test.s1"
+	vt2 := "int8"
+	vt3 := "uint8"
+	vs := "{127 255}"
+	vs2 := "{a:127 b:255}"
+	vs3 := "{a:(" + vt2 + ")127 b:(" + vt3 + ")255}"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs2)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs2)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs2)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs3)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs3)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs3)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs3)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs3)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs3)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Struct that contains another struct.
+	type s2 struct {
+		s1 s1
+		b  bool
+	}
+	v2 := s2{s1{127, 255}, true}
+	nv2 := (*s2)(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "spew_test.s2"
+	v2t2 := "spew_test.s1"
+	v2t3 := "int8"
+	v2t4 := "uint8"
+	v2t5 := "bool"
+	v2s := "{{127 255} true}"
+	v2s2 := "{s1:{a:127 b:255} b:true}"
+	v2s3 := "{s1:(" + v2t2 + "){a:(" + v2t3 + ")127 b:(" + v2t4 + ")255} b:(" +
+		v2t5 + ")true}"
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%+v", v2, v2s2)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s2)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s2)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s3)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s3)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s3)
+	addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s3)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s3)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s3)
+	addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+	// Struct that contains custom type with Stringer pointer interface via both
+	// exported and unexported fields.
+	type s3 struct {
+		s pstringer
+		S pstringer
+	}
+	v3 := s3{"test", "test2"}
+	nv3 := (*s3)(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "spew_test.s3"
+	v3t2 := "spew_test.pstringer"
+	v3s := "{stringer test stringer test2}"
+	v3sp := v3s
+	v3s2 := "{s:stringer test S:stringer test2}"
+	v3s2p := v3s2
+	v3s3 := "{s:(" + v3t2 + ")stringer test S:(" + v3t2 + ")stringer test2}"
+	v3s3p := v3s3
+	if spew.UnsafeDisabled {
+		v3s = "{test test2}"
+		v3sp = "{test stringer test2}"
+		v3s2 = "{s:test S:test2}"
+		v3s2p = "{s:test S:stringer test2}"
+		v3s3 = "{s:(" + v3t2 + ")test S:(" + v3t2 + ")test2}"
+		v3s3p = "{s:(" + v3t2 + ")test S:(" + v3t2 + ")stringer test2}"
+	}
+	addFormatterTest("%v", v3, v3s)
+	addFormatterTest("%v", pv3, "<*>"+v3sp)
+	addFormatterTest("%v", &pv3, "<**>"+v3sp)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%+v", v3, v3s2)
+	addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s2p)
+	addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s2p)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%#v", v3, "("+v3t+")"+v3s3)
+	addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s3p)
+	addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s3p)
+	addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+	addFormatterTest("%#+v", v3, "("+v3t+")"+v3s3)
+	addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s3p)
+	addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s3p)
+	addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"<nil>")
+
+	// Struct that contains embedded struct and field to same struct.
+	e := embed{"embedstr"}
+	v4 := embedwrap{embed: &e, e: &e}
+	nv4 := (*embedwrap)(nil)
+	pv4 := &v4
+	eAddr := fmt.Sprintf("%p", &e)
+	v4Addr := fmt.Sprintf("%p", pv4)
+	pv4Addr := fmt.Sprintf("%p", &pv4)
+	v4t := "spew_test.embedwrap"
+	v4t2 := "spew_test.embed"
+	v4t3 := "string"
+	v4s := "{<*>{embedstr} <*>{embedstr}}"
+	v4s2 := "{embed:<*>(" + eAddr + "){a:embedstr} e:<*>(" + eAddr +
+		"){a:embedstr}}"
+	v4s3 := "{embed:(*" + v4t2 + "){a:(" + v4t3 + ")embedstr} e:(*" + v4t2 +
+		"){a:(" + v4t3 + ")embedstr}}"
+	v4s4 := "{embed:(*" + v4t2 + ")(" + eAddr + "){a:(" + v4t3 +
+		")embedstr} e:(*" + v4t2 + ")(" + eAddr + "){a:(" + v4t3 + ")embedstr}}"
+	addFormatterTest("%v", v4, v4s)
+	addFormatterTest("%v", pv4, "<*>"+v4s)
+	addFormatterTest("%v", &pv4, "<**>"+v4s)
+	addFormatterTest("%+v", nv4, "<nil>")
+	addFormatterTest("%+v", v4, v4s2)
+	addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s2)
+	addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s2)
+	addFormatterTest("%+v", nv4, "<nil>")
+	addFormatterTest("%#v", v4, "("+v4t+")"+v4s3)
+	addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s3)
+	addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s3)
+	addFormatterTest("%#v", nv4, "(*"+v4t+")"+"<nil>")
+	addFormatterTest("%#+v", v4, "("+v4t+")"+v4s4)
+	addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s4)
+	addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s4)
+	addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"<nil>")
+}
+
+func addUintptrFormatterTests() {
+	// Null pointer.
+	v := uintptr(0)
+	nv := (*uintptr)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "uintptr"
+	vs := "<nil>"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Address of real variable.
+	i := 1
+	v2 := uintptr(unsafe.Pointer(&i))
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "uintptr"
+	v2s := fmt.Sprintf("%p", &i)
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+}
+
+func addUnsafePointerFormatterTests() {
+	// Null pointer.
+	v := unsafe.Pointer(uintptr(0))
+	nv := (*unsafe.Pointer)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "unsafe.Pointer"
+	vs := "<nil>"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Address of real variable.
+	i := 1
+	v2 := unsafe.Pointer(&i)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "unsafe.Pointer"
+	v2s := fmt.Sprintf("%p", &i)
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+}
+
+func addChanFormatterTests() {
+	// Nil channel.
+	var v chan int
+	pv := &v
+	nv := (*chan int)(nil)
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "chan int"
+	vs := "<nil>"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Real channel.
+	v2 := make(chan int)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "chan int"
+	v2s := fmt.Sprintf("%p", v2)
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+}
+
+func addFuncFormatterTests() {
+	// Function with no params and no returns.
+	v := addIntFormatterTests
+	nv := (*func())(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "func()"
+	vs := fmt.Sprintf("%p", v)
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+	// Function with param and no returns.
+	v2 := TestFormatter
+	nv2 := (*func(*testing.T))(nil)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "func(*testing.T)"
+	v2s := fmt.Sprintf("%p", v2)
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s)
+	addFormatterTest("%v", &pv2, "<**>"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%+v", v2, v2s)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%+v", nv2, "<nil>")
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+	addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+	addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+	// Function with multiple params and multiple returns.
+	var v3 = func(i int, s string) (b bool, err error) {
+		return true, nil
+	}
+	nv3 := (*func(int, string) (bool, error))(nil)
+	pv3 := &v3
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "func(int, string) (bool, error)"
+	v3s := fmt.Sprintf("%p", v3)
+	addFormatterTest("%v", v3, v3s)
+	addFormatterTest("%v", pv3, "<*>"+v3s)
+	addFormatterTest("%v", &pv3, "<**>"+v3s)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%+v", v3, v3s)
+	addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+	addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+	addFormatterTest("%+v", nv3, "<nil>")
+	addFormatterTest("%#v", v3, "("+v3t+")"+v3s)
+	addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s)
+	addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s)
+	addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+	addFormatterTest("%#+v", v3, "("+v3t+")"+v3s)
+	addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s)
+	addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s)
+	addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"<nil>")
+}
+
+func addCircularFormatterTests() {
+	// Struct that is circular through self referencing.
+	type circular struct {
+		c *circular
+	}
+	v := circular{nil}
+	v.c = &v
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "spew_test.circular"
+	vs := "{<*>{<*><shown>}}"
+	vs2 := "{<*><shown>}"
+	vs3 := "{c:<*>(" + vAddr + "){c:<*>(" + vAddr + ")<shown>}}"
+	vs4 := "{c:<*>(" + vAddr + ")<shown>}"
+	vs5 := "{c:(*" + vt + "){c:(*" + vt + ")<shown>}}"
+	vs6 := "{c:(*" + vt + ")<shown>}"
+	vs7 := "{c:(*" + vt + ")(" + vAddr + "){c:(*" + vt + ")(" + vAddr +
+		")<shown>}}"
+	vs8 := "{c:(*" + vt + ")(" + vAddr + ")<shown>}"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs2)
+	addFormatterTest("%v", &pv, "<**>"+vs2)
+	addFormatterTest("%+v", v, vs3)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs4)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs4)
+	addFormatterTest("%#v", v, "("+vt+")"+vs5)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs6)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs6)
+	addFormatterTest("%#+v", v, "("+vt+")"+vs7)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs8)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs8)
+
+	// Structs that are circular through cross referencing.
+	v2 := xref1{nil}
+	ts2 := xref2{&v2}
+	v2.ps2 = &ts2
+	pv2 := &v2
+	ts2Addr := fmt.Sprintf("%p", &ts2)
+	v2Addr := fmt.Sprintf("%p", pv2)
+	pv2Addr := fmt.Sprintf("%p", &pv2)
+	v2t := "spew_test.xref1"
+	v2t2 := "spew_test.xref2"
+	v2s := "{<*>{<*>{<*><shown>}}}"
+	v2s2 := "{<*>{<*><shown>}}"
+	v2s3 := "{ps2:<*>(" + ts2Addr + "){ps1:<*>(" + v2Addr + "){ps2:<*>(" +
+		ts2Addr + ")<shown>}}}"
+	v2s4 := "{ps2:<*>(" + ts2Addr + "){ps1:<*>(" + v2Addr + ")<shown>}}"
+	v2s5 := "{ps2:(*" + v2t2 + "){ps1:(*" + v2t + "){ps2:(*" + v2t2 +
+		")<shown>}}}"
+	v2s6 := "{ps2:(*" + v2t2 + "){ps1:(*" + v2t + ")<shown>}}"
+	v2s7 := "{ps2:(*" + v2t2 + ")(" + ts2Addr + "){ps1:(*" + v2t +
+		")(" + v2Addr + "){ps2:(*" + v2t2 + ")(" + ts2Addr +
+		")<shown>}}}"
+	v2s8 := "{ps2:(*" + v2t2 + ")(" + ts2Addr + "){ps1:(*" + v2t +
+		")(" + v2Addr + ")<shown>}}"
+	addFormatterTest("%v", v2, v2s)
+	addFormatterTest("%v", pv2, "<*>"+v2s2)
+	addFormatterTest("%v", &pv2, "<**>"+v2s2)
+	addFormatterTest("%+v", v2, v2s3)
+	addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s4)
+	addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s4)
+	addFormatterTest("%#v", v2, "("+v2t+")"+v2s5)
+	addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s6)
+	addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s6)
+	addFormatterTest("%#+v", v2, "("+v2t+")"+v2s7)
+	addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s8)
+	addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s8)
+
+	// Structs that are indirectly circular.
+	v3 := indirCir1{nil}
+	tic2 := indirCir2{nil}
+	tic3 := indirCir3{&v3}
+	tic2.ps3 = &tic3
+	v3.ps2 = &tic2
+	pv3 := &v3
+	tic2Addr := fmt.Sprintf("%p", &tic2)
+	tic3Addr := fmt.Sprintf("%p", &tic3)
+	v3Addr := fmt.Sprintf("%p", pv3)
+	pv3Addr := fmt.Sprintf("%p", &pv3)
+	v3t := "spew_test.indirCir1"
+	v3t2 := "spew_test.indirCir2"
+	v3t3 := "spew_test.indirCir3"
+	v3s := "{<*>{<*>{<*>{<*><shown>}}}}"
+	v3s2 := "{<*>{<*>{<*><shown>}}}"
+	v3s3 := "{ps2:<*>(" + tic2Addr + "){ps3:<*>(" + tic3Addr + "){ps1:<*>(" +
+		v3Addr + "){ps2:<*>(" + tic2Addr + ")<shown>}}}}"
+	v3s4 := "{ps2:<*>(" + tic2Addr + "){ps3:<*>(" + tic3Addr + "){ps1:<*>(" +
+		v3Addr + ")<shown>}}}"
+	v3s5 := "{ps2:(*" + v3t2 + "){ps3:(*" + v3t3 + "){ps1:(*" + v3t +
+		"){ps2:(*" + v3t2 + ")<shown>}}}}"
+	v3s6 := "{ps2:(*" + v3t2 + "){ps3:(*" + v3t3 + "){ps1:(*" + v3t +
+		")<shown>}}}"
+	v3s7 := "{ps2:(*" + v3t2 + ")(" + tic2Addr + "){ps3:(*" + v3t3 + ")(" +
+		tic3Addr + "){ps1:(*" + v3t + ")(" + v3Addr + "){ps2:(*" + v3t2 +
+		")(" + tic2Addr + ")<shown>}}}}"
+	v3s8 := "{ps2:(*" + v3t2 + ")(" + tic2Addr + "){ps3:(*" + v3t3 + ")(" +
+		tic3Addr + "){ps1:(*" + v3t + ")(" + v3Addr + ")<shown>}}}"
+	addFormatterTest("%v", v3, v3s)
+	addFormatterTest("%v", pv3, "<*>"+v3s2)
+	addFormatterTest("%v", &pv3, "<**>"+v3s2)
+	addFormatterTest("%+v", v3, v3s3)
+	addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s4)
+	addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s4)
+	addFormatterTest("%#v", v3, "("+v3t+")"+v3s5)
+	addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s6)
+	addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s6)
+	addFormatterTest("%#+v", v3, "("+v3t+")"+v3s7)
+	addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s8)
+	addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s8)
+}
+
+func addPanicFormatterTests() {
+	// Type that panics in its Stringer interface.
+	v := panicer(127)
+	nv := (*panicer)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "spew_test.panicer"
+	vs := "(PANIC=test panic)127"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+}
+
+func addErrorFormatterTests() {
+	// Type that has a custom Error interface.
+	v := customError(127)
+	nv := (*customError)(nil)
+	pv := &v
+	vAddr := fmt.Sprintf("%p", pv)
+	pvAddr := fmt.Sprintf("%p", &pv)
+	vt := "spew_test.customError"
+	vs := "error: 127"
+	addFormatterTest("%v", v, vs)
+	addFormatterTest("%v", pv, "<*>"+vs)
+	addFormatterTest("%v", &pv, "<**>"+vs)
+	addFormatterTest("%v", nv, "<nil>")
+	addFormatterTest("%+v", v, vs)
+	addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+	addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%+v", nv, "<nil>")
+	addFormatterTest("%#v", v, "("+vt+")"+vs)
+	addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+	addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+	addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+	addFormatterTest("%#+v", v, "("+vt+")"+vs)
+	addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+	addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+	addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+}
+
+func addPassthroughFormatterTests() {
+	// %x passthrough with uint.
+	v := uint(4294967295)
+	pv := &v
+	vAddr := fmt.Sprintf("%x", pv)
+	pvAddr := fmt.Sprintf("%x", &pv)
+	vs := "ffffffff"
+	addFormatterTest("%x", v, vs)
+	addFormatterTest("%x", pv, vAddr)
+	addFormatterTest("%x", &pv, pvAddr)
+
+	// %#x passthrough with uint.
+	v2 := int(2147483647)
+	pv2 := &v2
+	v2Addr := fmt.Sprintf("%#x", pv2)
+	pv2Addr := fmt.Sprintf("%#x", &pv2)
+	v2s := "0x7fffffff"
+	addFormatterTest("%#x", v2, v2s)
+	addFormatterTest("%#x", pv2, v2Addr)
+	addFormatterTest("%#x", &pv2, pv2Addr)
+
+	// %f passthrough with precision.
+	addFormatterTest("%.2f", 3.1415, "3.14")
+	addFormatterTest("%.3f", 3.1415, "3.142")
+	addFormatterTest("%.4f", 3.1415, "3.1415")
+
+	// %f passthrough with width and precision.
+	addFormatterTest("%5.2f", 3.1415, " 3.14")
+	addFormatterTest("%6.3f", 3.1415, " 3.142")
+	addFormatterTest("%7.4f", 3.1415, " 3.1415")
+
+	// %d passthrough with width.
+	addFormatterTest("%3d", 127, "127")
+	addFormatterTest("%4d", 127, " 127")
+	addFormatterTest("%5d", 127, "  127")
+
+	// %q passthrough with string.
+	addFormatterTest("%q", "test", "\"test\"")
+}
+
+// TestFormatter executes all of the tests described by formatterTests.
+func TestFormatter(t *testing.T) {
+	// Setup tests.
+	addIntFormatterTests()
+	addUintFormatterTests()
+	addBoolFormatterTests()
+	addFloatFormatterTests()
+	addComplexFormatterTests()
+	addArrayFormatterTests()
+	addSliceFormatterTests()
+	addStringFormatterTests()
+	addInterfaceFormatterTests()
+	addMapFormatterTests()
+	addStructFormatterTests()
+	addUintptrFormatterTests()
+	addUnsafePointerFormatterTests()
+	addChanFormatterTests()
+	addFuncFormatterTests()
+	addCircularFormatterTests()
+	addPanicFormatterTests()
+	addErrorFormatterTests()
+	addPassthroughFormatterTests()
+
+	t.Logf("Running %d tests", len(formatterTests))
+	for i, test := range formatterTests {
+		buf := new(bytes.Buffer)
+		spew.Fprintf(buf, test.format, test.in)
+		s := buf.String()
+		if testFailed(s, test.wants) {
+			t.Errorf("Formatter #%d format: %s got: %s %s", i, test.format, s,
+				stringizeWants(test.wants))
+			continue
+		}
+	}
+}
+
+type testStruct struct {
+	x int
+}
+
+func (ts testStruct) String() string {
+	return fmt.Sprintf("ts.%d", ts.x)
+}
+
+type testStructP struct {
+	x int
+}
+
+func (ts *testStructP) String() string {
+	return fmt.Sprintf("ts.%d", ts.x)
+}
+
+func TestPrintSortedKeys(t *testing.T) {
+	cfg := spew.ConfigState{SortKeys: true}
+	s := cfg.Sprint(map[int]string{1: "1", 3: "3", 2: "2"})
+	expected := "map[1:1 2:2 3:3]"
+	if s != expected {
+		t.Errorf("Sorted keys mismatch 1:\n  %v %v", s, expected)
+	}
+
+	s = cfg.Sprint(map[stringer]int{"1": 1, "3": 3, "2": 2})
+	expected = "map[stringer 1:1 stringer 2:2 stringer 3:3]"
+	if s != expected {
+		t.Errorf("Sorted keys mismatch 2:\n  %v %v", s, expected)
+	}
+
+	s = cfg.Sprint(map[pstringer]int{pstringer("1"): 1, pstringer("3"): 3, pstringer("2"): 2})
+	expected = "map[stringer 1:1 stringer 2:2 stringer 3:3]"
+	if spew.UnsafeDisabled {
+		expected = "map[1:1 2:2 3:3]"
+	}
+	if s != expected {
+		t.Errorf("Sorted keys mismatch 3:\n  %v %v", s, expected)
+	}
+
+	s = cfg.Sprint(map[testStruct]int{testStruct{1}: 1, testStruct{3}: 3, testStruct{2}: 2})
+	expected = "map[ts.1:1 ts.2:2 ts.3:3]"
+	if s != expected {
+		t.Errorf("Sorted keys mismatch 4:\n  %v %v", s, expected)
+	}
+
+	if !spew.UnsafeDisabled {
+		s = cfg.Sprint(map[testStructP]int{testStructP{1}: 1, testStructP{3}: 3, testStructP{2}: 2})
+		expected = "map[ts.1:1 ts.2:2 ts.3:3]"
+		if s != expected {
+			t.Errorf("Sorted keys mismatch 5:\n  %v %v", s, expected)
+		}
+	}
+
+	s = cfg.Sprint(map[customError]int{customError(1): 1, customError(3): 3, customError(2): 2})
+	expected = "map[error: 1:1 error: 2:2 error: 3:3]"
+	if s != expected {
+		t.Errorf("Sorted keys mismatch 6:\n  %v %v", s, expected)
+	}
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/internal_test.go b/go/src/github.com/davecgh/go-spew/spew/internal_test.go
new file mode 100644
index 0000000..1069ee2
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/internal_test.go
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+This test file is part of the spew package rather than than the spew_test
+package because it needs access to internals to properly test certain cases
+which are not possible via the public interface since they should never happen.
+*/
+
+package spew
+
+import (
+	"bytes"
+	"reflect"
+	"testing"
+)
+
+// dummyFmtState implements a fake fmt.State to use for testing invalid
+// reflect.Value handling.  This is necessary because the fmt package catches
+// invalid values before invoking the formatter on them.
+type dummyFmtState struct {
+	bytes.Buffer
+}
+
+func (dfs *dummyFmtState) Flag(f int) bool {
+	if f == int('+') {
+		return true
+	}
+	return false
+}
+
+func (dfs *dummyFmtState) Precision() (int, bool) {
+	return 0, false
+}
+
+func (dfs *dummyFmtState) Width() (int, bool) {
+	return 0, false
+}
+
+// TestInvalidReflectValue ensures the dump and formatter code handles an
+// invalid reflect value properly.  This needs access to internal state since it
+// should never happen in real code and therefore can't be tested via the public
+// API.
+func TestInvalidReflectValue(t *testing.T) {
+	i := 1
+
+	// Dump invalid reflect value.
+	v := new(reflect.Value)
+	buf := new(bytes.Buffer)
+	d := dumpState{w: buf, cs: &Config}
+	d.dump(*v)
+	s := buf.String()
+	want := "<invalid>"
+	if s != want {
+		t.Errorf("InvalidReflectValue #%d\n got: %s want: %s", i, s, want)
+	}
+	i++
+
+	// Formatter invalid reflect value.
+	buf2 := new(dummyFmtState)
+	f := formatState{value: *v, cs: &Config, fs: buf2}
+	f.format(*v)
+	s = buf2.String()
+	want = "<invalid>"
+	if s != want {
+		t.Errorf("InvalidReflectValue #%d got: %s want: %s", i, s, want)
+	}
+}
+
+// SortValues makes the internal sortValues function available to the test
+// package.
+func SortValues(values []reflect.Value, cs *ConfigState) {
+	sortValues(values, cs)
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/internalunsafe_test.go b/go/src/github.com/davecgh/go-spew/spew/internalunsafe_test.go
new file mode 100644
index 0000000..83e070e
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/internalunsafe_test.go
@@ -0,0 +1,101 @@
+// Copyright (c) 2013-2015 Dave Collins <dave@davec.name>
+
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+// NOTE: Due to the following build constraints, this file will only be compiled
+// when the code is not running on Google App Engine and "-tags disableunsafe"
+// is not added to the go build command line.
+// +build !appengine,!disableunsafe
+
+/*
+This test file is part of the spew package rather than than the spew_test
+package because it needs access to internals to properly test certain cases
+which are not possible via the public interface since they should never happen.
+*/
+
+package spew
+
+import (
+	"bytes"
+	"reflect"
+	"testing"
+	"unsafe"
+)
+
+// changeKind uses unsafe to intentionally change the kind of a reflect.Value to
+// the maximum kind value which does not exist.  This is needed to test the
+// fallback code which punts to the standard fmt library for new types that
+// might get added to the language.
+func changeKind(v *reflect.Value, readOnly bool) {
+	rvf := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + offsetFlag))
+	*rvf = *rvf | ((1<<flagKindWidth - 1) << flagKindShift)
+	if readOnly {
+		*rvf |= flagRO
+	} else {
+		*rvf &= ^uintptr(flagRO)
+	}
+}
+
+// TestAddedReflectValue tests functionaly of the dump and formatter code which
+// falls back to the standard fmt library for new types that might get added to
+// the language.
+func TestAddedReflectValue(t *testing.T) {
+	i := 1
+
+	// Dump using a reflect.Value that is exported.
+	v := reflect.ValueOf(int8(5))
+	changeKind(&v, false)
+	buf := new(bytes.Buffer)
+	d := dumpState{w: buf, cs: &Config}
+	d.dump(v)
+	s := buf.String()
+	want := "(int8) 5"
+	if s != want {
+		t.Errorf("TestAddedReflectValue #%d\n got: %s want: %s", i, s, want)
+	}
+	i++
+
+	// Dump using a reflect.Value that is not exported.
+	changeKind(&v, true)
+	buf.Reset()
+	d.dump(v)
+	s = buf.String()
+	want = "(int8) <int8 Value>"
+	if s != want {
+		t.Errorf("TestAddedReflectValue #%d\n got: %s want: %s", i, s, want)
+	}
+	i++
+
+	// Formatter using a reflect.Value that is exported.
+	changeKind(&v, false)
+	buf2 := new(dummyFmtState)
+	f := formatState{value: v, cs: &Config, fs: buf2}
+	f.format(v)
+	s = buf2.String()
+	want = "5"
+	if s != want {
+		t.Errorf("TestAddedReflectValue #%d got: %s want: %s", i, s, want)
+	}
+	i++
+
+	// Formatter using a reflect.Value that is not exported.
+	changeKind(&v, true)
+	buf2.Reset()
+	f = formatState{value: v, cs: &Config, fs: buf2}
+	f.format(v)
+	s = buf2.String()
+	want = "<int8 Value>"
+	if s != want {
+		t.Errorf("TestAddedReflectValue #%d got: %s want: %s", i, s, want)
+	}
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/spew.go b/go/src/github.com/davecgh/go-spew/spew/spew.go
new file mode 100644
index 0000000..d8233f5
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/spew.go
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+	"fmt"
+	"io"
+)
+
+// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the formatted string as a value that satisfies error.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Errorf(format string, a ...interface{}) (err error) {
+	return fmt.Errorf(format, convertArgs(a)...)
+}
+
+// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
+func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
+	return fmt.Fprint(w, convertArgs(a)...)
+}
+
+// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
+	return fmt.Fprintf(w, format, convertArgs(a)...)
+}
+
+// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
+// passed with a default Formatter interface returned by NewFormatter.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
+func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
+	return fmt.Fprintln(w, convertArgs(a)...)
+}
+
+// Print is a wrapper for fmt.Print that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
+func Print(a ...interface{}) (n int, err error) {
+	return fmt.Print(convertArgs(a)...)
+}
+
+// Printf is a wrapper for fmt.Printf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Printf(format string, a ...interface{}) (n int, err error) {
+	return fmt.Printf(format, convertArgs(a)...)
+}
+
+// Println is a wrapper for fmt.Println that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
+func Println(a ...interface{}) (n int, err error) {
+	return fmt.Println(convertArgs(a)...)
+}
+
+// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))
+func Sprint(a ...interface{}) string {
+	return fmt.Sprint(convertArgs(a)...)
+}
+
+// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Sprintf(format string, a ...interface{}) string {
+	return fmt.Sprintf(format, convertArgs(a)...)
+}
+
+// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
+// were passed with a default Formatter interface returned by NewFormatter.  It
+// returns the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))
+func Sprintln(a ...interface{}) string {
+	return fmt.Sprintln(convertArgs(a)...)
+}
+
+// convertArgs accepts a slice of arguments and returns a slice of the same
+// length with each argument converted to a default spew Formatter interface.
+func convertArgs(args []interface{}) (formatters []interface{}) {
+	formatters = make([]interface{}, len(args))
+	for index, arg := range args {
+		formatters[index] = NewFormatter(arg)
+	}
+	return formatters
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/spew_test.go b/go/src/github.com/davecgh/go-spew/spew/spew_test.go
new file mode 100644
index 0000000..dbbc085
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/spew_test.go
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew_test
+
+import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"testing"
+
+	"github.com/davecgh/go-spew/spew"
+)
+
+// spewFunc is used to identify which public function of the spew package or
+// ConfigState a test applies to.
+type spewFunc int
+
+const (
+	fCSFdump spewFunc = iota
+	fCSFprint
+	fCSFprintf
+	fCSFprintln
+	fCSPrint
+	fCSPrintln
+	fCSSdump
+	fCSSprint
+	fCSSprintf
+	fCSSprintln
+	fCSErrorf
+	fCSNewFormatter
+	fErrorf
+	fFprint
+	fFprintln
+	fPrint
+	fPrintln
+	fSdump
+	fSprint
+	fSprintf
+	fSprintln
+)
+
+// Map of spewFunc values to names for pretty printing.
+var spewFuncStrings = map[spewFunc]string{
+	fCSFdump:        "ConfigState.Fdump",
+	fCSFprint:       "ConfigState.Fprint",
+	fCSFprintf:      "ConfigState.Fprintf",
+	fCSFprintln:     "ConfigState.Fprintln",
+	fCSSdump:        "ConfigState.Sdump",
+	fCSPrint:        "ConfigState.Print",
+	fCSPrintln:      "ConfigState.Println",
+	fCSSprint:       "ConfigState.Sprint",
+	fCSSprintf:      "ConfigState.Sprintf",
+	fCSSprintln:     "ConfigState.Sprintln",
+	fCSErrorf:       "ConfigState.Errorf",
+	fCSNewFormatter: "ConfigState.NewFormatter",
+	fErrorf:         "spew.Errorf",
+	fFprint:         "spew.Fprint",
+	fFprintln:       "spew.Fprintln",
+	fPrint:          "spew.Print",
+	fPrintln:        "spew.Println",
+	fSdump:          "spew.Sdump",
+	fSprint:         "spew.Sprint",
+	fSprintf:        "spew.Sprintf",
+	fSprintln:       "spew.Sprintln",
+}
+
+func (f spewFunc) String() string {
+	if s, ok := spewFuncStrings[f]; ok {
+		return s
+	}
+	return fmt.Sprintf("Unknown spewFunc (%d)", int(f))
+}
+
+// spewTest is used to describe a test to be performed against the public
+// functions of the spew package or ConfigState.
+type spewTest struct {
+	cs     *spew.ConfigState
+	f      spewFunc
+	format string
+	in     interface{}
+	want   string
+}
+
+// spewTests houses the tests to be performed against the public functions of
+// the spew package and ConfigState.
+//
+// These tests are only intended to ensure the public functions are exercised
+// and are intentionally not exhaustive of types.  The exhaustive type
+// tests are handled in the dump and format tests.
+var spewTests []spewTest
+
+// redirStdout is a helper function to return the standard output from f as a
+// byte slice.
+func redirStdout(f func()) ([]byte, error) {
+	tempFile, err := ioutil.TempFile("", "ss-test")
+	if err != nil {
+		return nil, err
+	}
+	fileName := tempFile.Name()
+	defer os.Remove(fileName) // Ignore error
+
+	origStdout := os.Stdout
+	os.Stdout = tempFile
+	f()
+	os.Stdout = origStdout
+	tempFile.Close()
+
+	return ioutil.ReadFile(fileName)
+}
+
+func initSpewTests() {
+	// Config states with various settings.
+	scsDefault := spew.NewDefaultConfig()
+	scsNoMethods := &spew.ConfigState{Indent: " ", DisableMethods: true}
+	scsNoPmethods := &spew.ConfigState{Indent: " ", DisablePointerMethods: true}
+	scsMaxDepth := &spew.ConfigState{Indent: " ", MaxDepth: 1}
+	scsContinue := &spew.ConfigState{Indent: " ", ContinueOnMethod: true}
+
+	// Variables for tests on types which implement Stringer interface with and
+	// without a pointer receiver.
+	ts := stringer("test")
+	tps := pstringer("test")
+
+	// depthTester is used to test max depth handling for structs, array, slices
+	// and maps.
+	type depthTester struct {
+		ic    indirCir1
+		arr   [1]string
+		slice []string
+		m     map[string]int
+	}
+	dt := depthTester{indirCir1{nil}, [1]string{"arr"}, []string{"slice"},
+		map[string]int{"one": 1}}
+
+	// Variable for tests on types which implement error interface.
+	te := customError(10)
+
+	spewTests = []spewTest{
+		{scsDefault, fCSFdump, "", int8(127), "(int8) 127\n"},
+		{scsDefault, fCSFprint, "", int16(32767), "32767"},
+		{scsDefault, fCSFprintf, "%v", int32(2147483647), "2147483647"},
+		{scsDefault, fCSFprintln, "", int(2147483647), "2147483647\n"},
+		{scsDefault, fCSPrint, "", int64(9223372036854775807), "9223372036854775807"},
+		{scsDefault, fCSPrintln, "", uint8(255), "255\n"},
+		{scsDefault, fCSSdump, "", uint8(64), "(uint8) 64\n"},
+		{scsDefault, fCSSprint, "", complex(1, 2), "(1+2i)"},
+		{scsDefault, fCSSprintf, "%v", complex(float32(3), 4), "(3+4i)"},
+		{scsDefault, fCSSprintln, "", complex(float64(5), 6), "(5+6i)\n"},
+		{scsDefault, fCSErrorf, "%#v", uint16(65535), "(uint16)65535"},
+		{scsDefault, fCSNewFormatter, "%v", uint32(4294967295), "4294967295"},
+		{scsDefault, fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"},
+		{scsDefault, fFprint, "", float32(3.14), "3.14"},
+		{scsDefault, fFprintln, "", float64(6.28), "6.28\n"},
+		{scsDefault, fPrint, "", true, "true"},
+		{scsDefault, fPrintln, "", false, "false\n"},
+		{scsDefault, fSdump, "", complex(-10, -20), "(complex128) (-10-20i)\n"},
+		{scsDefault, fSprint, "", complex(-1, -2), "(-1-2i)"},
+		{scsDefault, fSprintf, "%v", complex(float32(-3), -4), "(-3-4i)"},
+		{scsDefault, fSprintln, "", complex(float64(-5), -6), "(-5-6i)\n"},
+		{scsNoMethods, fCSFprint, "", ts, "test"},
+		{scsNoMethods, fCSFprint, "", &ts, "<*>test"},
+		{scsNoMethods, fCSFprint, "", tps, "test"},
+		{scsNoMethods, fCSFprint, "", &tps, "<*>test"},
+		{scsNoPmethods, fCSFprint, "", ts, "stringer test"},
+		{scsNoPmethods, fCSFprint, "", &ts, "<*>stringer test"},
+		{scsNoPmethods, fCSFprint, "", tps, "test"},
+		{scsNoPmethods, fCSFprint, "", &tps, "<*>stringer test"},
+		{scsMaxDepth, fCSFprint, "", dt, "{{<max>} [<max>] [<max>] map[<max>]}"},
+		{scsMaxDepth, fCSFdump, "", dt, "(spew_test.depthTester) {\n" +
+			" ic: (spew_test.indirCir1) {\n  <max depth reached>\n },\n" +
+			" arr: ([1]string) (len=1 cap=1) {\n  <max depth reached>\n },\n" +
+			" slice: ([]string) (len=1 cap=1) {\n  <max depth reached>\n },\n" +
+			" m: (map[string]int) (len=1) {\n  <max depth reached>\n }\n}\n"},
+		{scsContinue, fCSFprint, "", ts, "(stringer test) test"},
+		{scsContinue, fCSFdump, "", ts, "(spew_test.stringer) " +
+			"(len=4) (stringer test) \"test\"\n"},
+		{scsContinue, fCSFprint, "", te, "(error: 10) 10"},
+		{scsContinue, fCSFdump, "", te, "(spew_test.customError) " +
+			"(error: 10) 10\n"},
+	}
+}
+
+// TestSpew executes all of the tests described by spewTests.
+func TestSpew(t *testing.T) {
+	initSpewTests()
+
+	t.Logf("Running %d tests", len(spewTests))
+	for i, test := range spewTests {
+		buf := new(bytes.Buffer)
+		switch test.f {
+		case fCSFdump:
+			test.cs.Fdump(buf, test.in)
+
+		case fCSFprint:
+			test.cs.Fprint(buf, test.in)
+
+		case fCSFprintf:
+			test.cs.Fprintf(buf, test.format, test.in)
+
+		case fCSFprintln:
+			test.cs.Fprintln(buf, test.in)
+
+		case fCSPrint:
+			b, err := redirStdout(func() { test.cs.Print(test.in) })
+			if err != nil {
+				t.Errorf("%v #%d %v", test.f, i, err)
+				continue
+			}
+			buf.Write(b)
+
+		case fCSPrintln:
+			b, err := redirStdout(func() { test.cs.Println(test.in) })
+			if err != nil {
+				t.Errorf("%v #%d %v", test.f, i, err)
+				continue
+			}
+			buf.Write(b)
+
+		case fCSSdump:
+			str := test.cs.Sdump(test.in)
+			buf.WriteString(str)
+
+		case fCSSprint:
+			str := test.cs.Sprint(test.in)
+			buf.WriteString(str)
+
+		case fCSSprintf:
+			str := test.cs.Sprintf(test.format, test.in)
+			buf.WriteString(str)
+
+		case fCSSprintln:
+			str := test.cs.Sprintln(test.in)
+			buf.WriteString(str)
+
+		case fCSErrorf:
+			err := test.cs.Errorf(test.format, test.in)
+			buf.WriteString(err.Error())
+
+		case fCSNewFormatter:
+			fmt.Fprintf(buf, test.format, test.cs.NewFormatter(test.in))
+
+		case fErrorf:
+			err := spew.Errorf(test.format, test.in)
+			buf.WriteString(err.Error())
+
+		case fFprint:
+			spew.Fprint(buf, test.in)
+
+		case fFprintln:
+			spew.Fprintln(buf, test.in)
+
+		case fPrint:
+			b, err := redirStdout(func() { spew.Print(test.in) })
+			if err != nil {
+				t.Errorf("%v #%d %v", test.f, i, err)
+				continue
+			}
+			buf.Write(b)
+
+		case fPrintln:
+			b, err := redirStdout(func() { spew.Println(test.in) })
+			if err != nil {
+				t.Errorf("%v #%d %v", test.f, i, err)
+				continue
+			}
+			buf.Write(b)
+
+		case fSdump:
+			str := spew.Sdump(test.in)
+			buf.WriteString(str)
+
+		case fSprint:
+			str := spew.Sprint(test.in)
+			buf.WriteString(str)
+
+		case fSprintf:
+			str := spew.Sprintf(test.format, test.in)
+			buf.WriteString(str)
+
+		case fSprintln:
+			str := spew.Sprintln(test.in)
+			buf.WriteString(str)
+
+		default:
+			t.Errorf("%v #%d unrecognized function", test.f, i)
+			continue
+		}
+		s := buf.String()
+		if test.want != s {
+			t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want)
+			continue
+		}
+	}
+}
diff --git a/go/src/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go b/go/src/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go
new file mode 100644
index 0000000..5c87dd4
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go
@@ -0,0 +1,82 @@
+// Copyright (c) 2013 Dave Collins <dave@davec.name>
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+// NOTE: Due to the following build constraints, this file will only be compiled
+// when both cgo is supported and "-tags testcgo" is added to the go test
+// command line.  This code should really only be in the dumpcgo_test.go file,
+// but unfortunately Go will not allow cgo in test files, so this is a
+// workaround to allow cgo types to be tested.  This configuration is used
+// because spew itself does not require cgo to run even though it does handle
+// certain cgo types specially.  Rather than forcing all clients to require cgo
+// and an external C compiler just to run the tests, this scheme makes them
+// optional.
+// +build cgo,testcgo
+
+package testdata
+
+/*
+#include <stdint.h>
+typedef unsigned char custom_uchar_t;
+
+char            *ncp = 0;
+char            *cp = "test";
+char             ca[6] = {'t', 'e', 's', 't', '2', '\0'};
+unsigned char    uca[6] = {'t', 'e', 's', 't', '3', '\0'};
+signed char      sca[6] = {'t', 'e', 's', 't', '4', '\0'};
+uint8_t          ui8ta[6] = {'t', 'e', 's', 't', '5', '\0'};
+custom_uchar_t   tuca[6] = {'t', 'e', 's', 't', '6', '\0'};
+*/
+import "C"
+
+// GetCgoNullCharPointer returns a null char pointer via cgo.  This is only
+// used for tests.
+func GetCgoNullCharPointer() interface{} {
+	return C.ncp
+}
+
+// GetCgoCharPointer returns a char pointer via cgo.  This is only used for
+// tests.
+func GetCgoCharPointer() interface{} {
+	return C.cp
+}
+
+// GetCgoCharArray returns a char array via cgo and the array's len and cap.
+// This is only used for tests.
+func GetCgoCharArray() (interface{}, int, int) {
+	return C.ca, len(C.ca), cap(C.ca)
+}
+
+// GetCgoUnsignedCharArray returns an unsigned char array via cgo and the
+// array's len and cap.  This is only used for tests.
+func GetCgoUnsignedCharArray() (interface{}, int, int) {
+	return C.uca, len(C.uca), cap(C.uca)
+}
+
+// GetCgoSignedCharArray returns a signed char array via cgo and the array's len
+// and cap.  This is only used for tests.
+func GetCgoSignedCharArray() (interface{}, int, int) {
+	return C.sca, len(C.sca), cap(C.sca)
+}
+
+// GetCgoUint8tArray returns a uint8_t array via cgo and the array's len and
+// cap.  This is only used for tests.
+func GetCgoUint8tArray() (interface{}, int, int) {
+	return C.ui8ta, len(C.ui8ta), cap(C.ui8ta)
+}
+
+// GetCgoTypdefedUnsignedCharArray returns a typedefed unsigned char array via
+// cgo and the array's len and cap.  This is only used for tests.
+func GetCgoTypdefedUnsignedCharArray() (interface{}, int, int) {
+	return C.tuca, len(C.tuca), cap(C.tuca)
+}
diff --git a/go/src/github.com/davecgh/go-spew/test_coverage.txt b/go/src/github.com/davecgh/go-spew/test_coverage.txt
new file mode 100644
index 0000000..2cd087a
--- /dev/null
+++ b/go/src/github.com/davecgh/go-spew/test_coverage.txt
@@ -0,0 +1,61 @@
+
+github.com/davecgh/go-spew/spew/dump.go		 dumpState.dump			 100.00% (88/88)
+github.com/davecgh/go-spew/spew/format.go	 formatState.format		 100.00% (82/82)
+github.com/davecgh/go-spew/spew/format.go	 formatState.formatPtr		 100.00% (52/52)
+github.com/davecgh/go-spew/spew/dump.go		 dumpState.dumpPtr		 100.00% (44/44)
+github.com/davecgh/go-spew/spew/dump.go		 dumpState.dumpSlice		 100.00% (39/39)
+github.com/davecgh/go-spew/spew/common.go	 handleMethods			 100.00% (30/30)
+github.com/davecgh/go-spew/spew/common.go	 printHexPtr			 100.00% (18/18)
+github.com/davecgh/go-spew/spew/common.go	 unsafeReflectValue		 100.00% (13/13)
+github.com/davecgh/go-spew/spew/format.go	 formatState.constructOrigFormat 100.00% (12/12)
+github.com/davecgh/go-spew/spew/dump.go		 fdump				 100.00% (11/11)
+github.com/davecgh/go-spew/spew/format.go	 formatState.Format		 100.00% (11/11)
+github.com/davecgh/go-spew/spew/common.go	 init				 100.00% (10/10)
+github.com/davecgh/go-spew/spew/common.go	 printComplex			 100.00% (9/9)
+github.com/davecgh/go-spew/spew/common.go	 valuesSorter.Less		 100.00% (8/8)
+github.com/davecgh/go-spew/spew/format.go	 formatState.buildDefaultFormat	 100.00% (7/7)
+github.com/davecgh/go-spew/spew/format.go	 formatState.unpackValue	 100.00% (5/5)
+github.com/davecgh/go-spew/spew/dump.go		 dumpState.indent		 100.00% (4/4)
+github.com/davecgh/go-spew/spew/common.go	 catchPanic			 100.00% (4/4)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.convertArgs	 100.00% (4/4)
+github.com/davecgh/go-spew/spew/spew.go		 convertArgs			 100.00% (4/4)
+github.com/davecgh/go-spew/spew/format.go	 newFormatter			 100.00% (3/3)
+github.com/davecgh/go-spew/spew/dump.go		 Sdump				 100.00% (3/3)
+github.com/davecgh/go-spew/spew/common.go	 printBool			 100.00% (3/3)
+github.com/davecgh/go-spew/spew/common.go	 sortValues			 100.00% (3/3)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Sdump		 100.00% (3/3)
+github.com/davecgh/go-spew/spew/dump.go		 dumpState.unpackValue		 100.00% (3/3)
+github.com/davecgh/go-spew/spew/spew.go		 Printf				 100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go		 Println			 100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go		 Sprint				 100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go		 Sprintf			 100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go		 Sprintln			 100.00% (1/1)
+github.com/davecgh/go-spew/spew/common.go	 printFloat			 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 NewDefaultConfig		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/common.go	 printInt			 100.00% (1/1)
+github.com/davecgh/go-spew/spew/common.go	 printUint			 100.00% (1/1)
+github.com/davecgh/go-spew/spew/common.go	 valuesSorter.Len		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/common.go	 valuesSorter.Swap		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Errorf		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Fprint		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Fprintf		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Fprintln		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Print		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Printf		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Println		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Sprint		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Sprintf		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Sprintln		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.NewFormatter	 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Fdump		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go	 ConfigState.Dump		 100.00% (1/1)
+github.com/davecgh/go-spew/spew/dump.go		 Fdump				 100.00% (1/1)
+github.com/davecgh/go-spew/spew/dump.go		 Dump				 100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go		 Fprintln			 100.00% (1/1)
+github.com/davecgh/go-spew/spew/format.go	 NewFormatter			 100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go		 Errorf				 100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go		 Fprint				 100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go		 Fprintf			 100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go		 Print				 100.00% (1/1)
+github.com/davecgh/go-spew/spew			 ------------------------------- 100.00% (505/505)
+
diff --git a/go/src/github.com/pmezard/go-difflib/.travis.yml b/go/src/github.com/pmezard/go-difflib/.travis.yml
new file mode 100644
index 0000000..90c9c6f
--- /dev/null
+++ b/go/src/github.com/pmezard/go-difflib/.travis.yml
@@ -0,0 +1,5 @@
+language: go
+go:
+  - 1.5
+  - tip
+
diff --git a/go/src/github.com/pmezard/go-difflib/LICENSE b/go/src/github.com/pmezard/go-difflib/LICENSE
new file mode 100644
index 0000000..c67dad6
--- /dev/null
+++ b/go/src/github.com/pmezard/go-difflib/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013, Patrick Mezard
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+    The names of its contributors may not be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/go/src/github.com/pmezard/go-difflib/README.google b/go/src/github.com/pmezard/go-difflib/README.google
new file mode 100644
index 0000000..4bdb7c4
--- /dev/null
+++ b/go/src/github.com/pmezard/go-difflib/README.google
@@ -0,0 +1,11 @@
+URL: https://github.com/pmezard/go-difflib/archive/792786c7400a136282c1664665ae0a8db921c6c2.zip
+Version: 792786c7400a136282c1664665ae0a8db921c6c2
+License: MIT
+License File: LICENSE
+
+Description:
+Go-difflib is a partial port of python 3 difflib package. Its main goal was to
+make unified and context diff available in pure Go, mostly for testing purposes.
+
+Local Modifications:
+None.
diff --git a/go/src/github.com/pmezard/go-difflib/README.md b/go/src/github.com/pmezard/go-difflib/README.md
new file mode 100644
index 0000000..e87f307
--- /dev/null
+++ b/go/src/github.com/pmezard/go-difflib/README.md
@@ -0,0 +1,50 @@
+go-difflib
+==========
+
+[![Build Status](https://travis-ci.org/pmezard/go-difflib.png?branch=master)](https://travis-ci.org/pmezard/go-difflib)
+[![GoDoc](https://godoc.org/github.com/pmezard/go-difflib/difflib?status.svg)](https://godoc.org/github.com/pmezard/go-difflib/difflib)
+
+Go-difflib is a partial port of python 3 difflib package. Its main goal
+was to make unified and context diff available in pure Go, mostly for
+testing purposes.
+
+The following class and functions (and related tests) have be ported:
+
+* `SequenceMatcher`
+* `unified_diff()`
+* `context_diff()`
+
+## Installation
+
+```bash
+$ go get github.com/pmezard/go-difflib/difflib
+```
+
+### Quick Start
+
+Diffs are configured with Unified (or ContextDiff) structures, and can
+be output to an io.Writer or returned as a string.
+
+```Go
+diff := UnifiedDiff{
+    A:        difflib.SplitLines("foo\nbar\n"),
+    B:        difflib.SplitLines("foo\nbaz\n"),
+    FromFile: "Original",
+    ToFile:   "Current",
+    Context:  3,
+}
+text, _ := GetUnifiedDiffString(diff)
+fmt.Printf(text)
+```
+
+would output:
+
+```
+--- Original
++++ Current
+@@ -1,3 +1,3 @@
+ foo
+-bar
++baz
+```
+
diff --git a/go/src/github.com/pmezard/go-difflib/difflib/difflib.go b/go/src/github.com/pmezard/go-difflib/difflib/difflib.go
new file mode 100644
index 0000000..003e99f
--- /dev/null
+++ b/go/src/github.com/pmezard/go-difflib/difflib/difflib.go
@@ -0,0 +1,772 @@
+// Package difflib is a partial port of Python difflib module.
+//
+// It provides tools to compare sequences of strings and generate textual diffs.
+//
+// The following class and functions have been ported:
+//
+// - SequenceMatcher
+//
+// - unified_diff
+//
+// - context_diff
+//
+// Getting unified diffs was the main goal of the port. Keep in mind this code
+// is mostly suitable to output text differences in a human friendly way, there
+// are no guarantees generated diffs are consumable by patch(1).
+package difflib
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"strings"
+)
+
+func min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}
+
+func max(a, b int) int {
+	if a > b {
+		return a
+	}
+	return b
+}
+
+func calculateRatio(matches, length int) float64 {
+	if length > 0 {
+		return 2.0 * float64(matches) / float64(length)
+	}
+	return 1.0
+}
+
+type Match struct {
+	A    int
+	B    int
+	Size int
+}
+
+type OpCode struct {
+	Tag byte
+	I1  int
+	I2  int
+	J1  int
+	J2  int
+}
+
+// SequenceMatcher compares sequence of strings. The basic
+// algorithm predates, and is a little fancier than, an algorithm
+// published in the late 1980's by Ratcliff and Obershelp under the
+// hyperbolic name "gestalt pattern matching".  The basic idea is to find
+// the longest contiguous matching subsequence that contains no "junk"
+// elements (R-O doesn't address junk).  The same idea is then applied
+// recursively to the pieces of the sequences to the left and to the right
+// of the matching subsequence.  This does not yield minimal edit
+// sequences, but does tend to yield matches that "look right" to people.
+//
+// SequenceMatcher tries to compute a "human-friendly diff" between two
+// sequences.  Unlike e.g. UNIX(tm) diff, the fundamental notion is the
+// longest *contiguous* & junk-free matching subsequence.  That's what
+// catches peoples' eyes.  The Windows(tm) windiff has another interesting
+// notion, pairing up elements that appear uniquely in each sequence.
+// That, and the method here, appear to yield more intuitive difference
+// reports than does diff.  This method appears to be the least vulnerable
+// to synching up on blocks of "junk lines", though (like blank lines in
+// ordinary text files, or maybe "<P>" lines in HTML files).  That may be
+// because this is the only method of the 3 that has a *concept* of
+// "junk" <wink>.
+//
+// Timing:  Basic R-O is cubic time worst case and quadratic time expected
+// case.  SequenceMatcher is quadratic time for the worst case and has
+// expected-case behavior dependent in a complicated way on how many
+// elements the sequences have in common; best case time is linear.
+type SequenceMatcher struct {
+	a              []string
+	b              []string
+	b2j            map[string][]int
+	IsJunk         func(string) bool
+	autoJunk       bool
+	bJunk          map[string]struct{}
+	matchingBlocks []Match
+	fullBCount     map[string]int
+	bPopular       map[string]struct{}
+	opCodes        []OpCode
+}
+
+func NewMatcher(a, b []string) *SequenceMatcher {
+	m := SequenceMatcher{autoJunk: true}
+	m.SetSeqs(a, b)
+	return &m
+}
+
+func NewMatcherWithJunk(a, b []string, autoJunk bool,
+	isJunk func(string) bool) *SequenceMatcher {
+
+	m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk}
+	m.SetSeqs(a, b)
+	return &m
+}
+
+// Set two sequences to be compared.
+func (m *SequenceMatcher) SetSeqs(a, b []string) {
+	m.SetSeq1(a)
+	m.SetSeq2(b)
+}
+
+// Set the first sequence to be compared. The second sequence to be compared is
+// not changed.
+//
+// SequenceMatcher computes and caches detailed information about the second
+// sequence, so if you want to compare one sequence S against many sequences,
+// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other
+// sequences.
+//
+// See also SetSeqs() and SetSeq2().
+func (m *SequenceMatcher) SetSeq1(a []string) {
+	if &a == &m.a {
+		return
+	}
+	m.a = a
+	m.matchingBlocks = nil
+	m.opCodes = nil
+}
+
+// Set the second sequence to be compared. The first sequence to be compared is
+// not changed.
+func (m *SequenceMatcher) SetSeq2(b []string) {
+	if &b == &m.b {
+		return
+	}
+	m.b = b
+	m.matchingBlocks = nil
+	m.opCodes = nil
+	m.fullBCount = nil
+	m.chainB()
+}
+
+func (m *SequenceMatcher) chainB() {
+	// Populate line -> index mapping
+	b2j := map[string][]int{}
+	for i, s := range m.b {
+		indices := b2j[s]
+		indices = append(indices, i)
+		b2j[s] = indices
+	}
+
+	// Purge junk elements
+	m.bJunk = map[string]struct{}{}
+	if m.IsJunk != nil {
+		junk := m.bJunk
+		for s, _ := range b2j {
+			if m.IsJunk(s) {
+				junk[s] = struct{}{}
+			}
+		}
+		for s, _ := range junk {
+			delete(b2j, s)
+		}
+	}
+
+	// Purge remaining popular elements
+	popular := map[string]struct{}{}
+	n := len(m.b)
+	if m.autoJunk && n >= 200 {
+		ntest := n/100 + 1
+		for s, indices := range b2j {
+			if len(indices) > ntest {
+				popular[s] = struct{}{}
+			}
+		}
+		for s, _ := range popular {
+			delete(b2j, s)
+		}
+	}
+	m.bPopular = popular
+	m.b2j = b2j
+}
+
+func (m *SequenceMatcher) isBJunk(s string) bool {
+	_, ok := m.bJunk[s]
+	return ok
+}
+
+// Find longest matching block in a[alo:ahi] and b[blo:bhi].
+//
+// If IsJunk is not defined:
+//
+// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
+//     alo <= i <= i+k <= ahi
+//     blo <= j <= j+k <= bhi
+// and for all (i',j',k') meeting those conditions,
+//     k >= k'
+//     i <= i'
+//     and if i == i', j <= j'
+//
+// In other words, of all maximal matching blocks, return one that
+// starts earliest in a, and of all those maximal matching blocks that
+// start earliest in a, return the one that starts earliest in b.
+//
+// If IsJunk is defined, first the longest matching block is
+// determined as above, but with the additional restriction that no
+// junk element appears in the block.  Then that block is extended as
+// far as possible by matching (only) junk elements on both sides.  So
+// the resulting block never matches on junk except as identical junk
+// happens to be adjacent to an "interesting" match.
+//
+// If no blocks match, return (alo, blo, 0).
+func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {
+	// CAUTION:  stripping common prefix or suffix would be incorrect.
+	// E.g.,
+	//    ab
+	//    acab
+	// Longest matching block is "ab", but if common prefix is
+	// stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
+	// strip, so ends up claiming that ab is changed to acab by
+	// inserting "ca" in the middle.  That's minimal but unintuitive:
+	// "it's obvious" that someone inserted "ac" at the front.
+	// Windiff ends up at the same place as diff, but by pairing up
+	// the unique 'b's and then matching the first two 'a's.
+	besti, bestj, bestsize := alo, blo, 0
+
+	// find longest junk-free match
+	// during an iteration of the loop, j2len[j] = length of longest
+	// junk-free match ending with a[i-1] and b[j]
+	j2len := map[int]int{}
+	for i := alo; i != ahi; i++ {
+		// look at all instances of a[i] in b; note that because
+		// b2j has no junk keys, the loop is skipped if a[i] is junk
+		newj2len := map[int]int{}
+		for _, j := range m.b2j[m.a[i]] {
+			// a[i] matches b[j]
+			if j < blo {
+				continue
+			}
+			if j >= bhi {
+				break
+			}
+			k := j2len[j-1] + 1
+			newj2len[j] = k
+			if k > bestsize {
+				besti, bestj, bestsize = i-k+1, j-k+1, k
+			}
+		}
+		j2len = newj2len
+	}
+
+	// Extend the best by non-junk elements on each end.  In particular,
+	// "popular" non-junk elements aren't in b2j, which greatly speeds
+	// the inner loop above, but also means "the best" match so far
+	// doesn't contain any junk *or* popular non-junk elements.
+	for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) &&
+		m.a[besti-1] == m.b[bestj-1] {
+		besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
+	}
+	for besti+bestsize < ahi && bestj+bestsize < bhi &&
+		!m.isBJunk(m.b[bestj+bestsize]) &&
+		m.a[besti+bestsize] == m.b[bestj+bestsize] {
+		bestsize += 1
+	}
+
+	// Now that we have a wholly interesting match (albeit possibly
+	// empty!), we may as well suck up the matching junk on each
+	// side of it too.  Can't think of a good reason not to, and it
+	// saves post-processing the (possibly considerable) expense of
+	// figuring out what to do with it.  In the case of an empty
+	// interesting match, this is clearly the right thing to do,
+	// because no other kind of match is possible in the regions.
+	for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) &&
+		m.a[besti-1] == m.b[bestj-1] {
+		besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
+	}
+	for besti+bestsize < ahi && bestj+bestsize < bhi &&
+		m.isBJunk(m.b[bestj+bestsize]) &&
+		m.a[besti+bestsize] == m.b[bestj+bestsize] {
+		bestsize += 1
+	}
+
+	return Match{A: besti, B: bestj, Size: bestsize}
+}
+
+// Return list of triples describing matching subsequences.
+//
+// Each triple is of the form (i, j, n), and means that
+// a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in
+// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are
+// adjacent triples in the list, and the second is not the last triple in the
+// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe
+// adjacent equal blocks.
+//
+// The last triple is a dummy, (len(a), len(b), 0), and is the only
+// triple with n==0.
+func (m *SequenceMatcher) GetMatchingBlocks() []Match {
+	if m.matchingBlocks != nil {
+		return m.matchingBlocks
+	}
+
+	var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match
+	matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match {
+		match := m.findLongestMatch(alo, ahi, blo, bhi)
+		i, j, k := match.A, match.B, match.Size
+		if match.Size > 0 {
+			if alo < i && blo < j {
+				matched = matchBlocks(alo, i, blo, j, matched)
+			}
+			matched = append(matched, match)
+			if i+k < ahi && j+k < bhi {
+				matched = matchBlocks(i+k, ahi, j+k, bhi, matched)
+			}
+		}
+		return matched
+	}
+	matched := matchBlocks(0, len(m.a), 0, len(m.b), nil)
+
+	// It's possible that we have adjacent equal blocks in the
+	// matching_blocks list now.
+	nonAdjacent := []Match{}
+	i1, j1, k1 := 0, 0, 0
+	for _, b := range matched {
+		// Is this block adjacent to i1, j1, k1?
+		i2, j2, k2 := b.A, b.B, b.Size
+		if i1+k1 == i2 && j1+k1 == j2 {
+			// Yes, so collapse them -- this just increases the length of
+			// the first block by the length of the second, and the first
+			// block so lengthened remains the block to compare against.
+			k1 += k2
+		} else {
+			// Not adjacent.  Remember the first block (k1==0 means it's
+			// the dummy we started with), and make the second block the
+			// new block to compare against.
+			if k1 > 0 {
+				nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
+			}
+			i1, j1, k1 = i2, j2, k2
+		}
+	}
+	if k1 > 0 {
+		nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
+	}
+
+	nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0})
+	m.matchingBlocks = nonAdjacent
+	return m.matchingBlocks
+}
+
+// Return list of 5-tuples describing how to turn a into b.
+//
+// Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple
+// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the
+// tuple preceding it, and likewise for j1 == the previous j2.
+//
+// The tags are characters, with these meanings:
+//
+// 'r' (replace):  a[i1:i2] should be replaced by b[j1:j2]
+//
+// 'd' (delete):   a[i1:i2] should be deleted, j1==j2 in this case.
+//
+// 'i' (insert):   b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case.
+//
+// 'e' (equal):    a[i1:i2] == b[j1:j2]
+func (m *SequenceMatcher) GetOpCodes() []OpCode {
+	if m.opCodes != nil {
+		return m.opCodes
+	}
+	i, j := 0, 0
+	matching := m.GetMatchingBlocks()
+	opCodes := make([]OpCode, 0, len(matching))
+	for _, m := range matching {
+		//  invariant:  we've pumped out correct diffs to change
+		//  a[:i] into b[:j], and the next matching block is
+		//  a[ai:ai+size] == b[bj:bj+size]. So we need to pump
+		//  out a diff to change a[i:ai] into b[j:bj], pump out
+		//  the matching block, and move (i,j) beyond the match
+		ai, bj, size := m.A, m.B, m.Size
+		tag := byte(0)
+		if i < ai && j < bj {
+			tag = 'r'
+		} else if i < ai {
+			tag = 'd'
+		} else if j < bj {
+			tag = 'i'
+		}
+		if tag > 0 {
+			opCodes = append(opCodes, OpCode{tag, i, ai, j, bj})
+		}
+		i, j = ai+size, bj+size
+		// the list of matching blocks is terminated by a
+		// sentinel with size 0
+		if size > 0 {
+			opCodes = append(opCodes, OpCode{'e', ai, i, bj, j})
+		}
+	}
+	m.opCodes = opCodes
+	return m.opCodes
+}
+
+// Isolate change clusters by eliminating ranges with no changes.
+//
+// Return a generator of groups with up to n lines of context.
+// Each group is in the same format as returned by GetOpCodes().
+func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
+	if n < 0 {
+		n = 3
+	}
+	codes := m.GetOpCodes()
+	if len(codes) == 0 {
+		codes = []OpCode{OpCode{'e', 0, 1, 0, 1}}
+	}
+	// Fixup leading and trailing groups if they show no changes.
+	if codes[0].Tag == 'e' {
+		c := codes[0]
+		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+		codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2}
+	}
+	if codes[len(codes)-1].Tag == 'e' {
+		c := codes[len(codes)-1]
+		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+		codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)}
+	}
+	nn := n + n
+	groups := [][]OpCode{}
+	group := []OpCode{}
+	for _, c := range codes {
+		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+		// End the current group and start a new one whenever
+		// there is a large range with no changes.
+		if c.Tag == 'e' && i2-i1 > nn {
+			group = append(group, OpCode{c.Tag, i1, min(i2, i1+n),
+				j1, min(j2, j1+n)})
+			groups = append(groups, group)
+			group = []OpCode{}
+			i1, j1 = max(i1, i2-n), max(j1, j2-n)
+		}
+		group = append(group, OpCode{c.Tag, i1, i2, j1, j2})
+	}
+	if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') {
+		groups = append(groups, group)
+	}
+	return groups
+}
+
+// Return a measure of the sequences' similarity (float in [0,1]).
+//
+// Where T is the total number of elements in both sequences, and
+// M is the number of matches, this is 2.0*M / T.
+// Note that this is 1 if the sequences are identical, and 0 if
+// they have nothing in common.
+//
+// .Ratio() is expensive to compute if you haven't already computed
+// .GetMatchingBlocks() or .GetOpCodes(), in which case you may
+// want to try .QuickRatio() or .RealQuickRation() first to get an
+// upper bound.
+func (m *SequenceMatcher) Ratio() float64 {
+	matches := 0
+	for _, m := range m.GetMatchingBlocks() {
+		matches += m.Size
+	}
+	return calculateRatio(matches, len(m.a)+len(m.b))
+}
+
+// Return an upper bound on ratio() relatively quickly.
+//
+// This isn't defined beyond that it is an upper bound on .Ratio(), and
+// is faster to compute.
+func (m *SequenceMatcher) QuickRatio() float64 {
+	// viewing a and b as multisets, set matches to the cardinality
+	// of their intersection; this counts the number of matches
+	// without regard to order, so is clearly an upper bound
+	if m.fullBCount == nil {
+		m.fullBCount = map[string]int{}
+		for _, s := range m.b {
+			m.fullBCount[s] = m.fullBCount[s] + 1
+		}
+	}
+
+	// avail[x] is the number of times x appears in 'b' less the
+	// number of times we've seen it in 'a' so far ... kinda
+	avail := map[string]int{}
+	matches := 0
+	for _, s := range m.a {
+		n, ok := avail[s]
+		if !ok {
+			n = m.fullBCount[s]
+		}
+		avail[s] = n - 1
+		if n > 0 {
+			matches += 1
+		}
+	}
+	return calculateRatio(matches, len(m.a)+len(m.b))
+}
+
+// Return an upper bound on ratio() very quickly.
+//
+// This isn't defined beyond that it is an upper bound on .Ratio(), and
+// is faster to compute than either .Ratio() or .QuickRatio().
+func (m *SequenceMatcher) RealQuickRatio() float64 {
+	la, lb := len(m.a), len(m.b)
+	return calculateRatio(min(la, lb), la+lb)
+}
+
+// Convert range to the "ed" format
+func formatRangeUnified(start, stop int) string {
+	// Per the diff spec at http://www.unix.org/single_unix_specification/
+	beginning := start + 1 // lines start numbering with one
+	length := stop - start
+	if length == 1 {
+		return fmt.Sprintf("%d", beginning)
+	}
+	if length == 0 {
+		beginning -= 1 // empty ranges begin at line just before the range
+	}
+	return fmt.Sprintf("%d,%d", beginning, length)
+}
+
+// Unified diff parameters
+type UnifiedDiff struct {
+	A        []string // First sequence lines
+	FromFile string   // First file name
+	FromDate string   // First file time
+	B        []string // Second sequence lines
+	ToFile   string   // Second file name
+	ToDate   string   // Second file time
+	Eol      string   // Headers end of line, defaults to LF
+	Context  int      // Number of context lines
+}
+
+// Compare two sequences of lines; generate the delta as a unified diff.
+//
+// Unified diffs are a compact way of showing line changes and a few
+// lines of context.  The number of context lines is set by 'n' which
+// defaults to three.
+//
+// By default, the diff control lines (those with ---, +++, or @@) are
+// created with a trailing newline.  This is helpful so that inputs
+// created from file.readlines() result in diffs that are suitable for
+// file.writelines() since both the inputs and outputs have trailing
+// newlines.
+//
+// For inputs that do not have trailing newlines, set the lineterm
+// argument to "" so that the output will be uniformly newline free.
+//
+// The unidiff format normally has a header for filenames and modification
+// times.  Any or all of these may be specified using strings for
+// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
+// The modification times are normally expressed in the ISO 8601 format.
+func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error {
+	buf := bufio.NewWriter(writer)
+	defer buf.Flush()
+	wf := func(format string, args ...interface{}) error {
+		_, err := buf.WriteString(fmt.Sprintf(format, args...))
+		return err
+	}
+	ws := func(s string) error {
+		_, err := buf.WriteString(s)
+		return err
+	}
+
+	if len(diff.Eol) == 0 {
+		diff.Eol = "\n"
+	}
+
+	started := false
+	m := NewMatcher(diff.A, diff.B)
+	for _, g := range m.GetGroupedOpCodes(diff.Context) {
+		if !started {
+			started = true
+			fromDate := ""
+			if len(diff.FromDate) > 0 {
+				fromDate = "\t" + diff.FromDate
+			}
+			toDate := ""
+			if len(diff.ToDate) > 0 {
+				toDate = "\t" + diff.ToDate
+			}
+			if diff.FromFile != "" || diff.ToFile != "" {
+				err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol)
+				if err != nil {
+					return err
+				}
+				err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol)
+				if err != nil {
+					return err
+				}
+			}
+		}
+		first, last := g[0], g[len(g)-1]
+		range1 := formatRangeUnified(first.I1, last.I2)
+		range2 := formatRangeUnified(first.J1, last.J2)
+		if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil {
+			return err
+		}
+		for _, c := range g {
+			i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+			if c.Tag == 'e' {
+				for _, line := range diff.A[i1:i2] {
+					if err := ws(" " + line); err != nil {
+						return err
+					}
+				}
+				continue
+			}
+			if c.Tag == 'r' || c.Tag == 'd' {
+				for _, line := range diff.A[i1:i2] {
+					if err := ws("-" + line); err != nil {
+						return err
+					}
+				}
+			}
+			if c.Tag == 'r' || c.Tag == 'i' {
+				for _, line := range diff.B[j1:j2] {
+					if err := ws("+" + line); err != nil {
+						return err
+					}
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// Like WriteUnifiedDiff but returns the diff a string.
+func GetUnifiedDiffString(diff UnifiedDiff) (string, error) {
+	w := &bytes.Buffer{}
+	err := WriteUnifiedDiff(w, diff)
+	return string(w.Bytes()), err
+}
+
+// Convert range to the "ed" format.
+func formatRangeContext(start, stop int) string {
+	// Per the diff spec at http://www.unix.org/single_unix_specification/
+	beginning := start + 1 // lines start numbering with one
+	length := stop - start
+	if length == 0 {
+		beginning -= 1 // empty ranges begin at line just before the range
+	}
+	if length <= 1 {
+		return fmt.Sprintf("%d", beginning)
+	}
+	return fmt.Sprintf("%d,%d", beginning, beginning+length-1)
+}
+
+type ContextDiff UnifiedDiff
+
+// Compare two sequences of lines; generate the delta as a context diff.
+//
+// Context diffs are a compact way of showing line changes and a few
+// lines of context. The number of context lines is set by diff.Context
+// which defaults to three.
+//
+// By default, the diff control lines (those with *** or ---) are
+// created with a trailing newline.
+//
+// For inputs that do not have trailing newlines, set the diff.Eol
+// argument to "" so that the output will be uniformly newline free.
+//
+// The context diff format normally has a header for filenames and
+// modification times.  Any or all of these may be specified using
+// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate.
+// The modification times are normally expressed in the ISO 8601 format.
+// If not specified, the strings default to blanks.
+func WriteContextDiff(writer io.Writer, diff ContextDiff) error {
+	buf := bufio.NewWriter(writer)
+	defer buf.Flush()
+	var diffErr error
+	wf := func(format string, args ...interface{}) {
+		_, err := buf.WriteString(fmt.Sprintf(format, args...))
+		if diffErr == nil && err != nil {
+			diffErr = err
+		}
+	}
+	ws := func(s string) {
+		_, err := buf.WriteString(s)
+		if diffErr == nil && err != nil {
+			diffErr = err
+		}
+	}
+
+	if len(diff.Eol) == 0 {
+		diff.Eol = "\n"
+	}
+
+	prefix := map[byte]string{
+		'i': "+ ",
+		'd': "- ",
+		'r': "! ",
+		'e': "  ",
+	}
+
+	started := false
+	m := NewMatcher(diff.A, diff.B)
+	for _, g := range m.GetGroupedOpCodes(diff.Context) {
+		if !started {
+			started = true
+			fromDate := ""
+			if len(diff.FromDate) > 0 {
+				fromDate = "\t" + diff.FromDate
+			}
+			toDate := ""
+			if len(diff.ToDate) > 0 {
+				toDate = "\t" + diff.ToDate
+			}
+			if diff.FromFile != "" || diff.ToFile != "" {
+				wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol)
+				wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol)
+			}
+		}
+
+		first, last := g[0], g[len(g)-1]
+		ws("***************" + diff.Eol)
+
+		range1 := formatRangeContext(first.I1, last.I2)
+		wf("*** %s ****%s", range1, diff.Eol)
+		for _, c := range g {
+			if c.Tag == 'r' || c.Tag == 'd' {
+				for _, cc := range g {
+					if cc.Tag == 'i' {
+						continue
+					}
+					for _, line := range diff.A[cc.I1:cc.I2] {
+						ws(prefix[cc.Tag] + line)
+					}
+				}
+				break
+			}
+		}
+
+		range2 := formatRangeContext(first.J1, last.J2)
+		wf("--- %s ----%s", range2, diff.Eol)
+		for _, c := range g {
+			if c.Tag == 'r' || c.Tag == 'i' {
+				for _, cc := range g {
+					if cc.Tag == 'd' {
+						continue
+					}
+					for _, line := range diff.B[cc.J1:cc.J2] {
+						ws(prefix[cc.Tag] + line)
+					}
+				}
+				break
+			}
+		}
+	}
+	return diffErr
+}
+
+// Like WriteContextDiff but returns the diff a string.
+func GetContextDiffString(diff ContextDiff) (string, error) {
+	w := &bytes.Buffer{}
+	err := WriteContextDiff(w, diff)
+	return string(w.Bytes()), err
+}
+
+// Split a string on "\n" while preserving them. The output can be used
+// as input for UnifiedDiff and ContextDiff structures.
+func SplitLines(s string) []string {
+	lines := strings.SplitAfter(s, "\n")
+	lines[len(lines)-1] += "\n"
+	return lines
+}
diff --git a/go/src/github.com/pmezard/go-difflib/difflib/difflib_test.go b/go/src/github.com/pmezard/go-difflib/difflib/difflib_test.go
new file mode 100644
index 0000000..d725119
--- /dev/null
+++ b/go/src/github.com/pmezard/go-difflib/difflib/difflib_test.go
@@ -0,0 +1,426 @@
+package difflib
+
+import (
+	"bytes"
+	"fmt"
+	"math"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+func assertAlmostEqual(t *testing.T, a, b float64, places int) {
+	if math.Abs(a-b) > math.Pow10(-places) {
+		t.Errorf("%.7f != %.7f", a, b)
+	}
+}
+
+func assertEqual(t *testing.T, a, b interface{}) {
+	if !reflect.DeepEqual(a, b) {
+		t.Errorf("%v != %v", a, b)
+	}
+}
+
+func splitChars(s string) []string {
+	chars := make([]string, 0, len(s))
+	// Assume ASCII inputs
+	for i := 0; i != len(s); i++ {
+		chars = append(chars, string(s[i]))
+	}
+	return chars
+}
+
+func TestSequenceMatcherRatio(t *testing.T) {
+	s := NewMatcher(splitChars("abcd"), splitChars("bcde"))
+	assertEqual(t, s.Ratio(), 0.75)
+	assertEqual(t, s.QuickRatio(), 0.75)
+	assertEqual(t, s.RealQuickRatio(), 1.0)
+}
+
+func TestGetOptCodes(t *testing.T) {
+	a := "qabxcd"
+	b := "abycdf"
+	s := NewMatcher(splitChars(a), splitChars(b))
+	w := &bytes.Buffer{}
+	for _, op := range s.GetOpCodes() {
+		fmt.Fprintf(w, "%s a[%d:%d], (%s) b[%d:%d] (%s)\n", string(op.Tag),
+			op.I1, op.I2, a[op.I1:op.I2], op.J1, op.J2, b[op.J1:op.J2])
+	}
+	result := string(w.Bytes())
+	expected := `d a[0:1], (q) b[0:0] ()
+e a[1:3], (ab) b[0:2] (ab)
+r a[3:4], (x) b[2:3] (y)
+e a[4:6], (cd) b[3:5] (cd)
+i a[6:6], () b[5:6] (f)
+`
+	if expected != result {
+		t.Errorf("unexpected op codes: \n%s", result)
+	}
+}
+
+func TestGroupedOpCodes(t *testing.T) {
+	a := []string{}
+	for i := 0; i != 39; i++ {
+		a = append(a, fmt.Sprintf("%02d", i))
+	}
+	b := []string{}
+	b = append(b, a[:8]...)
+	b = append(b, " i")
+	b = append(b, a[8:19]...)
+	b = append(b, " x")
+	b = append(b, a[20:22]...)
+	b = append(b, a[27:34]...)
+	b = append(b, " y")
+	b = append(b, a[35:]...)
+	s := NewMatcher(a, b)
+	w := &bytes.Buffer{}
+	for _, g := range s.GetGroupedOpCodes(-1) {
+		fmt.Fprintf(w, "group\n")
+		for _, op := range g {
+			fmt.Fprintf(w, "  %s, %d, %d, %d, %d\n", string(op.Tag),
+				op.I1, op.I2, op.J1, op.J2)
+		}
+	}
+	result := string(w.Bytes())
+	expected := `group
+  e, 5, 8, 5, 8
+  i, 8, 8, 8, 9
+  e, 8, 11, 9, 12
+group
+  e, 16, 19, 17, 20
+  r, 19, 20, 20, 21
+  e, 20, 22, 21, 23
+  d, 22, 27, 23, 23
+  e, 27, 30, 23, 26
+group
+  e, 31, 34, 27, 30
+  r, 34, 35, 30, 31
+  e, 35, 38, 31, 34
+`
+	if expected != result {
+		t.Errorf("unexpected op codes: \n%s", result)
+	}
+}
+
+func ExampleGetUnifiedDiffCode() {
+	a := `one
+two
+three
+four
+fmt.Printf("%s,%T",a,b)`
+	b := `zero
+one
+three
+four`
+	diff := UnifiedDiff{
+		A:        SplitLines(a),
+		B:        SplitLines(b),
+		FromFile: "Original",
+		FromDate: "2005-01-26 23:30:50",
+		ToFile:   "Current",
+		ToDate:   "2010-04-02 10:20:52",
+		Context:  3,
+	}
+	result, _ := GetUnifiedDiffString(diff)
+	fmt.Println(strings.Replace(result, "\t", " ", -1))
+	// Output:
+	// --- Original 2005-01-26 23:30:50
+	// +++ Current 2010-04-02 10:20:52
+	// @@ -1,5 +1,4 @@
+	// +zero
+	//  one
+	// -two
+	//  three
+	//  four
+	// -fmt.Printf("%s,%T",a,b)
+}
+
+func ExampleGetContextDiffCode() {
+	a := `one
+two
+three
+four
+fmt.Printf("%s,%T",a,b)`
+	b := `zero
+one
+tree
+four`
+	diff := ContextDiff{
+		A:        SplitLines(a),
+		B:        SplitLines(b),
+		FromFile: "Original",
+		ToFile:   "Current",
+		Context:  3,
+		Eol:      "\n",
+	}
+	result, _ := GetContextDiffString(diff)
+	fmt.Print(strings.Replace(result, "\t", " ", -1))
+	// Output:
+	// *** Original
+	// --- Current
+	// ***************
+	// *** 1,5 ****
+	//   one
+	// ! two
+	// ! three
+	//   four
+	// - fmt.Printf("%s,%T",a,b)
+	// --- 1,4 ----
+	// + zero
+	//   one
+	// ! tree
+	//   four
+}
+
+func ExampleGetContextDiffString() {
+	a := `one
+two
+three
+four`
+	b := `zero
+one
+tree
+four`
+	diff := ContextDiff{
+		A:        SplitLines(a),
+		B:        SplitLines(b),
+		FromFile: "Original",
+		ToFile:   "Current",
+		Context:  3,
+		Eol:      "\n",
+	}
+	result, _ := GetContextDiffString(diff)
+	fmt.Printf(strings.Replace(result, "\t", " ", -1))
+	// Output:
+	// *** Original
+	// --- Current
+	// ***************
+	// *** 1,4 ****
+	//   one
+	// ! two
+	// ! three
+	//   four
+	// --- 1,4 ----
+	// + zero
+	//   one
+	// ! tree
+	//   four
+}
+
+func rep(s string, count int) string {
+	return strings.Repeat(s, count)
+}
+
+func TestWithAsciiOneInsert(t *testing.T) {
+	sm := NewMatcher(splitChars(rep("b", 100)),
+		splitChars("a"+rep("b", 100)))
+	assertAlmostEqual(t, sm.Ratio(), 0.995, 3)
+	assertEqual(t, sm.GetOpCodes(),
+		[]OpCode{{'i', 0, 0, 0, 1}, {'e', 0, 100, 1, 101}})
+	assertEqual(t, len(sm.bPopular), 0)
+
+	sm = NewMatcher(splitChars(rep("b", 100)),
+		splitChars(rep("b", 50)+"a"+rep("b", 50)))
+	assertAlmostEqual(t, sm.Ratio(), 0.995, 3)
+	assertEqual(t, sm.GetOpCodes(),
+		[]OpCode{{'e', 0, 50, 0, 50}, {'i', 50, 50, 50, 51}, {'e', 50, 100, 51, 101}})
+	assertEqual(t, len(sm.bPopular), 0)
+}
+
+func TestWithAsciiOnDelete(t *testing.T) {
+	sm := NewMatcher(splitChars(rep("a", 40)+"c"+rep("b", 40)),
+		splitChars(rep("a", 40)+rep("b", 40)))
+	assertAlmostEqual(t, sm.Ratio(), 0.994, 3)
+	assertEqual(t, sm.GetOpCodes(),
+		[]OpCode{{'e', 0, 40, 0, 40}, {'d', 40, 41, 40, 40}, {'e', 41, 81, 40, 80}})
+}
+
+func TestWithAsciiBJunk(t *testing.T) {
+	isJunk := func(s string) bool {
+		return s == " "
+	}
+	sm := NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
+		splitChars(rep("a", 44)+rep("b", 40)), true, isJunk)
+	assertEqual(t, sm.bJunk, map[string]struct{}{})
+
+	sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
+		splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk)
+	assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}})
+
+	isJunk = func(s string) bool {
+		return s == " " || s == "b"
+	}
+	sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
+		splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk)
+	assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}, "b": struct{}{}})
+}
+
+func TestSFBugsRatioForNullSeqn(t *testing.T) {
+	sm := NewMatcher(nil, nil)
+	assertEqual(t, sm.Ratio(), 1.0)
+	assertEqual(t, sm.QuickRatio(), 1.0)
+	assertEqual(t, sm.RealQuickRatio(), 1.0)
+}
+
+func TestSFBugsComparingEmptyLists(t *testing.T) {
+	groups := NewMatcher(nil, nil).GetGroupedOpCodes(-1)
+	assertEqual(t, len(groups), 0)
+	diff := UnifiedDiff{
+		FromFile: "Original",
+		ToFile:   "Current",
+		Context:  3,
+	}
+	result, err := GetUnifiedDiffString(diff)
+	assertEqual(t, err, nil)
+	assertEqual(t, result, "")
+}
+
+func TestOutputFormatRangeFormatUnified(t *testing.T) {
+	// Per the diff spec at http://www.unix.org/single_unix_specification/
+	//
+	// Each <range> field shall be of the form:
+	//   %1d", <beginning line number>  if the range contains exactly one line,
+	// and:
+	//  "%1d,%1d", <beginning line number>, <number of lines> otherwise.
+	// If a range is empty, its beginning line number shall be the number of
+	// the line just before the range, or 0 if the empty range starts the file.
+	fm := formatRangeUnified
+	assertEqual(t, fm(3, 3), "3,0")
+	assertEqual(t, fm(3, 4), "4")
+	assertEqual(t, fm(3, 5), "4,2")
+	assertEqual(t, fm(3, 6), "4,3")
+	assertEqual(t, fm(0, 0), "0,0")
+}
+
+func TestOutputFormatRangeFormatContext(t *testing.T) {
+	// Per the diff spec at http://www.unix.org/single_unix_specification/
+	//
+	// The range of lines in file1 shall be written in the following format
+	// if the range contains two or more lines:
+	//     "*** %d,%d ****\n", <beginning line number>, <ending line number>
+	// and the following format otherwise:
+	//     "*** %d ****\n", <ending line number>
+	// The ending line number of an empty range shall be the number of the preceding line,
+	// or 0 if the range is at the start of the file.
+	//
+	// Next, the range of lines in file2 shall be written in the following format
+	// if the range contains two or more lines:
+	//     "--- %d,%d ----\n", <beginning line number>, <ending line number>
+	// and the following format otherwise:
+	//     "--- %d ----\n", <ending line number>
+	fm := formatRangeContext
+	assertEqual(t, fm(3, 3), "3")
+	assertEqual(t, fm(3, 4), "4")
+	assertEqual(t, fm(3, 5), "4,5")
+	assertEqual(t, fm(3, 6), "4,6")
+	assertEqual(t, fm(0, 0), "0")
+}
+
+func TestOutputFormatTabDelimiter(t *testing.T) {
+	diff := UnifiedDiff{
+		A:        splitChars("one"),
+		B:        splitChars("two"),
+		FromFile: "Original",
+		FromDate: "2005-01-26 23:30:50",
+		ToFile:   "Current",
+		ToDate:   "2010-04-12 10:20:52",
+		Eol:      "\n",
+	}
+	ud, err := GetUnifiedDiffString(diff)
+	assertEqual(t, err, nil)
+	assertEqual(t, SplitLines(ud)[:2], []string{
+		"--- Original\t2005-01-26 23:30:50\n",
+		"+++ Current\t2010-04-12 10:20:52\n",
+	})
+	cd, err := GetContextDiffString(ContextDiff(diff))
+	assertEqual(t, err, nil)
+	assertEqual(t, SplitLines(cd)[:2], []string{
+		"*** Original\t2005-01-26 23:30:50\n",
+		"--- Current\t2010-04-12 10:20:52\n",
+	})
+}
+
+func TestOutputFormatNoTrailingTabOnEmptyFiledate(t *testing.T) {
+	diff := UnifiedDiff{
+		A:        splitChars("one"),
+		B:        splitChars("two"),
+		FromFile: "Original",
+		ToFile:   "Current",
+		Eol:      "\n",
+	}
+	ud, err := GetUnifiedDiffString(diff)
+	assertEqual(t, err, nil)
+	assertEqual(t, SplitLines(ud)[:2], []string{"--- Original\n", "+++ Current\n"})
+
+	cd, err := GetContextDiffString(ContextDiff(diff))
+	assertEqual(t, err, nil)
+	assertEqual(t, SplitLines(cd)[:2], []string{"*** Original\n", "--- Current\n"})
+}
+
+func TestOmitFilenames(t *testing.T) {
+	diff := UnifiedDiff{
+		A:   SplitLines("o\nn\ne\n"),
+		B:   SplitLines("t\nw\no\n"),
+		Eol: "\n",
+	}
+	ud, err := GetUnifiedDiffString(diff)
+	assertEqual(t, err, nil)
+	assertEqual(t, SplitLines(ud), []string{
+		"@@ -0,0 +1,2 @@\n",
+		"+t\n",
+		"+w\n",
+		"@@ -2,2 +3,0 @@\n",
+		"-n\n",
+		"-e\n",
+		"\n",
+	})
+
+	cd, err := GetContextDiffString(ContextDiff(diff))
+	assertEqual(t, err, nil)
+	assertEqual(t, SplitLines(cd), []string{
+		"***************\n",
+		"*** 0 ****\n",
+		"--- 1,2 ----\n",
+		"+ t\n",
+		"+ w\n",
+		"***************\n",
+		"*** 2,3 ****\n",
+		"- n\n",
+		"- e\n",
+		"--- 3 ----\n",
+		"\n",
+	})
+}
+
+func TestSplitLines(t *testing.T) {
+	allTests := []struct {
+		input string
+		want  []string
+	}{
+		{"foo", []string{"foo\n"}},
+		{"foo\nbar", []string{"foo\n", "bar\n"}},
+		{"foo\nbar\n", []string{"foo\n", "bar\n", "\n"}},
+	}
+	for _, test := range allTests {
+		assertEqual(t, SplitLines(test.input), test.want)
+	}
+}
+
+func benchmarkSplitLines(b *testing.B, count int) {
+	str := strings.Repeat("foo\n", count)
+
+	b.ResetTimer()
+
+	n := 0
+	for i := 0; i < b.N; i++ {
+		n += len(SplitLines(str))
+	}
+}
+
+func BenchmarkSplitLines100(b *testing.B) {
+	benchmarkSplitLines(b, 100)
+}
+
+func BenchmarkSplitLines10000(b *testing.B) {
+	benchmarkSplitLines(b, 10000)
+}
diff --git a/go/src/github.com/shirou/gopsutil/.gitignore b/go/src/github.com/shirou/gopsutil/.gitignore
new file mode 100644
index 0000000..d2b87e8
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/.gitignore
@@ -0,0 +1,5 @@
+*~
+#*
+_obj
+*.tmp
+.idea
diff --git a/go/src/github.com/shirou/gopsutil/LICENSE b/go/src/github.com/shirou/gopsutil/LICENSE
new file mode 100644
index 0000000..602b2c0
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/LICENSE
@@ -0,0 +1,27 @@
+gopsutil is distributed under BSD license reproduced below.
+
+Copyright (c) 2014, WAKAYAMA Shirou
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+ * Neither the name of the gopsutil authors nor the names of its contributors
+   may be used to endorse or promote products derived from this software without
+   specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/go/src/github.com/shirou/gopsutil/Makefile b/go/src/github.com/shirou/gopsutil/Makefile
new file mode 100644
index 0000000..b5dcc94
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/Makefile
@@ -0,0 +1,18 @@
+.PHONY: help check
+.DEFAULT_GOAL := help
+
+SUBPKGS=cpu disk docker host internal load mem net process
+
+help:  ## Show help
+	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+
+check:  ## Check
+	errcheck -ignore="Close|Run|Write" ./...
+	golint ./... | egrep -v 'underscores|HttpOnly|should have comment|comment on exported|CamelCase|VM|UID'
+
+build_test:  ## test only buildable
+	GOOS=linux go test ./... | grep -v "exec format error"
+	GOOS=freebsd go test ./... | grep -v "exec format error"
+	CGO_ENABLED=0 GOOS=darwin go test ./... | grep -v "exec format error"
+	CGO_ENABLED=1 GOOS=darwin go test ./... | grep -v "exec format error"
+	GOOS=windows go test ./...| grep -v "exec format error"
diff --git a/go/src/github.com/shirou/gopsutil/README.google b/go/src/github.com/shirou/gopsutil/README.google
new file mode 100644
index 0000000..2f09dd8
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/README.google
@@ -0,0 +1,11 @@
+URL: https://github.com/shirou/gopsutil/archive/7b991b8135166c7fc81b65665a2f35c7a1966cfc.zip
+Version: 7b991b8135166c7fc81b65665a2f35c7a1966cfc
+License: BSD
+License File: LICENSE
+
+Description:
+A golang port of psutil, a cross-platform library for retrieving information on
+running processes and system utilization (CPU, memory, disks, network).
+
+Local Modifications:
+None.
diff --git a/go/src/github.com/shirou/gopsutil/README.rst b/go/src/github.com/shirou/gopsutil/README.rst
new file mode 100644
index 0000000..9ebcfb9
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/README.rst
@@ -0,0 +1,298 @@
+gopsutil: psutil for golang
+==============================
+
+.. image:: https://circleci.com/gh/shirou/gopsutil.svg?&style=shield
+        :target: https://circleci.com/gh/shirou/gopsutil
+
+.. image:: https://coveralls.io/repos/shirou/gopsutil/badge.svg?branch=master
+        :target: https://coveralls.io/r/shirou/gopsutil?branch=master
+
+.. image:: https://godoc.org/github.com/shirou/gopsutil?status.svg
+        :target: http://godoc.org/github.com/shirou/gopsutil
+
+This is a port of psutil (http://pythonhosted.org/psutil/). The challenge is porting all
+psutil functions on some architectures.
+
+
+.. highlights:: Breaking Changes!
+
+   Breaking changes is introduced at v2. See `issue 174 <https://github.com/shirou/gopsutil/issues/174>`_ .
+
+
+Migrating to v2
+-------------------------
+
+On gopsutil itself, `v2migration.sh <https://github.com/shirou/gopsutil/blob/v2/v2migration.sh>`_ is used for migration. It can not be commly used, but it may help to your migration.
+
+
+Available Architectures
+------------------------------------
+
+- FreeBSD i386/amd64
+- Linux i386/amd64/arm(raspberry pi)
+- Windows/amd64
+- Darwin/amd64
+
+All works are implemented without cgo by porting c struct to golang struct.
+
+
+Usage
+---------
+
+Note: gopsutil v2 breaks compatibility. If you want to stay with compatibility, please use v1 branch and vendoring.
+
+.. code:: go
+
+   package main
+
+   import (
+       "fmt"
+
+       "github.com/shirou/gopsutil/mem"
+   )
+
+   func main() {
+       v, _ := mem.VirtualMemory()
+
+       // almost every return value is a struct
+       fmt.Printf("Total: %v, Free:%v, UsedPercent:%f%%\n", v.Total, v.Free, v.UsedPercent)
+
+       // convert to JSON. String() is also implemented
+       fmt.Println(v)
+   }
+
+The output is below.
+
+::
+
+  Total: 3179569152, Free:284233728, UsedPercent:84.508194%
+  {"total":3179569152,"available":492572672,"used":2895335424,"usedPercent":84.50819439828305, (snip...)}
+
+You can set an alternative location to /proc by setting the HOST_PROC environment variable.
+You can set an alternative location to /sys by setting the HOST_SYS environment variable.
+You can set an alternative location to /etc by setting the HOST_ETC environment variable.
+
+Documentation
+------------------------
+
+see http://godoc.org/github.com/shirou/gopsutil
+
+Requrement
+-----------------
+
+- go1.5 or above is required.
+
+
+More Info
+--------------------
+
+Several methods have been added which are not present in psutil, but will provide useful information.
+
+- host/HostInfo()  (linux)
+
+  - Hostname
+  - Uptime
+  - Procs
+  - OS                    (ex: "linux")
+  - Platform              (ex: "ubuntu", "arch")
+  - PlatformFamily        (ex: "debian")
+  - PlatformVersion       (ex: "Ubuntu 13.10")
+  - VirtualizationSystem  (ex: "LXC")
+  - VirtualizationRole    (ex: "guest"/"host")
+
+- cpu/CPUInfo()  (linux, freebsd)
+
+  - CPU          (ex: 0, 1, ...)
+  - VendorID     (ex: "GenuineIntel")
+  - Family
+  - Model
+  - Stepping
+  - PhysicalID
+  - CoreID
+  - Cores        (ex: 2)
+  - ModelName    (ex: "Intel(R) Core(TM) i7-2640M CPU @ 2.80GHz")
+  - Mhz
+  - CacheSize
+  - Flags        (ex: "fpu vme de pse tsc msr pae mce cx8 ...")
+
+- load/LoadAvg()  (linux, freebsd)
+
+  - Load1
+  - Load5
+  - Load15
+
+- docker/GetDockerIDList() (linux only)
+
+  - container id list ([]string)
+
+- docker/CgroupCPU() (linux only)
+
+  - user
+  - system
+
+- docker/CgroupMem() (linux only)
+
+  - various status
+
+- net_protocols (linux only)
+
+  - system wide stats on network protocols (i.e IP, TCP, UDP, etc.)
+  - sourced from /proc/net/snmp
+
+- iptables nf_conntrack (linux only)
+
+  - system wide stats on netfilter conntrack module
+  - sourced from /proc/sys/net/netfilter/nf_conntrack_count
+
+Some codes are ported from Ohai. many thanks.
+
+
+Current Status
+------------------
+
+- x: work
+- b: almost work but something broken
+
+================= ====== ======= ====== =======
+name              Linux  FreeBSD MacOSX Windows
+cpu_times            x      x      x       x
+cpu_count            x      x      x       x
+cpu_percent          x      x      x       x
+cpu_times_percent    x      x      x       x
+virtual_memory       x      x      x       x
+swap_memory          x      x      x
+disk_partitions      x      x      x       x
+disk_io_counters     x      x
+disk_usage           x      x      x       x
+net_io_counters      x      x      b       x
+boot_time            x      x      x       x
+users                x      x      x       x
+pids                 x      x      x       x
+pid_exists           x      x      x       x
+net_connections      x             x
+net_protocols        x
+net_if_addrs
+net_if_stats
+netfilter_conntrack  x
+================= ====== ======= ====== =======
+
+Process class
+^^^^^^^^^^^^^^^
+
+================ ===== ======= ====== =======
+name             Linux FreeBSD MacOSX Windows
+pid                 x     x      x       x
+ppid                x     x      x       x
+name                x     x      x       x
+cmdline             x            x       x
+create_time         x
+status              x     x      x
+cwd                 x
+exe                 x     x              x
+uids                x     x      x
+gids                x     x      x
+terminal            x     x      x
+io_counters         x     x
+nice                x     x      x       x
+num_fds             x
+num_ctx_switches    x
+num_threads         x     x      x       x
+cpu_times           x
+memory_info         x     x      x
+memory_info_ex      x
+memory_maps         x
+open_files          x
+send_signal         x     x      x
+suspend             x     x      x
+resume              x     x      x
+terminate           x     x      x
+kill                x     x      x
+username            x
+ionice
+rlimit
+num_handlres
+threads
+cpu_percent         x            x
+cpu_affinity
+memory_percent
+parent              x            x
+children            x     x      x
+connections         x            x
+is_running
+================ ===== ======= ====== =======
+
+Original Metrics
+^^^^^^^^^^^^^^^^^^^
+================== ===== ======= ====== =======
+item               Linux FreeBSD MacOSX Windows
+**HostInfo**
+hostname              x     x      x       x
+  uptime              x     x      x
+  proces              x     x
+  os                  x     x      x       x
+  platform            x     x      x
+  platformfamiliy     x     x      x
+  virtualization      x
+**CPU**
+  VendorID            x     x      x       x
+  Family              x     x      x       x
+  Model               x     x      x       x
+  Stepping            x     x      x       x
+  PhysicalID          x
+  CoreID              x
+  Cores               x                    x
+  ModelName           x     x      x       x
+**LoadAvg**
+  Load1               x     x      x
+  Load5               x     x      x
+  Load15              x     x      x
+**GetDockerID**
+  container id        x     no    no      no
+**CgroupsCPU**
+  user                x     no    no      no
+  system              x     no    no      no
+**CgroupsMem**
+  various             x     no    no      no
+================== ===== ======= ====== =======
+
+- future work
+
+  - process_iter
+  - wait_procs
+  - Process class
+
+    - as_dict
+    - wait
+
+
+License
+------------
+
+New BSD License (same as psutil)
+
+
+Related Works
+-----------------------
+
+I have been influenced by the following great works:
+
+- psutil: http://pythonhosted.org/psutil/
+- dstat: https://github.com/dagwieers/dstat
+- gosigar: https://github.com/cloudfoundry/gosigar/
+- goprocinfo: https://github.com/c9s/goprocinfo
+- go-ps: https://github.com/mitchellh/go-ps
+- ohai: https://github.com/opscode/ohai/
+- bosun: https://github.com/bosun-monitor/bosun/tree/master/cmd/scollector/collectors
+- mackerel: https://github.com/mackerelio/mackerel-agent/tree/master/metrics
+
+How to Contribute
+---------------------------
+
+1. Fork it
+2. Create your feature branch (git checkout -b my-new-feature)
+3. Commit your changes (git commit -am 'Add some feature')
+4. Push to the branch (git push origin my-new-feature)
+5. Create new Pull Request
+
+My English is terrible, so documentation or correcting comments are also
+welcome.
diff --git a/go/src/github.com/shirou/gopsutil/circle.yml b/go/src/github.com/shirou/gopsutil/circle.yml
new file mode 100644
index 0000000..ad8c43d
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/circle.yml
@@ -0,0 +1,11 @@
+machine:
+  timezone:
+    Asia/Tokyo
+test:
+  override:
+    - GOOS=linux GOARCH=amd64 go test -v ./...
+    - GOOS=linux GOARCH=386 go get -v ./...
+    - GOOS=linux GOARCH=arm GOARM=7 go get -v ./...
+    - GOOS=freebsd GOARCH=amd64 go get -v ./...
+    - GOOS=windows GOARCH=amd64 go get -v ./...
+    - GOOS=darwin GOARCH=amd64 go get -v ./...
diff --git a/go/src/github.com/shirou/gopsutil/coverall.sh b/go/src/github.com/shirou/gopsutil/coverall.sh
new file mode 100644
index 0000000..35aa298
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/coverall.sh
@@ -0,0 +1,26 @@
+#/bin/sh
+
+# see http://www.songmu.jp/riji/entry/2015-01-15-goveralls-multi-package.html
+
+set -e
+# cleanup
+cleanup() {
+  if [ $tmpprof != "" ] && [ -f $tmpprof ]; then
+    rm -f $tmpprof
+  fi
+  exit
+}
+trap cleanup INT QUIT TERM EXIT
+
+# メインの処理
+prof=${1:-".profile.cov"}
+echo "mode: count" > $prof
+gopath1=$(echo $GOPATH | cut -d: -f1)
+for pkg in $(go list ./...); do
+  tmpprof=$gopath1/src/$pkg/profile.tmp
+  go test -covermode=count -coverprofile=$tmpprof $pkg
+  if [ -f $tmpprof ]; then
+    cat $tmpprof | tail -n +2 >> $prof
+    rm $tmpprof
+  fi
+done
diff --git a/go/src/github.com/shirou/gopsutil/cpu/cpu.go b/go/src/github.com/shirou/gopsutil/cpu/cpu.go
new file mode 100644
index 0000000..7153509
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/cpu/cpu.go
@@ -0,0 +1,76 @@
+package cpu
+
+import (
+	"encoding/json"
+	"runtime"
+	"strconv"
+	"strings"
+)
+
+type TimesStat struct {
+	CPU       string  `json:"cpu"`
+	User      float64 `json:"user"`
+	System    float64 `json:"system"`
+	Idle      float64 `json:"idle"`
+	Nice      float64 `json:"nice"`
+	Iowait    float64 `json:"iowait"`
+	Irq       float64 `json:"irq"`
+	Softirq   float64 `json:"softirq"`
+	Steal     float64 `json:"steal"`
+	Guest     float64 `json:"guest"`
+	GuestNice float64 `json:"guestNice"`
+	Stolen    float64 `json:"stolen"`
+}
+
+type InfoStat struct {
+	CPU        int32    `json:"cpu"`
+	VendorID   string   `json:"vendorId"`
+	Family     string   `json:"family"`
+	Model      string   `json:"model"`
+	Stepping   int32    `json:"stepping"`
+	PhysicalID string   `json:"physicalId"`
+	CoreID     string   `json:"coreId"`
+	Cores      int32    `json:"cores"`
+	ModelName  string   `json:"modelName"`
+	Mhz        float64  `json:"mhz"`
+	CacheSize  int32    `json:"cacheSize"`
+	Flags      []string `json:"flags"`
+}
+
+var lastCPUTimes []TimesStat
+var lastPerCPUTimes []TimesStat
+
+func Counts(logical bool) (int, error) {
+	return runtime.NumCPU(), nil
+}
+
+func (c TimesStat) String() string {
+	v := []string{
+		`"cpu":"` + c.CPU + `"`,
+		`"user":` + strconv.FormatFloat(c.User, 'f', 1, 64),
+		`"system":` + strconv.FormatFloat(c.System, 'f', 1, 64),
+		`"idle":` + strconv.FormatFloat(c.Idle, 'f', 1, 64),
+		`"nice":` + strconv.FormatFloat(c.Nice, 'f', 1, 64),
+		`"iowait":` + strconv.FormatFloat(c.Iowait, 'f', 1, 64),
+		`"irq":` + strconv.FormatFloat(c.Irq, 'f', 1, 64),
+		`"softirq":` + strconv.FormatFloat(c.Softirq, 'f', 1, 64),
+		`"steal":` + strconv.FormatFloat(c.Steal, 'f', 1, 64),
+		`"guest":` + strconv.FormatFloat(c.Guest, 'f', 1, 64),
+		`"guestNice":` + strconv.FormatFloat(c.GuestNice, 'f', 1, 64),
+		`"stolen":` + strconv.FormatFloat(c.Stolen, 'f', 1, 64),
+	}
+
+	return `{` + strings.Join(v, ",") + `}`
+}
+
+// Total returns the total number of seconds in a CPUTimesStat
+func (c TimesStat) Total() float64 {
+	total := c.User + c.System + c.Nice + c.Iowait + c.Irq + c.Softirq + c.Steal +
+		c.Guest + c.GuestNice + c.Idle + c.Stolen
+	return total
+}
+
+func (c InfoStat) String() string {
+	s, _ := json.Marshal(c)
+	return string(s)
+}
diff --git a/go/src/github.com/shirou/gopsutil/cpu/cpu_darwin.go b/go/src/github.com/shirou/gopsutil/cpu/cpu_darwin.go
new file mode 100644
index 0000000..fbb74a8
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/cpu/cpu_darwin.go
@@ -0,0 +1,106 @@
+// +build darwin
+
+package cpu
+
+import (
+	"os/exec"
+	"strconv"
+	"strings"
+)
+
+// sys/resource.h
+const (
+	CPUser    = 0
+	CPNice    = 1
+	CPSys     = 2
+	CPIntr    = 3
+	CPIdle    = 4
+	CPUStates = 5
+)
+
+// default value. from time.h
+var ClocksPerSec = float64(128)
+
+func Times(percpu bool) ([]TimesStat, error) {
+	if percpu {
+		return perCPUTimes()
+	}
+
+	return allCPUTimes()
+}
+
+// Returns only one CPUInfoStat on FreeBSD
+func Info() ([]InfoStat, error) {
+	var ret []InfoStat
+	sysctl, err := exec.LookPath("/usr/sbin/sysctl")
+	if err != nil {
+		return ret, err
+	}
+	out, err := exec.Command(sysctl, "machdep.cpu").Output()
+	if err != nil {
+		return ret, err
+	}
+
+	c := InfoStat{}
+	for _, line := range strings.Split(string(out), "\n") {
+		values := strings.Fields(line)
+		if len(values) < 1 {
+			continue
+		}
+
+		t, err := strconv.ParseInt(values[1], 10, 64)
+		// err is not checked here because some value is string.
+		if strings.HasPrefix(line, "machdep.cpu.brand_string") {
+			c.ModelName = strings.Join(values[1:], " ")
+		} else if strings.HasPrefix(line, "machdep.cpu.family") {
+			c.Family = values[1]
+		} else if strings.HasPrefix(line, "machdep.cpu.model") {
+			c.Model = values[1]
+		} else if strings.HasPrefix(line, "machdep.cpu.stepping") {
+			if err != nil {
+				return ret, err
+			}
+			c.Stepping = int32(t)
+		} else if strings.HasPrefix(line, "machdep.cpu.features") {
+			for _, v := range values[1:] {
+				c.Flags = append(c.Flags, strings.ToLower(v))
+			}
+		} else if strings.HasPrefix(line, "machdep.cpu.leaf7_features") {
+			for _, v := range values[1:] {
+				c.Flags = append(c.Flags, strings.ToLower(v))
+			}
+		} else if strings.HasPrefix(line, "machdep.cpu.extfeatures") {
+			for _, v := range values[1:] {
+				c.Flags = append(c.Flags, strings.ToLower(v))
+			}
+		} else if strings.HasPrefix(line, "machdep.cpu.core_count") {
+			if err != nil {
+				return ret, err
+			}
+			c.Cores = int32(t)
+		} else if strings.HasPrefix(line, "machdep.cpu.cache.size") {
+			if err != nil {
+				return ret, err
+			}
+			c.CacheSize = int32(t)
+		} else if strings.HasPrefix(line, "machdep.cpu.vendor") {
+			c.VendorID = values[1]
+		}
+	}
+
+	// Use the rated frequency of the CPU. This is a static value and does not
+	// account for low power or Turbo Boost modes.
+	out, err = exec.Command(sysctl, "hw.cpufrequency").Output()
+	if err != nil {
+		return ret, err
+	}
+
+	values := strings.Fields(string(out))
+	mhz, err := strconv.ParseFloat(values[1], 64)
+	if err != nil {
+		return ret, err
+	}
+	c.Mhz = mhz / 1000000.0
+
+	return append(ret, c), nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go b/go/src/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go
new file mode 100644
index 0000000..ee59fef
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go
@@ -0,0 +1,107 @@
+// +build darwin
+// +build cgo
+
+package cpu
+
+/*
+#include <stdlib.h>
+#include <sys/sysctl.h>
+#include <sys/mount.h>
+#include <mach/mach_init.h>
+#include <mach/mach_host.h>
+#include <mach/host_info.h>
+#include <libproc.h>
+#include <mach/processor_info.h>
+#include <mach/vm_map.h>
+*/
+import "C"
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"unsafe"
+)
+
+// these CPU times for darwin is borrowed from influxdb/telegraf.
+
+func perCPUTimes() ([]TimesStat, error) {
+	var (
+		count   C.mach_msg_type_number_t
+		cpuload *C.processor_cpu_load_info_data_t
+		ncpu    C.natural_t
+	)
+
+	status := C.host_processor_info(C.host_t(C.mach_host_self()),
+		C.PROCESSOR_CPU_LOAD_INFO,
+		&ncpu,
+		(*C.processor_info_array_t)(unsafe.Pointer(&cpuload)),
+		&count)
+
+	if status != C.KERN_SUCCESS {
+		return nil, fmt.Errorf("host_processor_info error=%d", status)
+	}
+
+	// jump through some cgo casting hoops and ensure we properly free
+	// the memory that cpuload points to
+	target := C.vm_map_t(C.mach_task_self_)
+	address := C.vm_address_t(uintptr(unsafe.Pointer(cpuload)))
+	defer C.vm_deallocate(target, address, C.vm_size_t(ncpu))
+
+	// the body of struct processor_cpu_load_info
+	// aka processor_cpu_load_info_data_t
+	var cpu_ticks [C.CPU_STATE_MAX]uint32
+
+	// copy the cpuload array to a []byte buffer
+	// where we can binary.Read the data
+	size := int(ncpu) * binary.Size(cpu_ticks)
+	buf := C.GoBytes(unsafe.Pointer(cpuload), C.int(size))
+
+	bbuf := bytes.NewBuffer(buf)
+
+	var ret []TimesStat
+
+	for i := 0; i < int(ncpu); i++ {
+		err := binary.Read(bbuf, binary.LittleEndian, &cpu_ticks)
+		if err != nil {
+			return nil, err
+		}
+
+		c := TimesStat{
+			CPU:    fmt.Sprintf("cpu%d", i),
+			User:   float64(cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec,
+			System: float64(cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec,
+			Nice:   float64(cpu_ticks[C.CPU_STATE_NICE]) / ClocksPerSec,
+			Idle:   float64(cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec,
+		}
+
+		ret = append(ret, c)
+	}
+
+	return ret, nil
+}
+
+func allCPUTimes() ([]TimesStat, error) {
+	var count C.mach_msg_type_number_t = C.HOST_CPU_LOAD_INFO_COUNT
+	var cpuload C.host_cpu_load_info_data_t
+
+	status := C.host_statistics(C.host_t(C.mach_host_self()),
+		C.HOST_CPU_LOAD_INFO,
+		C.host_info_t(unsafe.Pointer(&cpuload)),
+		&count)
+
+	if status != C.KERN_SUCCESS {
+		return nil, fmt.Errorf("host_statistics error=%d", status)
+	}
+
+	c := TimesStat{
+		CPU:    "cpu-total",
+		User:   float64(cpuload.cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec,
+		System: float64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec,
+		Nice:   float64(cpuload.cpu_ticks[C.CPU_STATE_NICE]) / ClocksPerSec,
+		Idle:   float64(cpuload.cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec,
+	}
+
+	return []TimesStat{c}, nil
+
+}
diff --git a/go/src/github.com/shirou/gopsutil/cpu/cpu_darwin_nocgo.go b/go/src/github.com/shirou/gopsutil/cpu/cpu_darwin_nocgo.go
new file mode 100644
index 0000000..242b4a8
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/cpu/cpu_darwin_nocgo.go
@@ -0,0 +1,14 @@
+// +build darwin
+// +build !cgo
+
+package cpu
+
+import "github.com/shirou/gopsutil/internal/common"
+
+func perCPUTimes() ([]TimesStat, error) {
+	return []TimesStat{}, common.ErrNotImplementedError
+}
+
+func allCPUTimes() ([]TimesStat, error) {
+	return []TimesStat{}, common.ErrNotImplementedError
+}
diff --git a/go/src/github.com/shirou/gopsutil/cpu/cpu_freebsd.go b/go/src/github.com/shirou/gopsutil/cpu/cpu_freebsd.go
new file mode 100644
index 0000000..ce1adf3
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/cpu/cpu_freebsd.go
@@ -0,0 +1,147 @@
+// +build freebsd
+
+package cpu
+
+import (
+	"fmt"
+	"os/exec"
+	"regexp"
+	"strconv"
+	"strings"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+// sys/resource.h
+const (
+	CPUser    = 0
+	CPNice    = 1
+	CPSys     = 2
+	CPIntr    = 3
+	CPIdle    = 4
+	CPUStates = 5
+)
+
+var ClocksPerSec = float64(128)
+
+func init() {
+	getconf, err := exec.LookPath("/usr/bin/getconf")
+	if err != nil {
+		return
+	}
+	out, err := exec.Command(getconf, "CLK_TCK").Output()
+	// ignore errors
+	if err == nil {
+		i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
+		if err == nil {
+			ClocksPerSec = float64(i)
+		}
+	}
+}
+
+func Times(percpu bool) ([]TimesStat, error) {
+	var ret []TimesStat
+
+	var sysctlCall string
+	var ncpu int
+	if percpu {
+		sysctlCall = "kern.cp_times"
+		ncpu, _ = Counts(true)
+	} else {
+		sysctlCall = "kern.cp_time"
+		ncpu = 1
+	}
+
+	cpuTimes, err := common.DoSysctrl(sysctlCall)
+	if err != nil {
+		return ret, err
+	}
+
+	for i := 0; i < ncpu; i++ {
+		offset := CPUStates * i
+		user, err := strconv.ParseFloat(cpuTimes[CPUser+offset], 64)
+		if err != nil {
+			return ret, err
+		}
+		nice, err := strconv.ParseFloat(cpuTimes[CPNice+offset], 64)
+		if err != nil {
+			return ret, err
+		}
+		sys, err := strconv.ParseFloat(cpuTimes[CPSys+offset], 64)
+		if err != nil {
+			return ret, err
+		}
+		idle, err := strconv.ParseFloat(cpuTimes[CPIdle+offset], 64)
+		if err != nil {
+			return ret, err
+		}
+		intr, err := strconv.ParseFloat(cpuTimes[CPIntr+offset], 64)
+		if err != nil {
+			return ret, err
+		}
+
+		c := TimesStat{
+			User:   float64(user / ClocksPerSec),
+			Nice:   float64(nice / ClocksPerSec),
+			System: float64(sys / ClocksPerSec),
+			Idle:   float64(idle / ClocksPerSec),
+			Irq:    float64(intr / ClocksPerSec),
+		}
+		if !percpu {
+			c.CPU = "cpu-total"
+		} else {
+			c.CPU = fmt.Sprintf("cpu%d", i)
+		}
+
+		ret = append(ret, c)
+	}
+
+	return ret, nil
+}
+
+// Returns only one CPUInfoStat on FreeBSD
+func Info() ([]InfoStat, error) {
+	filename := "/var/run/dmesg.boot"
+	lines, _ := common.ReadLines(filename)
+
+	var ret []InfoStat
+
+	c := InfoStat{}
+	for _, line := range lines {
+		if matches := regexp.MustCompile(`CPU:\s+(.+) \(([\d.]+).+\)`).FindStringSubmatch(line); matches != nil {
+			c.ModelName = matches[1]
+			t, err := strconv.ParseFloat(matches[2], 64)
+			if err != nil {
+				return ret, nil
+			}
+			c.Mhz = t
+		} else if matches := regexp.MustCompile(`Origin = "(.+)"  Id = (.+)  Family = (.+)  Model = (.+)  Stepping = (.+)`).FindStringSubmatch(line); matches != nil {
+			c.VendorID = matches[1]
+			c.Family = matches[3]
+			c.Model = matches[4]
+			t, err := strconv.ParseInt(matches[5], 10, 32)
+			if err != nil {
+				return ret, nil
+			}
+			c.Stepping = int32(t)
+		} else if matches := regexp.MustCompile(`Features=.+<(.+)>`).FindStringSubmatch(line); matches != nil {
+			for _, v := range strings.Split(matches[1], ",") {
+				c.Flags = append(c.Flags, strings.ToLower(v))
+			}
+		} else if matches := regexp.MustCompile(`Features2=[a-f\dx]+<(.+)>`).FindStringSubmatch(line); matches != nil {
+			for _, v := range strings.Split(matches[1], ",") {
+				c.Flags = append(c.Flags, strings.ToLower(v))
+			}
+		} else if matches := regexp.MustCompile(`Logical CPUs per core: (\d+)`).FindStringSubmatch(line); matches != nil {
+			// FIXME: no this line?
+			t, err := strconv.ParseInt(matches[1], 10, 32)
+			if err != nil {
+				return ret, nil
+			}
+			c.Cores = int32(t)
+		}
+
+	}
+
+	return append(ret, c), nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/cpu/cpu_linux.go b/go/src/github.com/shirou/gopsutil/cpu/cpu_linux.go
new file mode 100644
index 0000000..975b75c
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/cpu/cpu_linux.go
@@ -0,0 +1,244 @@
+// +build linux
+
+package cpu
+
+import (
+	"errors"
+	"fmt"
+	"os/exec"
+	"strconv"
+	"strings"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+var cpu_tick = float64(100)
+
+func init() {
+	getconf, err := exec.LookPath("/usr/bin/getconf")
+	if err != nil {
+		return
+	}
+	out, err := exec.Command(getconf, "CLK_TCK").Output()
+	// ignore errors
+	if err == nil {
+		i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
+		if err == nil {
+			cpu_tick = float64(i)
+		}
+	}
+}
+
+func Times(percpu bool) ([]TimesStat, error) {
+	filename := common.HostProc("stat")
+	var lines = []string{}
+	if percpu {
+		var startIdx uint = 1
+		for {
+			linen, _ := common.ReadLinesOffsetN(filename, startIdx, 1)
+			line := linen[0]
+			if !strings.HasPrefix(line, "cpu") {
+				break
+			}
+			lines = append(lines, line)
+			startIdx++
+		}
+	} else {
+		lines, _ = common.ReadLinesOffsetN(filename, 0, 1)
+	}
+
+	ret := make([]TimesStat, 0, len(lines))
+
+	for _, line := range lines {
+		ct, err := parseStatLine(line)
+		if err != nil {
+			continue
+		}
+		ret = append(ret, *ct)
+
+	}
+	return ret, nil
+}
+
+func sysCPUPath(cpu int32, relPath string) string {
+	return common.HostSys(fmt.Sprintf("devices/system/cpu/cpu%d", cpu), relPath)
+}
+
+func finishCPUInfo(c *InfoStat) error {
+	if c.Mhz == 0 {
+		lines, err := common.ReadLines(sysCPUPath(c.CPU, "cpufreq/cpuinfo_max_freq"))
+		if err == nil {
+			value, err := strconv.ParseFloat(lines[0], 64)
+			if err != nil {
+				return err
+			}
+			c.Mhz = value
+		}
+	}
+	if len(c.CoreID) == 0 {
+		lines, err := common.ReadLines(sysCPUPath(c.CPU, "topology/coreId"))
+		if err == nil {
+			c.CoreID = lines[0]
+		}
+	}
+	return nil
+}
+
+// CPUInfo on linux will return 1 item per physical thread.
+//
+// CPUs have three levels of counting: sockets, cores, threads.
+// Cores with HyperThreading count as having 2 threads per core.
+// Sockets often come with many physical CPU cores.
+// For example a single socket board with two cores each with HT will
+// return 4 CPUInfoStat structs on Linux and the "Cores" field set to 1.
+func Info() ([]InfoStat, error) {
+	filename := common.HostProc("cpuinfo")
+	lines, _ := common.ReadLines(filename)
+
+	var ret []InfoStat
+
+	c := InfoStat{CPU: -1, Cores: 1}
+	for _, line := range lines {
+		fields := strings.Split(line, ":")
+		if len(fields) < 2 {
+			continue
+		}
+		key := strings.TrimSpace(fields[0])
+		value := strings.TrimSpace(fields[1])
+
+		switch key {
+		case "processor":
+			if c.CPU >= 0 {
+				err := finishCPUInfo(&c)
+				if err != nil {
+					return ret, err
+				}
+				ret = append(ret, c)
+			}
+			c = InfoStat{Cores: 1}
+			t, err := strconv.ParseInt(value, 10, 64)
+			if err != nil {
+				return ret, err
+			}
+			c.CPU = int32(t)
+		case "vendorId", "vendor_id":
+			c.VendorID = value
+		case "cpu family":
+			c.Family = value
+		case "model":
+			c.Model = value
+		case "model name":
+			c.ModelName = value
+		case "stepping":
+			t, err := strconv.ParseInt(value, 10, 64)
+			if err != nil {
+				return ret, err
+			}
+			c.Stepping = int32(t)
+		case "cpu MHz":
+			t, err := strconv.ParseFloat(value, 64)
+			if err != nil {
+				return ret, err
+			}
+			c.Mhz = t
+		case "cache size":
+			t, err := strconv.ParseInt(strings.Replace(value, " KB", "", 1), 10, 64)
+			if err != nil {
+				return ret, err
+			}
+			c.CacheSize = int32(t)
+		case "physical id":
+			c.PhysicalID = value
+		case "core id":
+			c.CoreID = value
+		case "flags", "Features":
+			c.Flags = strings.FieldsFunc(value, func(r rune) bool {
+				return r == ',' || r == ' '
+			})
+		}
+	}
+	if c.CPU >= 0 {
+		err := finishCPUInfo(&c)
+		if err != nil {
+			return ret, err
+		}
+		ret = append(ret, c)
+	}
+	return ret, nil
+}
+
+func parseStatLine(line string) (*TimesStat, error) {
+	fields := strings.Fields(line)
+
+	if strings.HasPrefix(fields[0], "cpu") == false {
+		//		return CPUTimesStat{}, e
+		return nil, errors.New("not contain cpu")
+	}
+
+	cpu := fields[0]
+	if cpu == "cpu" {
+		cpu = "cpu-total"
+	}
+	user, err := strconv.ParseFloat(fields[1], 64)
+	if err != nil {
+		return nil, err
+	}
+	nice, err := strconv.ParseFloat(fields[2], 64)
+	if err != nil {
+		return nil, err
+	}
+	system, err := strconv.ParseFloat(fields[3], 64)
+	if err != nil {
+		return nil, err
+	}
+	idle, err := strconv.ParseFloat(fields[4], 64)
+	if err != nil {
+		return nil, err
+	}
+	iowait, err := strconv.ParseFloat(fields[5], 64)
+	if err != nil {
+		return nil, err
+	}
+	irq, err := strconv.ParseFloat(fields[6], 64)
+	if err != nil {
+		return nil, err
+	}
+	softirq, err := strconv.ParseFloat(fields[7], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	ct := &TimesStat{
+		CPU:     cpu,
+		User:    float64(user) / cpu_tick,
+		Nice:    float64(nice) / cpu_tick,
+		System:  float64(system) / cpu_tick,
+		Idle:    float64(idle) / cpu_tick,
+		Iowait:  float64(iowait) / cpu_tick,
+		Irq:     float64(irq) / cpu_tick,
+		Softirq: float64(softirq) / cpu_tick,
+	}
+	if len(fields) > 8 { // Linux >= 2.6.11
+		steal, err := strconv.ParseFloat(fields[8], 64)
+		if err != nil {
+			return nil, err
+		}
+		ct.Steal = float64(steal) / cpu_tick
+	}
+	if len(fields) > 9 { // Linux >= 2.6.24
+		guest, err := strconv.ParseFloat(fields[9], 64)
+		if err != nil {
+			return nil, err
+		}
+		ct.Guest = float64(guest) / cpu_tick
+	}
+	if len(fields) > 10 { // Linux >= 3.2.0
+		guestNice, err := strconv.ParseFloat(fields[10], 64)
+		if err != nil {
+			return nil, err
+		}
+		ct.GuestNice = float64(guestNice) / cpu_tick
+	}
+
+	return ct, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/cpu/cpu_test.go b/go/src/github.com/shirou/gopsutil/cpu/cpu_test.go
new file mode 100644
index 0000000..c3d56eb
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/cpu/cpu_test.go
@@ -0,0 +1,103 @@
+package cpu
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+	"testing"
+	"time"
+)
+
+func TestCpu_times(t *testing.T) {
+	v, err := Times(false)
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	if len(v) == 0 {
+		t.Error("could not get CPUs ", err)
+	}
+	empty := TimesStat{}
+	for _, vv := range v {
+		if vv == empty {
+			t.Errorf("could not get CPU User: %v", vv)
+		}
+	}
+}
+
+func TestCpu_counts(t *testing.T) {
+	v, err := Counts(true)
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	if v == 0 {
+		t.Errorf("could not get CPU counts: %v", v)
+	}
+}
+
+func TestCPUTimeStat_String(t *testing.T) {
+	v := TimesStat{
+		CPU:    "cpu0",
+		User:   100.1,
+		System: 200.1,
+		Idle:   300.1,
+	}
+	e := `{"cpu":"cpu0","user":100.1,"system":200.1,"idle":300.1,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0,"stolen":0.0}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("CPUTimesStat string is invalid: %v", v)
+	}
+}
+
+func TestCpuInfo(t *testing.T) {
+	v, err := Info()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	if len(v) == 0 {
+		t.Errorf("could not get CPU Info")
+	}
+	for _, vv := range v {
+		if vv.ModelName == "" {
+			t.Errorf("could not get CPU Info: %v", vv)
+		}
+	}
+}
+
+func testCPUPercent(t *testing.T, percpu bool) {
+	numcpu := runtime.NumCPU()
+	testCount := 3
+
+	if runtime.GOOS != "windows" {
+		testCount = 100
+		v, err := Percent(time.Millisecond, percpu)
+		if err != nil {
+			t.Errorf("error %v", err)
+		}
+		// Skip CircleCI which CPU num is different
+		if os.Getenv("CIRCLECI") != "true" {
+			if (percpu && len(v) != numcpu) || (!percpu && len(v) != 1) {
+				t.Fatalf("wrong number of entries from CPUPercent: %v", v)
+			}
+		}
+	}
+	for i := 0; i < testCount; i++ {
+		duration := time.Duration(10) * time.Microsecond
+		v, err := Percent(duration, percpu)
+		if err != nil {
+			t.Errorf("error %v", err)
+		}
+		for _, percent := range v {
+			// Check for slightly greater then 100% to account for any rounding issues.
+			if percent < 0.0 || percent > 100.0001*float64(numcpu) {
+				t.Fatalf("CPUPercent value is invalid: %f", percent)
+			}
+		}
+	}
+}
+
+func TestCPUPercent(t *testing.T) {
+	testCPUPercent(t, false)
+}
+
+func TestCPUPercentPerCpu(t *testing.T) {
+	testCPUPercent(t, true)
+}
diff --git a/go/src/github.com/shirou/gopsutil/cpu/cpu_unix.go b/go/src/github.com/shirou/gopsutil/cpu/cpu_unix.go
new file mode 100644
index 0000000..9f1ea4d
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/cpu/cpu_unix.go
@@ -0,0 +1,59 @@
+// +build linux freebsd darwin
+
+package cpu
+
+import (
+	"fmt"
+	"time"
+)
+
+func Percent(interval time.Duration, percpu bool) ([]float64, error) {
+	getAllBusy := func(t TimesStat) (float64, float64) {
+		busy := t.User + t.System + t.Nice + t.Iowait + t.Irq +
+			t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen
+		return busy + t.Idle, busy
+	}
+
+	calculate := func(t1, t2 TimesStat) float64 {
+		t1All, t1Busy := getAllBusy(t1)
+		t2All, t2Busy := getAllBusy(t2)
+
+		if t2Busy <= t1Busy {
+			return 0
+		}
+		if t2All <= t1All {
+			return 1
+		}
+		return (t2Busy - t1Busy) / (t2All - t1All) * 100
+	}
+
+	// Get CPU usage at the start of the interval.
+	cpuTimes1, err := Times(percpu)
+	if err != nil {
+		return nil, err
+	}
+
+	if interval > 0 {
+		time.Sleep(interval)
+	}
+
+	// And at the end of the interval.
+	cpuTimes2, err := Times(percpu)
+	if err != nil {
+		return nil, err
+	}
+
+	// Make sure the CPU measurements have the same length.
+	if len(cpuTimes1) != len(cpuTimes2) {
+		return nil, fmt.Errorf(
+			"received two CPU counts: %d != %d",
+			len(cpuTimes1), len(cpuTimes2),
+		)
+	}
+
+	ret := make([]float64, len(cpuTimes1))
+	for i, t := range cpuTimes2 {
+		ret[i] = calculate(cpuTimes1[i], t)
+	}
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/cpu/cpu_windows.go b/go/src/github.com/shirou/gopsutil/cpu/cpu_windows.go
new file mode 100644
index 0000000..fbd25e6
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/cpu/cpu_windows.go
@@ -0,0 +1,105 @@
+// +build windows
+
+package cpu
+
+import (
+	"fmt"
+	"syscall"
+	"time"
+	"unsafe"
+
+	"github.com/StackExchange/wmi"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+type Win32_Processor struct {
+	LoadPercentage            *uint16
+	Family                    uint16
+	Manufacturer              string
+	Name                      string
+	NumberOfLogicalProcessors uint32
+	ProcessorID               *string
+	Stepping                  *string
+	MaxClockSpeed             uint32
+}
+
+// TODO: Get percpu
+func Times(percpu bool) ([]TimesStat, error) {
+	var ret []TimesStat
+
+	var lpIdleTime common.FILETIME
+	var lpKernelTime common.FILETIME
+	var lpUserTime common.FILETIME
+	r, _, _ := common.ProcGetSystemTimes.Call(
+		uintptr(unsafe.Pointer(&lpIdleTime)),
+		uintptr(unsafe.Pointer(&lpKernelTime)),
+		uintptr(unsafe.Pointer(&lpUserTime)))
+	if r == 0 {
+		return ret, syscall.GetLastError()
+	}
+
+	LOT := float64(0.0000001)
+	HIT := (LOT * 4294967296.0)
+	idle := ((HIT * float64(lpIdleTime.DwHighDateTime)) + (LOT * float64(lpIdleTime.DwLowDateTime)))
+	user := ((HIT * float64(lpUserTime.DwHighDateTime)) + (LOT * float64(lpUserTime.DwLowDateTime)))
+	kernel := ((HIT * float64(lpKernelTime.DwHighDateTime)) + (LOT * float64(lpKernelTime.DwLowDateTime)))
+	system := (kernel - idle)
+
+	ret = append(ret, TimesStat{
+		Idle:   float64(idle),
+		User:   float64(user),
+		System: float64(system),
+	})
+	return ret, nil
+}
+
+func Info() ([]InfoStat, error) {
+	var ret []InfoStat
+	var dst []Win32_Processor
+	q := wmi.CreateQuery(&dst, "")
+	err := wmi.Query(q, &dst)
+	if err != nil {
+		return ret, err
+	}
+
+	var procID string
+	for i, l := range dst {
+		procID = ""
+		if l.ProcessorID != nil {
+			procID = *l.ProcessorID
+		}
+
+		cpu := InfoStat{
+			CPU:        int32(i),
+			Family:     fmt.Sprintf("%d", l.Family),
+			VendorID:   l.Manufacturer,
+			ModelName:  l.Name,
+			Cores:      int32(l.NumberOfLogicalProcessors),
+			PhysicalID: procID,
+			Mhz:        float64(l.MaxClockSpeed),
+			Flags:      []string{},
+		}
+		ret = append(ret, cpu)
+	}
+
+	return ret, nil
+}
+
+func Percent(interval time.Duration, percpu bool) ([]float64, error) {
+	var ret []float64
+	var dst []Win32_Processor
+	q := wmi.CreateQuery(&dst, "")
+	err := wmi.Query(q, &dst)
+	if err != nil {
+		return ret, err
+	}
+	for _, l := range dst {
+		// use range but windows can only get one percent.
+		if l.LoadPercentage == nil {
+			continue
+		}
+		ret = append(ret, float64(*l.LoadPercentage))
+	}
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/disk.go b/go/src/github.com/shirou/gopsutil/disk/disk.go
new file mode 100644
index 0000000..b187a1d
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/disk.go
@@ -0,0 +1,52 @@
+package disk
+
+import (
+	"encoding/json"
+)
+
+type UsageStat struct {
+	Path              string  `json:"path"`
+	Fstype            string  `json:"fstype"`
+	Total             uint64  `json:"total"`
+	Free              uint64  `json:"free"`
+	Used              uint64  `json:"used"`
+	UsedPercent       float64 `json:"usedPercent"`
+	InodesTotal       uint64  `json:"inodesTotal"`
+	InodesUsed        uint64  `json:"inodesUsed"`
+	InodesFree        uint64  `json:"inodesFree"`
+	InodesUsedPercent float64 `json:"inodesUsedPercent"`
+}
+
+type PartitionStat struct {
+	Device     string `json:"device"`
+	Mountpoint string `json:"mountpoint"`
+	Fstype     string `json:"fstype"`
+	Opts       string `json:"opts"`
+}
+
+type IOCountersStat struct {
+	ReadCount    uint64 `json:"readCount"`
+	WriteCount   uint64 `json:"writeCount"`
+	ReadBytes    uint64 `json:"readBytes"`
+	WriteBytes   uint64 `json:"writeBytes"`
+	ReadTime     uint64 `json:"readTime"`
+	WriteTime    uint64 `json:"writeTime"`
+	Name         string `json:"name"`
+	IoTime       uint64 `json:"ioTime"`
+	SerialNumber string `json:"serialNumber"`
+}
+
+func (d UsageStat) String() string {
+	s, _ := json.Marshal(d)
+	return string(s)
+}
+
+func (d PartitionStat) String() string {
+	s, _ := json.Marshal(d)
+	return string(s)
+}
+
+func (d IOCountersStat) String() string {
+	s, _ := json.Marshal(d)
+	return string(s)
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/disk_darwin.go b/go/src/github.com/shirou/gopsutil/disk/disk_darwin.go
new file mode 100644
index 0000000..1ccb330
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/disk_darwin.go
@@ -0,0 +1,111 @@
+// +build darwin
+
+package disk
+
+import (
+	"path"
+	"syscall"
+	"unsafe"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func Partitions(all bool) ([]PartitionStat, error) {
+	var ret []PartitionStat
+
+	count, err := Getfsstat(nil, MntWait)
+	if err != nil {
+		return ret, err
+	}
+	fs := make([]Statfs_t, count)
+	_, err = Getfsstat(fs, MntWait)
+	for _, stat := range fs {
+		opts := "rw"
+		if stat.Flags&MntReadOnly != 0 {
+			opts = "ro"
+		}
+		if stat.Flags&MntSynchronous != 0 {
+			opts += ",sync"
+		}
+		if stat.Flags&MntNoExec != 0 {
+			opts += ",noexec"
+		}
+		if stat.Flags&MntNoSuid != 0 {
+			opts += ",nosuid"
+		}
+		if stat.Flags&MntUnion != 0 {
+			opts += ",union"
+		}
+		if stat.Flags&MntAsync != 0 {
+			opts += ",async"
+		}
+		if stat.Flags&MntSuidDir != 0 {
+			opts += ",suiddir"
+		}
+		if stat.Flags&MntSoftDep != 0 {
+			opts += ",softdep"
+		}
+		if stat.Flags&MntNoSymFollow != 0 {
+			opts += ",nosymfollow"
+		}
+		if stat.Flags&MntGEOMJournal != 0 {
+			opts += ",gjounalc"
+		}
+		if stat.Flags&MntMultilabel != 0 {
+			opts += ",multilabel"
+		}
+		if stat.Flags&MntACLs != 0 {
+			opts += ",acls"
+		}
+		if stat.Flags&MntNoATime != 0 {
+			opts += ",noattime"
+		}
+		if stat.Flags&MntClusterRead != 0 {
+			opts += ",nocluster"
+		}
+		if stat.Flags&MntClusterWrite != 0 {
+			opts += ",noclusterw"
+		}
+		if stat.Flags&MntNFS4ACLs != 0 {
+			opts += ",nfs4acls"
+		}
+		d := PartitionStat{
+			Device:     common.IntToString(stat.Mntfromname[:]),
+			Mountpoint: common.IntToString(stat.Mntonname[:]),
+			Fstype:     common.IntToString(stat.Fstypename[:]),
+			Opts:       opts,
+		}
+		if all == false {
+			if !path.IsAbs(d.Device) || !common.PathExists(d.Device) {
+				continue
+			}
+		}
+
+		ret = append(ret, d)
+	}
+
+	return ret, nil
+}
+
+func IOCounters() (map[string]IOCountersStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
+	var _p0 unsafe.Pointer
+	var bufsize uintptr
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+		bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
+	}
+	r0, _, e1 := syscall.Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func getFsType(stat syscall.Statfs_t) string {
+	return common.IntToString(stat.Fstypename[:])
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/disk_darwin_amd64.go b/go/src/github.com/shirou/gopsutil/disk/disk_darwin_amd64.go
new file mode 100644
index 0000000..f58e213
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/disk_darwin_amd64.go
@@ -0,0 +1,58 @@
+// +build darwin
+// +build amd64
+
+package disk
+
+const (
+	MntWait    = 1
+	MfsNameLen = 15 /* length of fs type name, not inc. nul */
+	MNameLen   = 90 /* length of buffer for returned name */
+
+	MFSTYPENAMELEN = 16 /* length of fs type name including null */
+	MAXPATHLEN     = 1024
+	MNAMELEN       = MAXPATHLEN
+
+	SYS_GETFSSTAT64 = 347
+)
+
+type Fsid struct{ val [2]int32 } /* file system id type */
+type uid_t int32
+
+// sys/mount.h
+const (
+	MntReadOnly     = 0x00000001 /* read only filesystem */
+	MntSynchronous  = 0x00000002 /* filesystem written synchronously */
+	MntNoExec       = 0x00000004 /* can't exec from filesystem */
+	MntNoSuid       = 0x00000008 /* don't honor setuid bits on fs */
+	MntUnion        = 0x00000020 /* union with underlying filesystem */
+	MntAsync        = 0x00000040 /* filesystem written asynchronously */
+	MntSuidDir      = 0x00100000 /* special handling of SUID on dirs */
+	MntSoftDep      = 0x00200000 /* soft updates being done */
+	MntNoSymFollow  = 0x00400000 /* do not follow symlinks */
+	MntGEOMJournal  = 0x02000000 /* GEOM journal support enabled */
+	MntMultilabel   = 0x04000000 /* MAC support for individual objects */
+	MntACLs         = 0x08000000 /* ACL support enabled */
+	MntNoATime      = 0x10000000 /* disable update of file access time */
+	MntClusterRead  = 0x40000000 /* disable cluster read */
+	MntClusterWrite = 0x80000000 /* disable cluster write */
+	MntNFS4ACLs     = 0x00000010
+)
+
+type Statfs_t struct {
+	Bsize       uint32
+	Iosize      int32
+	Blocks      uint64
+	Bfree       uint64
+	Bavail      uint64
+	Files       uint64
+	Ffree       uint64
+	Fsid        Fsid
+	Owner       uint32
+	Type        uint32
+	Flags       uint32
+	Fssubtype   uint32
+	Fstypename  [16]int8
+	Mntonname   [1024]int8
+	Mntfromname [1024]int8
+	Reserved    [8]uint32
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/disk_freebsd.go b/go/src/github.com/shirou/gopsutil/disk/disk_freebsd.go
new file mode 100644
index 0000000..4024bcb
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/disk_freebsd.go
@@ -0,0 +1,175 @@
+// +build freebsd
+
+package disk
+
+import (
+	"bytes"
+	"encoding/binary"
+	"path"
+	"strconv"
+	"syscall"
+	"unsafe"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func Partitions(all bool) ([]PartitionStat, error) {
+	var ret []PartitionStat
+
+	// get length
+	count, err := syscall.Getfsstat(nil, MNT_WAIT)
+	if err != nil {
+		return ret, err
+	}
+
+	fs := make([]Statfs, count)
+	_, err = Getfsstat(fs, MNT_WAIT)
+
+	for _, stat := range fs {
+		opts := "rw"
+		if stat.Flags&MNT_RDONLY != 0 {
+			opts = "ro"
+		}
+		if stat.Flags&MNT_SYNCHRONOUS != 0 {
+			opts += ",sync"
+		}
+		if stat.Flags&MNT_NOEXEC != 0 {
+			opts += ",noexec"
+		}
+		if stat.Flags&MNT_NOSUID != 0 {
+			opts += ",nosuid"
+		}
+		if stat.Flags&MNT_UNION != 0 {
+			opts += ",union"
+		}
+		if stat.Flags&MNT_ASYNC != 0 {
+			opts += ",async"
+		}
+		if stat.Flags&MNT_SUIDDIR != 0 {
+			opts += ",suiddir"
+		}
+		if stat.Flags&MNT_SOFTDEP != 0 {
+			opts += ",softdep"
+		}
+		if stat.Flags&MNT_NOSYMFOLLOW != 0 {
+			opts += ",nosymfollow"
+		}
+		if stat.Flags&MNT_GJOURNAL != 0 {
+			opts += ",gjounalc"
+		}
+		if stat.Flags&MNT_MULTILABEL != 0 {
+			opts += ",multilabel"
+		}
+		if stat.Flags&MNT_ACLS != 0 {
+			opts += ",acls"
+		}
+		if stat.Flags&MNT_NOATIME != 0 {
+			opts += ",noattime"
+		}
+		if stat.Flags&MNT_NOCLUSTERR != 0 {
+			opts += ",nocluster"
+		}
+		if stat.Flags&MNT_NOCLUSTERW != 0 {
+			opts += ",noclusterw"
+		}
+		if stat.Flags&MNT_NFS4ACLS != 0 {
+			opts += ",nfs4acls"
+		}
+
+		d := PartitionStat{
+			Device:     common.IntToString(stat.Mntfromname[:]),
+			Mountpoint: common.IntToString(stat.Mntonname[:]),
+			Fstype:     common.IntToString(stat.Fstypename[:]),
+			Opts:       opts,
+		}
+		if all == false {
+			if !path.IsAbs(d.Device) || !common.PathExists(d.Device) {
+				continue
+			}
+		}
+
+		ret = append(ret, d)
+	}
+
+	return ret, nil
+}
+
+func IOCounters() (map[string]IOCountersStat, error) {
+	// statinfo->devinfo->devstat
+	// /usr/include/devinfo.h
+	ret := make(map[string]IOCountersStat)
+
+	r, err := syscall.Sysctl("kern.devstat.all")
+	if err != nil {
+		return nil, err
+	}
+	buf := []byte(r)
+	length := len(buf)
+
+	count := int(uint64(length) / uint64(sizeOfDevstat))
+
+	buf = buf[8:] // devstat.all has version in the head.
+	// parse buf to Devstat
+	for i := 0; i < count; i++ {
+		b := buf[i*sizeOfDevstat : i*sizeOfDevstat+sizeOfDevstat]
+		d, err := parseDevstat(b)
+		if err != nil {
+			continue
+		}
+		un := strconv.Itoa(int(d.Unit_number))
+		name := common.IntToString(d.Device_name[:]) + un
+
+		ds := IOCountersStat{
+			ReadCount:  d.Operations[DEVSTAT_READ],
+			WriteCount: d.Operations[DEVSTAT_WRITE],
+			ReadBytes:  d.Bytes[DEVSTAT_READ],
+			WriteBytes: d.Bytes[DEVSTAT_WRITE],
+			ReadTime:   d.Duration[DEVSTAT_READ].Compute(),
+			WriteTime:  d.Duration[DEVSTAT_WRITE].Compute(),
+			Name:       name,
+		}
+		ret[name] = ds
+	}
+
+	return ret, nil
+}
+
+func (b Bintime) Compute() uint64 {
+	BINTIME_SCALE := 5.42101086242752217003726400434970855712890625e-20
+	return uint64(b.Sec) + b.Frac*uint64(BINTIME_SCALE)
+}
+
+// BT2LD(time)     ((long double)(time).sec + (time).frac * BINTIME_SCALE)
+
+// Getfsstat is borrowed from pkg/syscall/syscall_freebsd.go
+// change Statfs_t to Statfs in order to get more information
+func Getfsstat(buf []Statfs, flags int) (n int, err error) {
+	var _p0 unsafe.Pointer
+	var bufsize uintptr
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+		bufsize = unsafe.Sizeof(Statfs{}) * uintptr(len(buf))
+	}
+	r0, _, e1 := syscall.Syscall(syscall.SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func parseDevstat(buf []byte) (Devstat, error) {
+	var ds Devstat
+	br := bytes.NewReader(buf)
+	//	err := binary.Read(br, binary.LittleEndian, &ds)
+	err := common.Read(br, binary.LittleEndian, &ds)
+	if err != nil {
+		return ds, err
+	}
+
+	return ds, nil
+}
+
+func getFsType(stat syscall.Statfs_t) string {
+	return common.IntToString(stat.Fstypename[:])
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/disk_freebsd_386.go b/go/src/github.com/shirou/gopsutil/disk/disk_freebsd_386.go
new file mode 100644
index 0000000..0b3f536
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/disk_freebsd_386.go
@@ -0,0 +1,112 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_freebsd.go
+
+package disk
+
+const (
+	sizeofPtr        = 0x4
+	sizeofShort      = 0x2
+	sizeofInt        = 0x4
+	sizeofLong       = 0x4
+	sizeofLongLong   = 0x8
+	sizeofLongDouble = 0x8
+
+	DEVSTAT_NO_DATA = 0x00
+	DEVSTAT_READ    = 0x01
+	DEVSTAT_WRITE   = 0x02
+	DEVSTAT_FREE    = 0x03
+
+	MNT_RDONLY      = 0x00000001
+	MNT_SYNCHRONOUS = 0x00000002
+	MNT_NOEXEC      = 0x00000004
+	MNT_NOSUID      = 0x00000008
+	MNT_UNION       = 0x00000020
+	MNT_ASYNC       = 0x00000040
+	MNT_SUIDDIR     = 0x00100000
+	MNT_SOFTDEP     = 0x00200000
+	MNT_NOSYMFOLLOW = 0x00400000
+	MNT_GJOURNAL    = 0x02000000
+	MNT_MULTILABEL  = 0x04000000
+	MNT_ACLS        = 0x08000000
+	MNT_NOATIME     = 0x10000000
+	MNT_NOCLUSTERR  = 0x40000000
+	MNT_NOCLUSTERW  = 0x80000000
+	MNT_NFS4ACLS    = 0x00000010
+
+	MNT_WAIT    = 1
+	MNT_NOWAIT  = 2
+	MNT_LAZY    = 3
+	MNT_SUSPEND = 4
+)
+
+const (
+	sizeOfDevstat = 0xf0
+)
+
+type (
+	_C_short       int16
+	_C_int         int32
+	_C_long        int32
+	_C_long_long   int64
+	_C_long_double int64
+)
+
+type Statfs struct {
+	Version     uint32
+	Type        uint32
+	Flags       uint64
+	Bsize       uint64
+	Iosize      uint64
+	Blocks      uint64
+	Bfree       uint64
+	Bavail      int64
+	Files       uint64
+	Ffree       int64
+	Syncwrites  uint64
+	Asyncwrites uint64
+	Syncreads   uint64
+	Asyncreads  uint64
+	Spare       [10]uint64
+	Namemax     uint32
+	Owner       uint32
+	Fsid        Fsid
+	Charspare   [80]int8
+	Fstypename  [16]int8
+	Mntfromname [88]int8
+	Mntonname   [88]int8
+}
+type Fsid struct {
+	Val [2]int32
+}
+
+type Devstat struct {
+	Sequence0     uint32
+	Allocated     int32
+	Start_count   uint32
+	End_count     uint32
+	Busy_from     Bintime
+	Dev_links     _Ctype_struct___0
+	Device_number uint32
+	Device_name   [16]int8
+	Unit_number   int32
+	Bytes         [4]uint64
+	Operations    [4]uint64
+	Duration      [4]Bintime
+	Busy_time     Bintime
+	Creation_time Bintime
+	Block_size    uint32
+	Tag_types     [3]uint64
+	Flags         uint32
+	Device_type   uint32
+	Priority      uint32
+	Id            *byte
+	Sequence1     uint32
+}
+type Bintime struct {
+	Sec  int32
+	Frac uint64
+}
+
+type _Ctype_struct___0 struct {
+	Empty uint32
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/disk_freebsd_amd64.go b/go/src/github.com/shirou/gopsutil/disk/disk_freebsd_amd64.go
new file mode 100644
index 0000000..89b617c
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/disk_freebsd_amd64.go
@@ -0,0 +1,115 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_freebsd.go
+
+package disk
+
+const (
+	sizeofPtr        = 0x8
+	sizeofShort      = 0x2
+	sizeofInt        = 0x4
+	sizeofLong       = 0x8
+	sizeofLongLong   = 0x8
+	sizeofLongDouble = 0x8
+
+	DEVSTAT_NO_DATA = 0x00
+	DEVSTAT_READ    = 0x01
+	DEVSTAT_WRITE   = 0x02
+	DEVSTAT_FREE    = 0x03
+
+	MNT_RDONLY      = 0x00000001
+	MNT_SYNCHRONOUS = 0x00000002
+	MNT_NOEXEC      = 0x00000004
+	MNT_NOSUID      = 0x00000008
+	MNT_UNION       = 0x00000020
+	MNT_ASYNC       = 0x00000040
+	MNT_SUIDDIR     = 0x00100000
+	MNT_SOFTDEP     = 0x00200000
+	MNT_NOSYMFOLLOW = 0x00400000
+	MNT_GJOURNAL    = 0x02000000
+	MNT_MULTILABEL  = 0x04000000
+	MNT_ACLS        = 0x08000000
+	MNT_NOATIME     = 0x10000000
+	MNT_NOCLUSTERR  = 0x40000000
+	MNT_NOCLUSTERW  = 0x80000000
+	MNT_NFS4ACLS    = 0x00000010
+
+	MNT_WAIT    = 1
+	MNT_NOWAIT  = 2
+	MNT_LAZY    = 3
+	MNT_SUSPEND = 4
+)
+
+const (
+	sizeOfDevstat = 0x120
+)
+
+type (
+	_C_short       int16
+	_C_int         int32
+	_C_long        int64
+	_C_long_long   int64
+	_C_long_double int64
+)
+
+type Statfs struct {
+	Version     uint32
+	Type        uint32
+	Flags       uint64
+	Bsize       uint64
+	Iosize      uint64
+	Blocks      uint64
+	Bfree       uint64
+	Bavail      int64
+	Files       uint64
+	Ffree       int64
+	Syncwrites  uint64
+	Asyncwrites uint64
+	Syncreads   uint64
+	Asyncreads  uint64
+	Spare       [10]uint64
+	Namemax     uint32
+	Owner       uint32
+	Fsid        Fsid
+	Charspare   [80]int8
+	Fstypename  [16]int8
+	Mntfromname [88]int8
+	Mntonname   [88]int8
+}
+type Fsid struct {
+	Val [2]int32
+}
+
+type Devstat struct {
+	Sequence0     uint32
+	Allocated     int32
+	Start_count   uint32
+	End_count     uint32
+	Busy_from     Bintime
+	Dev_links     _Ctype_struct___0
+	Device_number uint32
+	Device_name   [16]int8
+	Unit_number   int32
+	Bytes         [4]uint64
+	Operations    [4]uint64
+	Duration      [4]Bintime
+	Busy_time     Bintime
+	Creation_time Bintime
+	Block_size    uint32
+	Pad_cgo_0     [4]byte
+	Tag_types     [3]uint64
+	Flags         uint32
+	Device_type   uint32
+	Priority      uint32
+	Pad_cgo_1     [4]byte
+	ID            *byte
+	Sequence1     uint32
+	Pad_cgo_2     [4]byte
+}
+type Bintime struct {
+	Sec  int64
+	Frac uint64
+}
+
+type _Ctype_struct___0 struct {
+	Empty uint64
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/disk_linux.go b/go/src/github.com/shirou/gopsutil/disk/disk_linux.go
new file mode 100644
index 0000000..c1c3345
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/disk_linux.go
@@ -0,0 +1,367 @@
+// +build linux
+
+package disk
+
+import (
+	"fmt"
+	"os/exec"
+	"strconv"
+	"strings"
+	"syscall"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+const (
+	SectorSize = 512
+)
+const (
+	// man statfs
+	ADFS_SUPER_MAGIC      = 0xadf5
+	AFFS_SUPER_MAGIC      = 0xADFF
+	BDEVFS_MAGIC          = 0x62646576
+	BEFS_SUPER_MAGIC      = 0x42465331
+	BFS_MAGIC             = 0x1BADFACE
+	BINFMTFS_MAGIC        = 0x42494e4d
+	BTRFS_SUPER_MAGIC     = 0x9123683E
+	CGROUP_SUPER_MAGIC    = 0x27e0eb
+	CIFS_MAGIC_NUMBER     = 0xFF534D42
+	CODA_SUPER_MAGIC      = 0x73757245
+	COH_SUPER_MAGIC       = 0x012FF7B7
+	CRAMFS_MAGIC          = 0x28cd3d45
+	DEBUGFS_MAGIC         = 0x64626720
+	DEVFS_SUPER_MAGIC     = 0x1373
+	DEVPTS_SUPER_MAGIC    = 0x1cd1
+	EFIVARFS_MAGIC        = 0xde5e81e4
+	EFS_SUPER_MAGIC       = 0x00414A53
+	EXT_SUPER_MAGIC       = 0x137D
+	EXT2_OLD_SUPER_MAGIC  = 0xEF51
+	EXT2_SUPER_MAGIC      = 0xEF53
+	EXT3_SUPER_MAGIC      = 0xEF53
+	EXT4_SUPER_MAGIC      = 0xEF53
+	FUSE_SUPER_MAGIC      = 0x65735546
+	FUTEXFS_SUPER_MAGIC   = 0xBAD1DEA
+	HFS_SUPER_MAGIC       = 0x4244
+	HOSTFS_SUPER_MAGIC    = 0x00c0ffee
+	HPFS_SUPER_MAGIC      = 0xF995E849
+	HUGETLBFS_MAGIC       = 0x958458f6
+	ISOFS_SUPER_MAGIC     = 0x9660
+	JFFS2_SUPER_MAGIC     = 0x72b6
+	JFS_SUPER_MAGIC       = 0x3153464a
+	MINIX_SUPER_MAGIC     = 0x137F /* orig. minix */
+	MINIX_SUPER_MAGIC2    = 0x138F /* 30 char minix */
+	MINIX2_SUPER_MAGIC    = 0x2468 /* minix V2 */
+	MINIX2_SUPER_MAGIC2   = 0x2478 /* minix V2, 30 char names */
+	MINIX3_SUPER_MAGIC    = 0x4d5a /* minix V3 fs, 60 char names */
+	MQUEUE_MAGIC          = 0x19800202
+	MSDOS_SUPER_MAGIC     = 0x4d44
+	NCP_SUPER_MAGIC       = 0x564c
+	NFS_SUPER_MAGIC       = 0x6969
+	NILFS_SUPER_MAGIC     = 0x3434
+	NTFS_SB_MAGIC         = 0x5346544e
+	OCFS2_SUPER_MAGIC     = 0x7461636f
+	OPENPROM_SUPER_MAGIC  = 0x9fa1
+	PIPEFS_MAGIC          = 0x50495045
+	PROC_SUPER_MAGIC      = 0x9fa0
+	PSTOREFS_MAGIC        = 0x6165676C
+	QNX4_SUPER_MAGIC      = 0x002f
+	QNX6_SUPER_MAGIC      = 0x68191122
+	RAMFS_MAGIC           = 0x858458f6
+	REISERFS_SUPER_MAGIC  = 0x52654973
+	ROMFS_MAGIC           = 0x7275
+	SELINUX_MAGIC         = 0xf97cff8c
+	SMACK_MAGIC           = 0x43415d53
+	SMB_SUPER_MAGIC       = 0x517B
+	SOCKFS_MAGIC          = 0x534F434B
+	SQUASHFS_MAGIC        = 0x73717368
+	SYSFS_MAGIC           = 0x62656572
+	SYSV2_SUPER_MAGIC     = 0x012FF7B6
+	SYSV4_SUPER_MAGIC     = 0x012FF7B5
+	TMPFS_MAGIC           = 0x01021994
+	UDF_SUPER_MAGIC       = 0x15013346
+	UFS_MAGIC             = 0x00011954
+	USBDEVICE_SUPER_MAGIC = 0x9fa2
+	V9FS_MAGIC            = 0x01021997
+	VXFS_SUPER_MAGIC      = 0xa501FCF5
+	XENFS_SUPER_MAGIC     = 0xabba1974
+	XENIX_SUPER_MAGIC     = 0x012FF7B4
+	XFS_SUPER_MAGIC       = 0x58465342
+	_XIAFS_SUPER_MAGIC    = 0x012FD16D
+
+	AFS_SUPER_MAGIC             = 0x5346414F
+	AUFS_SUPER_MAGIC            = 0x61756673
+	ANON_INODE_FS_SUPER_MAGIC   = 0x09041934
+	CEPH_SUPER_MAGIC            = 0x00C36400
+	ECRYPTFS_SUPER_MAGIC        = 0xF15F
+	FAT_SUPER_MAGIC             = 0x4006
+	FHGFS_SUPER_MAGIC           = 0x19830326
+	FUSEBLK_SUPER_MAGIC         = 0x65735546
+	FUSECTL_SUPER_MAGIC         = 0x65735543
+	GFS_SUPER_MAGIC             = 0x1161970
+	GPFS_SUPER_MAGIC            = 0x47504653
+	MTD_INODE_FS_SUPER_MAGIC    = 0x11307854
+	INOTIFYFS_SUPER_MAGIC       = 0x2BAD1DEA
+	ISOFS_R_WIN_SUPER_MAGIC     = 0x4004
+	ISOFS_WIN_SUPER_MAGIC       = 0x4000
+	JFFS_SUPER_MAGIC            = 0x07C0
+	KAFS_SUPER_MAGIC            = 0x6B414653
+	LUSTRE_SUPER_MAGIC          = 0x0BD00BD0
+	NFSD_SUPER_MAGIC            = 0x6E667364
+	PANFS_SUPER_MAGIC           = 0xAAD7AAEA
+	RPC_PIPEFS_SUPER_MAGIC      = 0x67596969
+	SECURITYFS_SUPER_MAGIC      = 0x73636673
+	UFS_BYTESWAPPED_SUPER_MAGIC = 0x54190100
+	VMHGFS_SUPER_MAGIC          = 0xBACBACBC
+	VZFS_SUPER_MAGIC            = 0x565A4653
+	ZFS_SUPER_MAGIC             = 0x2FC12FC1
+)
+
+// coreutils/src/stat.c
+var fsTypeMap = map[int64]string{
+	ADFS_SUPER_MAGIC:          "adfs",          /* 0xADF5 local */
+	AFFS_SUPER_MAGIC:          "affs",          /* 0xADFF local */
+	AFS_SUPER_MAGIC:           "afs",           /* 0x5346414F remote */
+	ANON_INODE_FS_SUPER_MAGIC: "anon-inode FS", /* 0x09041934 local */
+	AUFS_SUPER_MAGIC:          "aufs",          /* 0x61756673 remote */
+	//	AUTOFS_SUPER_MAGIC:          "autofs",              /* 0x0187 local */
+	BEFS_SUPER_MAGIC:            "befs",                /* 0x42465331 local */
+	BDEVFS_MAGIC:                "bdevfs",              /* 0x62646576 local */
+	BFS_MAGIC:                   "bfs",                 /* 0x1BADFACE local */
+	BINFMTFS_MAGIC:              "binfmt_misc",         /* 0x42494E4D local */
+	BTRFS_SUPER_MAGIC:           "btrfs",               /* 0x9123683E local */
+	CEPH_SUPER_MAGIC:            "ceph",                /* 0x00C36400 remote */
+	CGROUP_SUPER_MAGIC:          "cgroupfs",            /* 0x0027E0EB local */
+	CIFS_MAGIC_NUMBER:           "cifs",                /* 0xFF534D42 remote */
+	CODA_SUPER_MAGIC:            "coda",                /* 0x73757245 remote */
+	COH_SUPER_MAGIC:             "coh",                 /* 0x012FF7B7 local */
+	CRAMFS_MAGIC:                "cramfs",              /* 0x28CD3D45 local */
+	DEBUGFS_MAGIC:               "debugfs",             /* 0x64626720 local */
+	DEVFS_SUPER_MAGIC:           "devfs",               /* 0x1373 local */
+	DEVPTS_SUPER_MAGIC:          "devpts",              /* 0x1CD1 local */
+	ECRYPTFS_SUPER_MAGIC:        "ecryptfs",            /* 0xF15F local */
+	EFS_SUPER_MAGIC:             "efs",                 /* 0x00414A53 local */
+	EXT_SUPER_MAGIC:             "ext",                 /* 0x137D local */
+	EXT2_SUPER_MAGIC:            "ext2/ext3",           /* 0xEF53 local */
+	EXT2_OLD_SUPER_MAGIC:        "ext2",                /* 0xEF51 local */
+	FAT_SUPER_MAGIC:             "fat",                 /* 0x4006 local */
+	FHGFS_SUPER_MAGIC:           "fhgfs",               /* 0x19830326 remote */
+	FUSEBLK_SUPER_MAGIC:         "fuseblk",             /* 0x65735546 remote */
+	FUSECTL_SUPER_MAGIC:         "fusectl",             /* 0x65735543 remote */
+	FUTEXFS_SUPER_MAGIC:         "futexfs",             /* 0x0BAD1DEA local */
+	GFS_SUPER_MAGIC:             "gfs/gfs2",            /* 0x1161970 remote */
+	GPFS_SUPER_MAGIC:            "gpfs",                /* 0x47504653 remote */
+	HFS_SUPER_MAGIC:             "hfs",                 /* 0x4244 local */
+	HPFS_SUPER_MAGIC:            "hpfs",                /* 0xF995E849 local */
+	HUGETLBFS_MAGIC:             "hugetlbfs",           /* 0x958458F6 local */
+	MTD_INODE_FS_SUPER_MAGIC:    "inodefs",             /* 0x11307854 local */
+	INOTIFYFS_SUPER_MAGIC:       "inotifyfs",           /* 0x2BAD1DEA local */
+	ISOFS_SUPER_MAGIC:           "isofs",               /* 0x9660 local */
+	ISOFS_R_WIN_SUPER_MAGIC:     "isofs",               /* 0x4004 local */
+	ISOFS_WIN_SUPER_MAGIC:       "isofs",               /* 0x4000 local */
+	JFFS_SUPER_MAGIC:            "jffs",                /* 0x07C0 local */
+	JFFS2_SUPER_MAGIC:           "jffs2",               /* 0x72B6 local */
+	JFS_SUPER_MAGIC:             "jfs",                 /* 0x3153464A local */
+	KAFS_SUPER_MAGIC:            "k-afs",               /* 0x6B414653 remote */
+	LUSTRE_SUPER_MAGIC:          "lustre",              /* 0x0BD00BD0 remote */
+	MINIX_SUPER_MAGIC:           "minix",               /* 0x137F local */
+	MINIX_SUPER_MAGIC2:          "minix (30 char.)",    /* 0x138F local */
+	MINIX2_SUPER_MAGIC:          "minix v2",            /* 0x2468 local */
+	MINIX2_SUPER_MAGIC2:         "minix v2 (30 char.)", /* 0x2478 local */
+	MINIX3_SUPER_MAGIC:          "minix3",              /* 0x4D5A local */
+	MQUEUE_MAGIC:                "mqueue",              /* 0x19800202 local */
+	MSDOS_SUPER_MAGIC:           "msdos",               /* 0x4D44 local */
+	NCP_SUPER_MAGIC:             "novell",              /* 0x564C remote */
+	NFS_SUPER_MAGIC:             "nfs",                 /* 0x6969 remote */
+	NFSD_SUPER_MAGIC:            "nfsd",                /* 0x6E667364 remote */
+	NILFS_SUPER_MAGIC:           "nilfs",               /* 0x3434 local */
+	NTFS_SB_MAGIC:               "ntfs",                /* 0x5346544E local */
+	OPENPROM_SUPER_MAGIC:        "openprom",            /* 0x9FA1 local */
+	OCFS2_SUPER_MAGIC:           "ocfs2",               /* 0x7461636f remote */
+	PANFS_SUPER_MAGIC:           "panfs",               /* 0xAAD7AAEA remote */
+	PIPEFS_MAGIC:                "pipefs",              /* 0x50495045 remote */
+	PROC_SUPER_MAGIC:            "proc",                /* 0x9FA0 local */
+	PSTOREFS_MAGIC:              "pstorefs",            /* 0x6165676C local */
+	QNX4_SUPER_MAGIC:            "qnx4",                /* 0x002F local */
+	QNX6_SUPER_MAGIC:            "qnx6",                /* 0x68191122 local */
+	RAMFS_MAGIC:                 "ramfs",               /* 0x858458F6 local */
+	REISERFS_SUPER_MAGIC:        "reiserfs",            /* 0x52654973 local */
+	ROMFS_MAGIC:                 "romfs",               /* 0x7275 local */
+	RPC_PIPEFS_SUPER_MAGIC:      "rpc_pipefs",          /* 0x67596969 local */
+	SECURITYFS_SUPER_MAGIC:      "securityfs",          /* 0x73636673 local */
+	SELINUX_MAGIC:               "selinux",             /* 0xF97CFF8C local */
+	SMB_SUPER_MAGIC:             "smb",                 /* 0x517B remote */
+	SOCKFS_MAGIC:                "sockfs",              /* 0x534F434B local */
+	SQUASHFS_MAGIC:              "squashfs",            /* 0x73717368 local */
+	SYSFS_MAGIC:                 "sysfs",               /* 0x62656572 local */
+	SYSV2_SUPER_MAGIC:           "sysv2",               /* 0x012FF7B6 local */
+	SYSV4_SUPER_MAGIC:           "sysv4",               /* 0x012FF7B5 local */
+	TMPFS_MAGIC:                 "tmpfs",               /* 0x01021994 local */
+	UDF_SUPER_MAGIC:             "udf",                 /* 0x15013346 local */
+	UFS_MAGIC:                   "ufs",                 /* 0x00011954 local */
+	UFS_BYTESWAPPED_SUPER_MAGIC: "ufs",                 /* 0x54190100 local */
+	USBDEVICE_SUPER_MAGIC:       "usbdevfs",            /* 0x9FA2 local */
+	V9FS_MAGIC:                  "v9fs",                /* 0x01021997 local */
+	VMHGFS_SUPER_MAGIC:          "vmhgfs",              /* 0xBACBACBC remote */
+	VXFS_SUPER_MAGIC:            "vxfs",                /* 0xA501FCF5 local */
+	VZFS_SUPER_MAGIC:            "vzfs",                /* 0x565A4653 local */
+	XENFS_SUPER_MAGIC:           "xenfs",               /* 0xABBA1974 local */
+	XENIX_SUPER_MAGIC:           "xenix",               /* 0x012FF7B4 local */
+	XFS_SUPER_MAGIC:             "xfs",                 /* 0x58465342 local */
+	_XIAFS_SUPER_MAGIC:          "xia",                 /* 0x012FD16D local */
+	ZFS_SUPER_MAGIC:             "zfs",                 /* 0x2FC12FC1 local */
+}
+
+// Partitions returns disk partitions. If all is false, returns
+// physical devices only (e.g. hard disks, cd-rom drives, USB keys)
+// and ignore all others (e.g. memory partitions such as /dev/shm)
+//
+// should use setmntent(3) but this implement use /etc/mtab file
+func Partitions(all bool) ([]PartitionStat, error) {
+	filename := common.HostEtc("mtab")
+	lines, err := common.ReadLines(filename)
+	if err != nil {
+		return nil, err
+	}
+
+	fs, err := getFileSystems()
+	if err != nil {
+		return nil, err
+	}
+
+	ret := make([]PartitionStat, 0, len(lines))
+
+	for _, line := range lines {
+		fields := strings.Fields(line)
+		d := PartitionStat{
+			Device:     fields[0],
+			Mountpoint: fields[1],
+			Fstype:     fields[2],
+			Opts:       fields[3],
+		}
+		if all == false {
+			if d.Device == "none" || !common.StringsHas(fs, d.Fstype) {
+				continue
+			}
+		}
+		ret = append(ret, d)
+	}
+
+	return ret, nil
+}
+
+// getFileSystems returns supported filesystems from /proc/filesystems
+func getFileSystems() ([]string, error) {
+	filename := common.HostProc("filesystems")
+	lines, err := common.ReadLines(filename)
+	if err != nil {
+		return nil, err
+	}
+	var ret []string
+	for _, line := range lines {
+		if !strings.HasPrefix(line, "nodev") {
+			ret = append(ret, strings.TrimSpace(line))
+			continue
+		}
+		t := strings.Split(line, "\t")
+		if len(t) != 2 || t[1] != "zfs" {
+			continue
+		}
+		ret = append(ret, strings.TrimSpace(t[1]))
+	}
+
+	return ret, nil
+}
+
+func IOCounters() (map[string]IOCountersStat, error) {
+	filename := common.HostProc("diskstats")
+	lines, err := common.ReadLines(filename)
+	if err != nil {
+		return nil, err
+	}
+	ret := make(map[string]IOCountersStat, 0)
+	empty := IOCountersStat{}
+
+	for _, line := range lines {
+		fields := strings.Fields(line)
+		name := fields[2]
+		reads, err := strconv.ParseUint((fields[3]), 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		rbytes, err := strconv.ParseUint((fields[5]), 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		rtime, err := strconv.ParseUint((fields[6]), 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		writes, err := strconv.ParseUint((fields[7]), 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		wbytes, err := strconv.ParseUint((fields[9]), 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		wtime, err := strconv.ParseUint((fields[10]), 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		iotime, err := strconv.ParseUint((fields[12]), 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		d := IOCountersStat{
+			ReadBytes:  rbytes * SectorSize,
+			WriteBytes: wbytes * SectorSize,
+			ReadCount:  reads,
+			WriteCount: writes,
+			ReadTime:   rtime,
+			WriteTime:  wtime,
+			IoTime:     iotime,
+		}
+		if d == empty {
+			continue
+		}
+		d.Name = name
+
+		d.SerialNumber = GetDiskSerialNumber(name)
+		ret[name] = d
+	}
+	return ret, nil
+}
+
+func GetDiskSerialNumber(name string) string {
+	n := fmt.Sprintf("--name=%s", name)
+	udevadm, err := exec.LookPath("/sbin/udevadm")
+	if err != nil {
+		return ""
+	}
+
+	out, err := exec.Command(udevadm, "info", "--query=property", n).Output()
+
+	// does not return error, just an empty string
+	if err != nil {
+		return ""
+	}
+	lines := strings.Split(string(out), "\n")
+	for _, line := range lines {
+		values := strings.Split(line, "=")
+		if len(values) < 2 || values[0] != "ID_SERIAL" {
+			// only get ID_SERIAL, not ID_SERIAL_SHORT
+			continue
+		}
+		return values[1]
+	}
+	return ""
+}
+
+func getFsType(stat syscall.Statfs_t) string {
+	t := int64(stat.Type)
+	ret, ok := fsTypeMap[t]
+	if !ok {
+		return ""
+	}
+	return ret
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/disk_test.go b/go/src/github.com/shirou/gopsutil/disk/disk_test.go
new file mode 100644
index 0000000..8023c03
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/disk_test.go
@@ -0,0 +1,100 @@
+package disk
+
+import (
+	"fmt"
+	"runtime"
+	"testing"
+)
+
+func TestDisk_usage(t *testing.T) {
+	path := "/"
+	if runtime.GOOS == "windows" {
+		path = "C:"
+	}
+	v, err := Usage(path)
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	if v.Path != path {
+		t.Errorf("error %v", err)
+	}
+}
+
+func TestDisk_partitions(t *testing.T) {
+	ret, err := Partitions(false)
+	if err != nil || len(ret) == 0 {
+		t.Errorf("error %v", err)
+	}
+	empty := PartitionStat{}
+	if len(ret) == 0 {
+		t.Errorf("ret is empty")
+	}
+	for _, disk := range ret {
+		if disk == empty {
+			t.Errorf("Could not get device info %v", disk)
+		}
+	}
+}
+
+func TestDisk_io_counters(t *testing.T) {
+	ret, err := IOCounters()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	if len(ret) == 0 {
+		t.Errorf("ret is empty")
+	}
+	empty := IOCountersStat{}
+	for part, io := range ret {
+		if io == empty {
+			t.Errorf("io_counter error %v, %v", part, io)
+		}
+	}
+}
+
+func TestDiskUsageStat_String(t *testing.T) {
+	v := UsageStat{
+		Path:              "/",
+		Total:             1000,
+		Free:              2000,
+		Used:              3000,
+		UsedPercent:       50.1,
+		InodesTotal:       4000,
+		InodesUsed:        5000,
+		InodesFree:        6000,
+		InodesUsedPercent: 49.1,
+		Fstype:            "ext4",
+	}
+	e := `{"path":"/","fstype":"ext4","total":1000,"free":2000,"used":3000,"usedPercent":50.1,"inodesTotal":4000,"inodesUsed":5000,"inodesFree":6000,"inodesUsedPercent":49.1}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("DiskUsageStat string is invalid: %v", v)
+	}
+}
+
+func TestDiskPartitionStat_String(t *testing.T) {
+	v := PartitionStat{
+		Device:     "sd01",
+		Mountpoint: "/",
+		Fstype:     "ext4",
+		Opts:       "ro",
+	}
+	e := `{"device":"sd01","mountpoint":"/","fstype":"ext4","opts":"ro"}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("DiskUsageStat string is invalid: %v", v)
+	}
+}
+
+func TestDiskIOCountersStat_String(t *testing.T) {
+	v := IOCountersStat{
+		Name:         "sd01",
+		ReadCount:    100,
+		WriteCount:   200,
+		ReadBytes:    300,
+		WriteBytes:   400,
+		SerialNumber: "SERIAL",
+	}
+	e := `{"readCount":100,"writeCount":200,"readBytes":300,"writeBytes":400,"readTime":0,"writeTime":0,"name":"sd01","ioTime":0,"serialNumber":"SERIAL"}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("DiskUsageStat string is invalid: %v", v)
+	}
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/disk_unix.go b/go/src/github.com/shirou/gopsutil/disk/disk_unix.go
new file mode 100644
index 0000000..2858008
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/disk_unix.go
@@ -0,0 +1,30 @@
+// +build freebsd linux darwin
+
+package disk
+
+import "syscall"
+
+func Usage(path string) (*UsageStat, error) {
+	stat := syscall.Statfs_t{}
+	err := syscall.Statfs(path, &stat)
+	if err != nil {
+		return nil, err
+	}
+	bsize := stat.Bsize
+
+	ret := &UsageStat{
+		Path:        path,
+		Fstype:      getFsType(stat),
+		Total:       (uint64(stat.Blocks) * uint64(bsize)),
+		Free:        (uint64(stat.Bavail) * uint64(bsize)),
+		InodesTotal: (uint64(stat.Files)),
+		InodesFree:  (uint64(stat.Ffree)),
+	}
+
+	ret.InodesUsed = (ret.InodesTotal - ret.InodesFree)
+	ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0
+	ret.Used = (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(bsize)
+	ret.UsedPercent = (float64(ret.Used) / float64(ret.Total)) * 100.0
+
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/disk_windows.go b/go/src/github.com/shirou/gopsutil/disk/disk_windows.go
new file mode 100644
index 0000000..b3a30d6
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/disk_windows.go
@@ -0,0 +1,155 @@
+// +build windows
+
+package disk
+
+import (
+	"bytes"
+	"syscall"
+	"unsafe"
+
+	"github.com/StackExchange/wmi"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+var (
+	procGetDiskFreeSpaceExW     = common.Modkernel32.NewProc("GetDiskFreeSpaceExW")
+	procGetLogicalDriveStringsW = common.Modkernel32.NewProc("GetLogicalDriveStringsW")
+	procGetDriveType            = common.Modkernel32.NewProc("GetDriveTypeW")
+	provGetVolumeInformation    = common.Modkernel32.NewProc("GetVolumeInformationW")
+)
+
+var (
+	FileFileCompression = int64(16)     // 0x00000010
+	FileReadOnlyVolume  = int64(524288) // 0x00080000
+)
+
+type Win32_PerfFormattedData struct {
+	Name                    string
+	AvgDiskBytesPerRead     uint64
+	AvgDiskBytesPerWrite    uint64
+	AvgDiskReadQueueLength  uint64
+	AvgDiskWriteQueueLength uint64
+	AvgDisksecPerRead       uint64
+	AvgDisksecPerWrite      uint64
+}
+
+const WaitMSec = 500
+
+func Usage(path string) (*UsageStat, error) {
+	ret := &UsageStat{}
+
+	lpFreeBytesAvailable := int64(0)
+	lpTotalNumberOfBytes := int64(0)
+	lpTotalNumberOfFreeBytes := int64(0)
+	diskret, _, err := procGetDiskFreeSpaceExW.Call(
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))),
+		uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
+		uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
+		uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)))
+	if diskret == 0 {
+		return nil, err
+	}
+	ret = &UsageStat{
+		Path:        path,
+		Total:       uint64(lpTotalNumberOfBytes),
+		Free:        uint64(lpTotalNumberOfFreeBytes),
+		Used:        uint64(lpTotalNumberOfBytes) - uint64(lpTotalNumberOfFreeBytes),
+		UsedPercent: (float64(lpTotalNumberOfBytes) - float64(lpTotalNumberOfFreeBytes)) / float64(lpTotalNumberOfBytes) * 100,
+		// InodesTotal: 0,
+		// InodesFree: 0,
+		// InodesUsed: 0,
+		// InodesUsedPercent: 0,
+	}
+	return ret, nil
+}
+
+func Partitions(all bool) ([]PartitionStat, error) {
+	var ret []PartitionStat
+	lpBuffer := make([]byte, 254)
+	diskret, _, err := procGetLogicalDriveStringsW.Call(
+		uintptr(len(lpBuffer)),
+		uintptr(unsafe.Pointer(&lpBuffer[0])))
+	if diskret == 0 {
+		return ret, err
+	}
+	for _, v := range lpBuffer {
+		if v >= 65 && v <= 90 {
+			path := string(v) + ":"
+			if path == "A:" || path == "B:" { // skip floppy drives
+				continue
+			}
+			typepath, _ := syscall.UTF16PtrFromString(path)
+			typeret, _, _ := procGetDriveType.Call(uintptr(unsafe.Pointer(typepath)))
+			if typeret == 0 {
+				return ret, syscall.GetLastError()
+			}
+			// 2: DRIVE_REMOVABLE 3: DRIVE_FIXED 5: DRIVE_CDROM
+
+			if typeret == 2 || typeret == 3 || typeret == 5 {
+				lpVolumeNameBuffer := make([]byte, 256)
+				lpVolumeSerialNumber := int64(0)
+				lpMaximumComponentLength := int64(0)
+				lpFileSystemFlags := int64(0)
+				lpFileSystemNameBuffer := make([]byte, 256)
+				volpath, _ := syscall.UTF16PtrFromString(string(v) + ":/")
+				driveret, _, err := provGetVolumeInformation.Call(
+					uintptr(unsafe.Pointer(volpath)),
+					uintptr(unsafe.Pointer(&lpVolumeNameBuffer[0])),
+					uintptr(len(lpVolumeNameBuffer)),
+					uintptr(unsafe.Pointer(&lpVolumeSerialNumber)),
+					uintptr(unsafe.Pointer(&lpMaximumComponentLength)),
+					uintptr(unsafe.Pointer(&lpFileSystemFlags)),
+					uintptr(unsafe.Pointer(&lpFileSystemNameBuffer[0])),
+					uintptr(len(lpFileSystemNameBuffer)))
+				if driveret == 0 {
+					if typeret == 5 {
+						continue //device is not ready will happen if there is no disk in the drive
+					}
+					return ret, err
+				}
+				opts := "rw"
+				if lpFileSystemFlags&FileReadOnlyVolume != 0 {
+					opts = "ro"
+				}
+				if lpFileSystemFlags&FileFileCompression != 0 {
+					opts += ".compress"
+				}
+
+				d := PartitionStat{
+					Mountpoint: path,
+					Device:     path,
+					Fstype:     string(bytes.Replace(lpFileSystemNameBuffer, []byte("\x00"), []byte(""), -1)),
+					Opts:       opts,
+				}
+				ret = append(ret, d)
+			}
+		}
+	}
+	return ret, nil
+}
+
+func IOCounters() (map[string]IOCountersStat, error) {
+	ret := make(map[string]IOCountersStat, 0)
+	var dst []Win32_PerfFormattedData
+
+	err := wmi.Query("SELECT * FROM Win32_PerfFormattedData_PerfDisk_LogicalDisk ", &dst)
+	if err != nil {
+		return ret, err
+	}
+	for _, d := range dst {
+		if len(d.Name) > 3 { // not get _Total or Harddrive
+			continue
+		}
+		ret[d.Name] = IOCountersStat{
+			Name:       d.Name,
+			ReadCount:  uint64(d.AvgDiskReadQueueLength),
+			WriteCount: d.AvgDiskWriteQueueLength,
+			ReadBytes:  uint64(d.AvgDiskBytesPerRead),
+			WriteBytes: uint64(d.AvgDiskBytesPerWrite),
+			ReadTime:   d.AvgDisksecPerRead,
+			WriteTime:  d.AvgDisksecPerWrite,
+		}
+	}
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/disk/types_freebsd.go b/go/src/github.com/shirou/gopsutil/disk/types_freebsd.go
new file mode 100644
index 0000000..dd6ddc4
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/disk/types_freebsd.go
@@ -0,0 +1,88 @@
+// +build ignore
+// Hand writing: _Ctype_struct___0
+
+/*
+Input to cgo -godefs.
+
+*/
+
+package disk
+
+/*
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <devstat.h>
+
+enum {
+	sizeofPtr = sizeof(void*),
+};
+
+// because statinfo has long double snap_time, redefine with changing long long
+struct statinfo2 {
+        long            cp_time[CPUSTATES];
+        long            tk_nin;
+        long            tk_nout;
+        struct devinfo  *dinfo;
+        long long       snap_time;
+};
+*/
+import "C"
+
+// Machine characteristics; for internal use.
+
+const (
+	sizeofPtr        = C.sizeofPtr
+	sizeofShort      = C.sizeof_short
+	sizeofInt        = C.sizeof_int
+	sizeofLong       = C.sizeof_long
+	sizeofLongLong   = C.sizeof_longlong
+	sizeofLongDouble = C.sizeof_longlong
+
+	DEVSTAT_NO_DATA = 0x00
+	DEVSTAT_READ    = 0x01
+	DEVSTAT_WRITE   = 0x02
+	DEVSTAT_FREE    = 0x03
+
+	// from sys/mount.h
+	MNT_RDONLY      = 0x00000001 /* read only filesystem */
+	MNT_SYNCHRONOUS = 0x00000002 /* filesystem written synchronously */
+	MNT_NOEXEC      = 0x00000004 /* can't exec from filesystem */
+	MNT_NOSUID      = 0x00000008 /* don't honor setuid bits on fs */
+	MNT_UNION       = 0x00000020 /* union with underlying filesystem */
+	MNT_ASYNC       = 0x00000040 /* filesystem written asynchronously */
+	MNT_SUIDDIR     = 0x00100000 /* special handling of SUID on dirs */
+	MNT_SOFTDEP     = 0x00200000 /* soft updates being done */
+	MNT_NOSYMFOLLOW = 0x00400000 /* do not follow symlinks */
+	MNT_GJOURNAL    = 0x02000000 /* GEOM journal support enabled */
+	MNT_MULTILABEL  = 0x04000000 /* MAC support for individual objects */
+	MNT_ACLS        = 0x08000000 /* ACL support enabled */
+	MNT_NOATIME     = 0x10000000 /* disable update of file access time */
+	MNT_NOCLUSTERR  = 0x40000000 /* disable cluster read */
+	MNT_NOCLUSTERW  = 0x80000000 /* disable cluster write */
+	MNT_NFS4ACLS    = 0x00000010
+
+	MNT_WAIT    = 1 /* synchronously wait for I/O to complete */
+	MNT_NOWAIT  = 2 /* start all I/O, but do not wait for it */
+	MNT_LAZY    = 3 /* push data not written by filesystem syncer */
+	MNT_SUSPEND = 4 /* Suspend file system after sync */
+)
+
+const (
+	sizeOfDevstat = C.sizeof_struct_devstat
+)
+
+// Basic types
+
+type (
+	_C_short       C.short
+	_C_int         C.int
+	_C_long        C.long
+	_C_long_long   C.longlong
+	_C_long_double C.longlong
+)
+
+type Statfs C.struct_statfs
+type Fsid C.struct_fsid
+
+type Devstat C.struct_devstat
+type Bintime C.struct_bintime
diff --git a/go/src/github.com/shirou/gopsutil/doc.go b/go/src/github.com/shirou/gopsutil/doc.go
new file mode 100644
index 0000000..6a65fe2
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/doc.go
@@ -0,0 +1 @@
+package gopsutil
diff --git a/go/src/github.com/shirou/gopsutil/docker/docker.go b/go/src/github.com/shirou/gopsutil/docker/docker.go
new file mode 100644
index 0000000..1bd3bdc
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/docker/docker.go
@@ -0,0 +1,49 @@
+package docker
+
+import "errors"
+
+var ErrDockerNotAvailable = errors.New("docker not available")
+var ErrCgroupNotAvailable = errors.New("cgroup not available")
+
+type CgroupMemStat struct {
+	ContainerID             string `json:"containerID"`
+	Cache                   uint64 `json:"cache"`
+	RSS                     uint64 `json:"rss"`
+	RSSHuge                 uint64 `json:"rssHuge"`
+	MappedFile              uint64 `json:"mappedFile"`
+	Pgpgin                  uint64 `json:"pgpgin"`
+	Pgpgout                 uint64 `json:"pgpgout"`
+	Pgfault                 uint64 `json:"pgfault"`
+	Pgmajfault              uint64 `json:"pgmajfault"`
+	InactiveAnon            uint64 `json:"inactiveAnon"`
+	ActiveAnon              uint64 `json:"activeAnon"`
+	InactiveFile            uint64 `json:"inactiveFile"`
+	ActiveFile              uint64 `json:"activeFile"`
+	Unevictable             uint64 `json:"unevictable"`
+	HierarchicalMemoryLimit uint64 `json:"hierarchicalMemoryLimit"`
+	TotalCache              uint64 `json:"totalCache"`
+	TotalRSS                uint64 `json:"totalRss"`
+	TotalRSSHuge            uint64 `json:"totalRssHuge"`
+	TotalMappedFile         uint64 `json:"totalMappedFile"`
+	TotalPgpgIn             uint64 `json:"totalPgpgin"`
+	TotalPgpgOut            uint64 `json:"totalPgpgout"`
+	TotalPgFault            uint64 `json:"totalPgfault"`
+	TotalPgMajFault         uint64 `json:"totalPgmajfault"`
+	TotalInactiveAnon       uint64 `json:"totalInactiveAnon"`
+	TotalActiveAnon         uint64 `json:"totalActiveAnon"`
+	TotalInactiveFile       uint64 `json:"totalInactiveFile"`
+	TotalActiveFile         uint64 `json:"totalActiveFile"`
+	TotalUnevictable        uint64 `json:"totalUnevictable"`
+	MemUsageInBytes         uint64 `json:"memUsageInBytes"`
+	MemMaxUsageInBytes      uint64 `json:"memMaxUsageInBytes"`
+	MemLimitInBytes         uint64 `json:"memoryLimitInBbytes"`
+	MemFailCnt              uint64 `json:"memoryFailcnt"`
+}
+
+type CgroupDockerStat struct {
+	ContainerID string `json:"containerID"`
+	Name        string `json:"name"`
+	Image       string `json:"image"`
+	Status      string `json:"status"`
+	Running     bool   `json:"running"`
+}
diff --git a/go/src/github.com/shirou/gopsutil/docker/docker_linux.go b/go/src/github.com/shirou/gopsutil/docker/docker_linux.go
new file mode 100644
index 0000000..2501c16
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/docker/docker_linux.go
@@ -0,0 +1,254 @@
+// +build linux
+
+package docker
+
+import (
+	"encoding/json"
+	"fmt"
+	"os"
+	"os/exec"
+	"path"
+	"strconv"
+	"strings"
+
+	cpu "github.com/shirou/gopsutil/cpu"
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+// GetDockerStat returns a list of Docker basic stats.
+// This requires certain permission.
+func GetDockerStat() ([]CgroupDockerStat, error) {
+	path, err := exec.LookPath("docker")
+	if err != nil {
+		return nil, ErrDockerNotAvailable
+	}
+
+	out, err := exec.Command(path, "ps", "-a", "--no-trunc", "--format", "{{.ID}}|{{.Image}}|{{.Names}}|{{.Status}}").Output()
+	if err != nil {
+		return []CgroupDockerStat{}, err
+	}
+	lines := strings.Split(string(out), "\n")
+	ret := make([]CgroupDockerStat, 0, len(lines))
+
+	for _, l := range lines {
+		if l == "" {
+			continue
+		}
+		cols := strings.Split(l, "|")
+		if len(cols) != 4 {
+			continue
+		}
+		names := strings.Split(cols[2], ",")
+		stat := CgroupDockerStat{
+			ContainerID: cols[0],
+			Name:        names[0],
+			Image:       cols[1],
+			Status:      cols[3],
+			Running:     strings.Contains(cols[3], "Up"),
+		}
+		ret = append(ret, stat)
+	}
+
+	return ret, nil
+}
+
+func (c CgroupDockerStat) String() string {
+	s, _ := json.Marshal(c)
+	return string(s)
+}
+
+// GetDockerIDList returnes a list of DockerID.
+// This requires certain permission.
+func GetDockerIDList() ([]string, error) {
+	path, err := exec.LookPath("docker")
+	if err != nil {
+		return nil, ErrDockerNotAvailable
+	}
+
+	out, err := exec.Command(path, "ps", "-q", "--no-trunc").Output()
+	if err != nil {
+		return []string{}, err
+	}
+	lines := strings.Split(string(out), "\n")
+	ret := make([]string, 0, len(lines))
+
+	for _, l := range lines {
+		if l == "" {
+			continue
+		}
+		ret = append(ret, l)
+	}
+
+	return ret, nil
+}
+
+// CgroupCPU returnes specified cgroup id CPU status.
+// containerID is same as docker id if you use docker.
+// If you use container via systemd.slice, you could use
+// containerID = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/
+func CgroupCPU(containerID string, base string) (*cpu.TimesStat, error) {
+	statfile := getCgroupFilePath(containerID, base, "cpuacct", "cpuacct.stat")
+	lines, err := common.ReadLines(statfile)
+	if err != nil {
+		return nil, err
+	}
+	// empty containerID means all cgroup
+	if len(containerID) == 0 {
+		containerID = "all"
+	}
+	ret := &cpu.TimesStat{CPU: containerID}
+	for _, line := range lines {
+		fields := strings.Split(line, " ")
+		if fields[0] == "user" {
+			user, err := strconv.ParseFloat(fields[1], 64)
+			if err == nil {
+				ret.User = float64(user)
+			}
+		}
+		if fields[0] == "system" {
+			system, err := strconv.ParseFloat(fields[1], 64)
+			if err == nil {
+				ret.System = float64(system)
+			}
+		}
+	}
+
+	return ret, nil
+}
+
+func CgroupCPUDocker(containerid string) (*cpu.TimesStat, error) {
+	return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker"))
+}
+
+func CgroupMem(containerID string, base string) (*CgroupMemStat, error) {
+	statfile := getCgroupFilePath(containerID, base, "memory", "memory.stat")
+
+	// empty containerID means all cgroup
+	if len(containerID) == 0 {
+		containerID = "all"
+	}
+	lines, err := common.ReadLines(statfile)
+	if err != nil {
+		return nil, err
+	}
+	ret := &CgroupMemStat{ContainerID: containerID}
+	for _, line := range lines {
+		fields := strings.Split(line, " ")
+		v, err := strconv.ParseUint(fields[1], 10, 64)
+		if err != nil {
+			continue
+		}
+		switch fields[0] {
+		case "cache":
+			ret.Cache = v
+		case "rss":
+			ret.RSS = v
+		case "rssHuge":
+			ret.RSSHuge = v
+		case "mappedFile":
+			ret.MappedFile = v
+		case "pgpgin":
+			ret.Pgpgin = v
+		case "pgpgout":
+			ret.Pgpgout = v
+		case "pgfault":
+			ret.Pgfault = v
+		case "pgmajfault":
+			ret.Pgmajfault = v
+		case "inactiveAnon":
+			ret.InactiveAnon = v
+		case "activeAnon":
+			ret.ActiveAnon = v
+		case "inactiveFile":
+			ret.InactiveFile = v
+		case "activeFile":
+			ret.ActiveFile = v
+		case "unevictable":
+			ret.Unevictable = v
+		case "hierarchicalMemoryLimit":
+			ret.HierarchicalMemoryLimit = v
+		case "totalCache":
+			ret.TotalCache = v
+		case "totalRss":
+			ret.TotalRSS = v
+		case "totalRssHuge":
+			ret.TotalRSSHuge = v
+		case "totalMappedFile":
+			ret.TotalMappedFile = v
+		case "totalPgpgin":
+			ret.TotalPgpgIn = v
+		case "totalPgpgout":
+			ret.TotalPgpgOut = v
+		case "totalPgfault":
+			ret.TotalPgFault = v
+		case "totalPgmajfault":
+			ret.TotalPgMajFault = v
+		case "totalInactiveAnon":
+			ret.TotalInactiveAnon = v
+		case "totalActiveAnon":
+			ret.TotalActiveAnon = v
+		case "totalInactiveFile":
+			ret.TotalInactiveFile = v
+		case "totalActiveFile":
+			ret.TotalActiveFile = v
+		case "totalUnevictable":
+			ret.TotalUnevictable = v
+		}
+	}
+
+	r, err := getCgroupMemFile(containerID, base, "memory.usage_in_bytes")
+	if err == nil {
+		ret.MemUsageInBytes = r
+	}
+	r, err = getCgroupMemFile(containerID, base, "memory.max_usage_in_bytes")
+	if err == nil {
+		ret.MemMaxUsageInBytes = r
+	}
+	r, err = getCgroupMemFile(containerID, base, "memoryLimitInBbytes")
+	if err == nil {
+		ret.MemLimitInBytes = r
+	}
+	r, err = getCgroupMemFile(containerID, base, "memoryFailcnt")
+	if err == nil {
+		ret.MemFailCnt = r
+	}
+
+	return ret, nil
+}
+
+func CgroupMemDocker(containerID string) (*CgroupMemStat, error) {
+	return CgroupMem(containerID, common.HostSys("fs/cgroup/memory/docker"))
+}
+
+func (m CgroupMemStat) String() string {
+	s, _ := json.Marshal(m)
+	return string(s)
+}
+
+// getCgroupFilePath constructs file path to get targetted stats file.
+func getCgroupFilePath(containerID, base, target, file string) string {
+	if len(base) == 0 {
+		base = common.HostSys(fmt.Sprintf("fs/cgroup/%s/docker", target))
+	}
+	statfile := path.Join(base, containerID, file)
+
+	if _, err := os.Stat(statfile); os.IsNotExist(err) {
+		statfile = path.Join(
+			common.HostSys(fmt.Sprintf("fs/cgroup/%s/system.slice", target)), "docker-"+containerID+".scope", file)
+	}
+
+	return statfile
+}
+
+// getCgroupMemFile reads a cgroup file and return the contents as uint64.
+func getCgroupMemFile(containerID, base, file string) (uint64, error) {
+	statfile := getCgroupFilePath(containerID, base, "memory", file)
+	lines, err := common.ReadLines(statfile)
+	if err != nil {
+		return 0, err
+	}
+	if len(lines) != 1 {
+		return 0, fmt.Errorf("wrong format file: %s", statfile)
+	}
+	return strconv.ParseUint(lines[0], 10, 64)
+}
diff --git a/go/src/github.com/shirou/gopsutil/docker/docker_linux_test.go b/go/src/github.com/shirou/gopsutil/docker/docker_linux_test.go
new file mode 100644
index 0000000..bd5b8c7
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/docker/docker_linux_test.go
@@ -0,0 +1,82 @@
+// +build linux
+
+package docker
+
+import "testing"
+
+func TestGetDockerIDList(t *testing.T) {
+	// If there is not docker environment, this test always fail.
+	// not tested here
+	/*
+		_, err := GetDockerIDList()
+		if err != nil {
+			t.Errorf("error %v", err)
+		}
+	*/
+}
+
+func TestGetDockerStat(t *testing.T) {
+	// If there is not docker environment, this test always fail.
+	// not tested here
+
+	/*
+		ret, err := GetDockerStat()
+		if err != nil {
+			t.Errorf("error %v", err)
+		}
+		if len(ret) == 0 {
+			t.Errorf("ret is empty")
+		}
+		empty := CgroupDockerStat{}
+		for _, v := range ret {
+			if empty == v {
+				t.Errorf("empty CgroupDockerStat")
+			}
+			if v.ContainerID == "" {
+				t.Errorf("Could not get container id")
+			}
+		}
+	*/
+}
+
+func TestCgroupCPU(t *testing.T) {
+	v, _ := GetDockerIDList()
+	for _, id := range v {
+		v, err := CgroupCPUDocker(id)
+		if err != nil {
+			t.Errorf("error %v", err)
+		}
+		if v.CPU == "" {
+			t.Errorf("could not get CgroupCPU %v", v)
+		}
+
+	}
+}
+
+func TestCgroupCPUInvalidId(t *testing.T) {
+	_, err := CgroupCPUDocker("bad id")
+	if err == nil {
+		t.Error("Expected path does not exist error")
+	}
+}
+
+func TestCgroupMem(t *testing.T) {
+	v, _ := GetDockerIDList()
+	for _, id := range v {
+		v, err := CgroupMemDocker(id)
+		if err != nil {
+			t.Errorf("error %v", err)
+		}
+		empty := &CgroupMemStat{}
+		if v == empty {
+			t.Errorf("Could not CgroupMemStat %v", v)
+		}
+	}
+}
+
+func TestCgroupMemInvalidId(t *testing.T) {
+	_, err := CgroupMemDocker("bad id")
+	if err == nil {
+		t.Error("Expected path does not exist error")
+	}
+}
diff --git a/go/src/github.com/shirou/gopsutil/docker/docker_notlinux.go b/go/src/github.com/shirou/gopsutil/docker/docker_notlinux.go
new file mode 100644
index 0000000..f78fb33
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/docker/docker_notlinux.go
@@ -0,0 +1,47 @@
+// +build !linux
+
+package docker
+
+import (
+	"encoding/json"
+
+	"github.com/shirou/gopsutil/cpu"
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+// GetDockerStat returns a list of Docker basic stats.
+// This requires certain permission.
+func GetDockerStat() ([]CgroupDockerStat, error) {
+	return nil, ErrDockerNotAvailable
+}
+
+// GetDockerIDList returnes a list of DockerID.
+// This requires certain permission.
+func GetDockerIDList() ([]string, error) {
+	return nil, ErrDockerNotAvailable
+}
+
+// CgroupCPU returnes specified cgroup id CPU status.
+// containerid is same as docker id if you use docker.
+// If you use container via systemd.slice, you could use
+// containerid = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/
+func CgroupCPU(containerid string, base string) (*cpu.TimesStat, error) {
+	return nil, ErrCgroupNotAvailable
+}
+
+func CgroupCPUDocker(containerid string) (*cpu.TimesStat, error) {
+	return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker"))
+}
+
+func CgroupMem(containerid string, base string) (*CgroupMemStat, error) {
+	return nil, ErrCgroupNotAvailable
+}
+
+func CgroupMemDocker(containerid string) (*CgroupMemStat, error) {
+	return CgroupMem(containerid, common.HostSys("fs/cgroup/memory/docker"))
+}
+
+func (m CgroupMemStat) String() string {
+	s, _ := json.Marshal(m)
+	return string(s)
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host.go b/go/src/github.com/shirou/gopsutil/host/host.go
new file mode 100644
index 0000000..150eb60
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host.go
@@ -0,0 +1,38 @@
+package host
+
+import (
+	"encoding/json"
+)
+
+// A HostInfoStat describes the host status.
+// This is not in the psutil but it useful.
+type InfoStat struct {
+	Hostname             string `json:"hostname"`
+	Uptime               uint64 `json:"uptime"`
+	BootTime             uint64 `json:"bootTime"`
+	Procs                uint64 `json:"procs"`           // number of processes
+	OS                   string `json:"os"`              // ex: freebsd, linux
+	Platform             string `json:"platform"`        // ex: ubuntu, linuxmint
+	PlatformFamily       string `json:"platformFamily"` // ex: debian, rhel
+	PlatformVersion      string `json:"platformVersion"`
+	VirtualizationSystem string `json:"virtualizationSystem"`
+	VirtualizationRole   string `json:"virtualizationRole"` // guest or host
+
+}
+
+type UserStat struct {
+	User     string `json:"user"`
+	Terminal string `json:"terminal"`
+	Host     string `json:"host"`
+	Started  int    `json:"started"`
+}
+
+func (h InfoStat) String() string {
+	s, _ := json.Marshal(h)
+	return string(s)
+}
+
+func (u UserStat) String() string {
+	s, _ := json.Marshal(u)
+	return string(s)
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_darwin.go b/go/src/github.com/shirou/gopsutil/host/host_darwin.go
new file mode 100644
index 0000000..f4a8c36
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_darwin.go
@@ -0,0 +1,152 @@
+// +build darwin
+
+package host
+
+import (
+	"bytes"
+	"encoding/binary"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+	"unsafe"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+// from utmpx.h
+const USER_PROCESS = 7
+
+func Info() (*InfoStat, error) {
+	ret := &InfoStat{
+		OS:             runtime.GOOS,
+		PlatformFamily: "darwin",
+	}
+
+	hostname, err := os.Hostname()
+	if err == nil {
+		ret.Hostname = hostname
+	}
+
+	platform, family, version, err := PlatformInformation()
+	if err == nil {
+		ret.Platform = platform
+		ret.PlatformFamily = family
+		ret.PlatformVersion = version
+	}
+	system, role, err := Virtualization()
+	if err == nil {
+		ret.VirtualizationSystem = system
+		ret.VirtualizationRole = role
+	}
+
+	boot, err := BootTime()
+	if err == nil {
+		ret.BootTime = boot
+		ret.Uptime = uptime(boot)
+	}
+
+	return ret, nil
+}
+
+func BootTime() (uint64, error) {
+	values, err := common.DoSysctrl("kern.boottime")
+	if err != nil {
+		return 0, err
+	}
+	// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
+	v := strings.Replace(values[2], ",", "", 1)
+	boottime, err := strconv.ParseInt(v, 10, 64)
+	if err != nil {
+		return 0, err
+	}
+
+	return uint64(boottime), nil
+}
+
+func uptime(boot uint64) uint64 {
+	return uint64(time.Now().Unix()) - boot
+}
+
+func Uptime() (uint64, error) {
+	boot, err := BootTime()
+	if err != nil {
+		return 0, err
+	}
+	return uptime(boot), nil
+}
+
+func Users() ([]UserStat, error) {
+	utmpfile := "/var/run/utmpx"
+	var ret []UserStat
+
+	file, err := os.Open(utmpfile)
+	if err != nil {
+		return ret, err
+	}
+
+	buf, err := ioutil.ReadAll(file)
+	if err != nil {
+		return ret, err
+	}
+
+	u := Utmpx{}
+	entrySize := int(unsafe.Sizeof(u))
+	count := len(buf) / entrySize
+
+	for i := 0; i < count; i++ {
+		b := buf[i*entrySize : i*entrySize+entrySize]
+
+		var u Utmpx
+		br := bytes.NewReader(b)
+		err := binary.Read(br, binary.LittleEndian, &u)
+		if err != nil {
+			continue
+		}
+		if u.Type != USER_PROCESS {
+			continue
+		}
+		user := UserStat{
+			User:     common.IntToString(u.User[:]),
+			Terminal: common.IntToString(u.Line[:]),
+			Host:     common.IntToString(u.Host[:]),
+			Started:  int(u.Tv.Sec),
+		}
+		ret = append(ret, user)
+	}
+
+	return ret, nil
+
+}
+
+func PlatformInformation() (string, string, string, error) {
+	platform := ""
+	family := ""
+	version := ""
+
+	uname, err := exec.LookPath("uname")
+	if err != nil {
+		return "", "", "", err
+	}
+	out, err := exec.Command(uname, "-s").Output()
+	if err == nil {
+		platform = strings.ToLower(strings.TrimSpace(string(out)))
+	}
+
+	out, err = exec.Command(uname, "-r").Output()
+	if err == nil {
+		version = strings.ToLower(strings.TrimSpace(string(out)))
+	}
+
+	return platform, family, version, nil
+}
+
+func Virtualization() (string, string, error) {
+	system := ""
+	role := ""
+
+	return system, role, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_darwin_amd64.go b/go/src/github.com/shirou/gopsutil/host/host_darwin_amd64.go
new file mode 100644
index 0000000..c3596f9
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_darwin_amd64.go
@@ -0,0 +1,19 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_darwin.go
+
+package host
+
+type Utmpx struct {
+	User      [256]int8
+	ID        [4]int8
+	Line      [32]int8
+	Pid       int32
+	Type      int16
+	Pad_cgo_0 [6]byte
+	Tv        Timeval
+	Host      [256]int8
+	Pad       [16]uint32
+}
+type Timeval struct {
+	Sec int32
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_freebsd.go b/go/src/github.com/shirou/gopsutil/host/host_freebsd.go
new file mode 100644
index 0000000..aeb1b45
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_freebsd.go
@@ -0,0 +1,194 @@
+// +build freebsd
+
+package host
+
+import (
+	"bytes"
+	"encoding/binary"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+	"unsafe"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+const (
+	UTNameSize = 16 /* see MAXLOGNAME in <sys/param.h> */
+	UTLineSize = 8
+	UTHostSize = 16
+)
+
+func Info() (*InfoStat, error) {
+	ret := &InfoStat{
+		OS:             runtime.GOOS,
+		PlatformFamily: "freebsd",
+	}
+
+	hostname, err := os.Hostname()
+	if err == nil {
+		ret.Hostname = hostname
+	}
+
+	platform, family, version, err := PlatformInformation()
+	if err == nil {
+		ret.Platform = platform
+		ret.PlatformFamily = family
+		ret.PlatformVersion = version
+	}
+	system, role, err := Virtualization()
+	if err == nil {
+		ret.VirtualizationSystem = system
+		ret.VirtualizationRole = role
+	}
+
+	boot, err := BootTime()
+	if err == nil {
+		ret.BootTime = boot
+		ret.Uptime = uptime(boot)
+	}
+
+	return ret, nil
+}
+
+func BootTime() (uint64, error) {
+	values, err := common.DoSysctrl("kern.boottime")
+	if err != nil {
+		return 0, err
+	}
+	// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
+	v := strings.Replace(values[2], ",", "", 1)
+
+	boottime, err := strconv.ParseUint(v, 10, 64)
+	if err != nil {
+		return 0, err
+	}
+
+	return boottime, nil
+}
+
+func uptime(boot uint64) uint64 {
+	return uint64(time.Now().Unix()) - boot
+}
+
+func Uptime() (uint64, error) {
+	boot, err := BootTime()
+	if err != nil {
+		return 0, err
+	}
+	return uptime(boot), nil
+}
+
+func Users() ([]UserStat, error) {
+	utmpfile := "/var/run/utx.active"
+	if !common.PathExists(utmpfile) {
+		utmpfile = "/var/run/utmp" // before 9.0
+		return getUsersFromUtmp(utmpfile)
+	}
+
+	var ret []UserStat
+	file, err := os.Open(utmpfile)
+	if err != nil {
+		return ret, err
+	}
+
+	buf, err := ioutil.ReadAll(file)
+	if err != nil {
+		return ret, err
+	}
+
+	entrySize := sizeOfUtmpx
+	count := len(buf) / entrySize
+
+	for i := 0; i < count; i++ {
+		b := buf[i*sizeOfUtmpx : (i+1)*sizeOfUtmpx]
+		var u Utmpx
+		br := bytes.NewReader(b)
+		err := binary.Read(br, binary.LittleEndian, &u)
+		if err != nil || u.Type != 4 {
+			continue
+		}
+		sec := (binary.LittleEndian.Uint32(u.Tv.Sec[:])) / 2 // TODO:
+		user := UserStat{
+			User:     common.IntToString(u.User[:]),
+			Terminal: common.IntToString(u.Line[:]),
+			Host:     common.IntToString(u.Host[:]),
+			Started:  int(sec),
+		}
+
+		ret = append(ret, user)
+	}
+
+	return ret, nil
+
+}
+
+func PlatformInformation() (string, string, string, error) {
+	platform := ""
+	family := ""
+	version := ""
+	uname, err := exec.LookPath("uname")
+	if err != nil {
+		return "", "", "", err
+	}
+
+	out, err := exec.Command(uname, "-s").Output()
+	if err == nil {
+		platform = strings.ToLower(strings.TrimSpace(string(out)))
+	}
+
+	out, err = exec.Command(uname, "-r").Output()
+	if err == nil {
+		version = strings.ToLower(strings.TrimSpace(string(out)))
+	}
+
+	return platform, family, version, nil
+}
+
+func Virtualization() (string, string, error) {
+	system := ""
+	role := ""
+
+	return system, role, nil
+}
+
+// before 9.0
+func getUsersFromUtmp(utmpfile string) ([]UserStat, error) {
+	var ret []UserStat
+	file, err := os.Open(utmpfile)
+	if err != nil {
+		return ret, err
+	}
+	buf, err := ioutil.ReadAll(file)
+	if err != nil {
+		return ret, err
+	}
+
+	u := Utmp{}
+	entrySize := int(unsafe.Sizeof(u))
+	count := len(buf) / entrySize
+
+	for i := 0; i < count; i++ {
+		b := buf[i*entrySize : i*entrySize+entrySize]
+		var u Utmp
+		br := bytes.NewReader(b)
+		err := binary.Read(br, binary.LittleEndian, &u)
+		if err != nil || u.Time == 0 {
+			continue
+		}
+		user := UserStat{
+			User:     common.IntToString(u.Name[:]),
+			Terminal: common.IntToString(u.Line[:]),
+			Host:     common.IntToString(u.Host[:]),
+			Started:  int(u.Time),
+		}
+
+		ret = append(ret, user)
+	}
+
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_freebsd_386.go b/go/src/github.com/shirou/gopsutil/host/host_freebsd_386.go
new file mode 100644
index 0000000..7f06d8f
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_freebsd_386.go
@@ -0,0 +1,43 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_freebsd.go
+
+package host
+
+const (
+	sizeofPtr      = 0x4
+	sizeofShort    = 0x2
+	sizeofInt      = 0x4
+	sizeofLong     = 0x4
+	sizeofLongLong = 0x8
+	sizeOfUtmpx    = 197 // TODO why should 197
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int32
+	_C_long_long int64
+)
+
+type Utmp struct {
+	Line [8]int8
+	Name [16]int8
+	Host [16]int8
+	Time int32
+}
+
+type Utmpx struct {
+	Type int16
+	Tv   Timeval
+	Id   [8]int8
+	Pid  int32
+	User [32]int8
+	Line [16]int8
+	Host [125]int8
+	//      X__ut_spare     [64]int8
+}
+
+type Timeval struct {
+	Sec  [4]byte
+	Usec [3]byte
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_freebsd_amd64.go b/go/src/github.com/shirou/gopsutil/host/host_freebsd_amd64.go
new file mode 100644
index 0000000..3f015f0
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_freebsd_amd64.go
@@ -0,0 +1,44 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_freebsd.go
+
+package host
+
+const (
+	sizeofPtr      = 0x8
+	sizeofShort    = 0x2
+	sizeofInt      = 0x4
+	sizeofLong     = 0x8
+	sizeofLongLong = 0x8
+	sizeOfUtmpx    = 197 // TODO: why should 197, not 0x118
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int64
+	_C_long_long int64
+)
+
+type Utmp struct {
+	Line [8]int8
+	Name [16]int8
+	Host [16]int8
+	Time int32
+}
+
+type Utmpx struct {
+	Type int16
+	Tv   Timeval
+	Id   [8]int8
+	Pid  int32
+	User [32]int8
+	Line [16]int8
+	Host [125]int8
+	//      Host [128]int8
+	//      X__ut_spare [64]int8
+}
+
+type Timeval struct {
+	Sec  [4]byte
+	Usec [3]byte
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_linux.go b/go/src/github.com/shirou/gopsutil/host/host_linux.go
new file mode 100644
index 0000000..14d0935
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_linux.go
@@ -0,0 +1,428 @@
+// +build linux
+
+package host
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+type LSB struct {
+	ID          string
+	Release     string
+	Codename    string
+	Description string
+}
+
+// from utmp.h
+const USER_PROCESS = 7
+
+func Info() (*InfoStat, error) {
+	ret := &InfoStat{
+		OS: runtime.GOOS,
+	}
+
+	hostname, err := os.Hostname()
+	if err == nil {
+		ret.Hostname = hostname
+	}
+
+	platform, family, version, err := PlatformInformation()
+	if err == nil {
+		ret.Platform = platform
+		ret.PlatformFamily = family
+		ret.PlatformVersion = version
+	}
+	system, role, err := Virtualization()
+	if err == nil {
+		ret.VirtualizationSystem = system
+		ret.VirtualizationRole = role
+	}
+	boot, err := BootTime()
+	if err == nil {
+		ret.BootTime = boot
+		ret.Uptime = uptime(boot)
+	}
+
+	return ret, nil
+}
+
+// BootTime returns the system boot time expressed in seconds since the epoch.
+func BootTime() (uint64, error) {
+	filename := common.HostProc("stat")
+	lines, err := common.ReadLines(filename)
+	if err != nil {
+		return 0, err
+	}
+	for _, line := range lines {
+		if strings.HasPrefix(line, "btime") {
+			f := strings.Fields(line)
+			if len(f) != 2 {
+				return 0, fmt.Errorf("wrong btime format")
+			}
+			b, err := strconv.ParseInt(f[1], 10, 64)
+			if err != nil {
+				return 0, err
+			}
+			return uint64(b), nil
+		}
+	}
+
+	return 0, fmt.Errorf("could not find btime")
+}
+
+func uptime(boot uint64) uint64 {
+	return uint64(time.Now().Unix()) - boot
+}
+
+func Uptime() (uint64, error) {
+	boot, err := BootTime()
+	if err != nil {
+		return 0, err
+	}
+	return uptime(boot), nil
+}
+
+func Users() ([]UserStat, error) {
+	utmpfile := "/var/run/utmp"
+
+	file, err := os.Open(utmpfile)
+	if err != nil {
+		return nil, err
+	}
+
+	buf, err := ioutil.ReadAll(file)
+	if err != nil {
+		return nil, err
+	}
+
+	count := len(buf) / sizeOfUtmp
+
+	ret := make([]UserStat, 0, count)
+
+	for i := 0; i < count; i++ {
+		b := buf[i*sizeOfUtmp : (i+1)*sizeOfUtmp]
+
+		var u utmp
+		br := bytes.NewReader(b)
+		err := binary.Read(br, binary.LittleEndian, &u)
+		if err != nil {
+			continue
+		}
+		if u.Type != USER_PROCESS {
+			continue
+		}
+		user := UserStat{
+			User:     common.IntToString(u.User[:]),
+			Terminal: common.IntToString(u.Line[:]),
+			Host:     common.IntToString(u.Host[:]),
+			Started:  int(u.Tv.Sec),
+		}
+		ret = append(ret, user)
+	}
+
+	return ret, nil
+
+}
+
+func getLSB() (*LSB, error) {
+	ret := &LSB{}
+	if common.PathExists(common.HostEtc("lsb-release")) {
+		contents, err := common.ReadLines(common.HostEtc("lsb-release"))
+		if err != nil {
+			return ret, err // return empty
+		}
+		for _, line := range contents {
+			field := strings.Split(line, "=")
+			if len(field) < 2 {
+				continue
+			}
+			switch field[0] {
+			case "DISTRIB_ID":
+				ret.ID = field[1]
+			case "DISTRIB_RELEASE":
+				ret.Release = field[1]
+			case "DISTRIB_CODENAME":
+				ret.Codename = field[1]
+			case "DISTRIB_DESCRIPTION":
+				ret.Description = field[1]
+			}
+		}
+	} else if common.PathExists("/usr/bin/lsb_release") {
+		lsb_release, err := exec.LookPath("/usr/bin/lsb_release")
+		if err != nil {
+			return ret, err
+		}
+		out, err := exec.Command(lsb_release).Output()
+		if err != nil {
+			return ret, err
+		}
+		for _, line := range strings.Split(string(out), "\n") {
+			field := strings.Split(line, ":")
+			if len(field) < 2 {
+				continue
+			}
+			switch field[0] {
+			case "Distributor ID":
+				ret.ID = field[1]
+			case "Release":
+				ret.Release = field[1]
+			case "Codename":
+				ret.Codename = field[1]
+			case "Description":
+				ret.Description = field[1]
+			}
+		}
+
+	}
+
+	return ret, nil
+}
+
+func PlatformInformation() (platform string, family string, version string, err error) {
+
+	lsb, err := getLSB()
+	if err != nil {
+		lsb = &LSB{}
+	}
+
+	if common.PathExists(common.HostEtc("oracle-release")) {
+		platform = "oracle"
+		contents, err := common.ReadLines(common.HostEtc("oracle-release"))
+		if err == nil {
+			version = getRedhatishVersion(contents)
+		}
+
+	} else if common.PathExists(common.HostEtc("enterprise-release")) {
+		platform = "oracle"
+		contents, err := common.ReadLines(common.HostEtc("enterprise-release"))
+		if err == nil {
+			version = getRedhatishVersion(contents)
+		}
+	} else if common.PathExists(common.HostEtc("debian_version")) {
+		if lsb.ID == "Ubuntu" {
+			platform = "ubuntu"
+			version = lsb.Release
+		} else if lsb.ID == "LinuxMint" {
+			platform = "linuxmint"
+			version = lsb.Release
+		} else {
+			if common.PathExists("/usr/bin/raspi-config") {
+				platform = "raspbian"
+			} else {
+				platform = "debian"
+			}
+			contents, err := common.ReadLines(common.HostEtc("debian_version"))
+			if err == nil {
+				version = contents[0]
+			}
+		}
+	} else if common.PathExists(common.HostEtc("redhat-release")) {
+		contents, err := common.ReadLines(common.HostEtc("redhat-release"))
+		if err == nil {
+			version = getRedhatishVersion(contents)
+			platform = getRedhatishPlatform(contents)
+		}
+	} else if common.PathExists(common.HostEtc("system-release")) {
+		contents, err := common.ReadLines(common.HostEtc("system-release"))
+		if err == nil {
+			version = getRedhatishVersion(contents)
+			platform = getRedhatishPlatform(contents)
+		}
+	} else if common.PathExists(common.HostEtc("gentoo-release")) {
+		platform = "gentoo"
+		contents, err := common.ReadLines(common.HostEtc("gentoo-release"))
+		if err == nil {
+			version = getRedhatishVersion(contents)
+		}
+	} else if common.PathExists(common.HostEtc("SuSE-release")) {
+		contents, err := common.ReadLines(common.HostEtc("SuSE-release"))
+		if err == nil {
+			version = getSuseVersion(contents)
+			platform = getSusePlatform(contents)
+		}
+		// TODO: slackware detecion
+	} else if common.PathExists(common.HostEtc("arch-release")) {
+		platform = "arch"
+		version = lsb.Release
+	} else if lsb.ID == "RedHat" {
+		platform = "redhat"
+		version = lsb.Release
+	} else if lsb.ID == "Amazon" {
+		platform = "amazon"
+		version = lsb.Release
+	} else if lsb.ID == "ScientificSL" {
+		platform = "scientific"
+		version = lsb.Release
+	} else if lsb.ID == "XenServer" {
+		platform = "xenserver"
+		version = lsb.Release
+	} else if lsb.ID != "" {
+		platform = strings.ToLower(lsb.ID)
+		version = lsb.Release
+	}
+
+	switch platform {
+	case "debian", "ubuntu", "linuxmint", "raspbian":
+		family = "debian"
+	case "fedora":
+		family = "fedora"
+	case "oracle", "centos", "redhat", "scientific", "enterpriseenterprise", "amazon", "xenserver", "cloudlinux", "ibm_powerkvm":
+		family = "rhel"
+	case "suse", "opensuse":
+		family = "suse"
+	case "gentoo":
+		family = "gentoo"
+	case "slackware":
+		family = "slackware"
+	case "arch":
+		family = "arch"
+	case "exherbo":
+		family = "exherbo"
+	}
+
+	return platform, family, version, nil
+
+}
+
+func getRedhatishVersion(contents []string) string {
+	c := strings.ToLower(strings.Join(contents, ""))
+
+	if strings.Contains(c, "rawhide") {
+		return "rawhide"
+	}
+	if matches := regexp.MustCompile(`release (\d[\d.]*)`).FindStringSubmatch(c); matches != nil {
+		return matches[1]
+	}
+	return ""
+}
+
+func getRedhatishPlatform(contents []string) string {
+	c := strings.ToLower(strings.Join(contents, ""))
+
+	if strings.Contains(c, "red hat") {
+		return "redhat"
+	}
+	f := strings.Split(c, " ")
+
+	return f[0]
+}
+
+func getSuseVersion(contents []string) string {
+	version := ""
+	for _, line := range contents {
+		if matches := regexp.MustCompile(`VERSION = ([\d.]+)`).FindStringSubmatch(line); matches != nil {
+			version = matches[1]
+		} else if matches := regexp.MustCompile(`PATCHLEVEL = ([\d]+)`).FindStringSubmatch(line); matches != nil {
+			version = version + "." + matches[1]
+		}
+	}
+	return version
+}
+
+func getSusePlatform(contents []string) string {
+	c := strings.ToLower(strings.Join(contents, ""))
+	if strings.Contains(c, "opensuse") {
+		return "opensuse"
+	}
+	return "suse"
+}
+
+func Virtualization() (string, string, error) {
+	var system string
+	var role string
+
+	filename := common.HostProc("xen")
+	if common.PathExists(filename) {
+		system = "xen"
+		role = "guest" // assume guest
+
+		if common.PathExists(filename + "/capabilities") {
+			contents, err := common.ReadLines(filename + "/capabilities")
+			if err == nil {
+				if common.StringsHas(contents, "control_d") {
+					role = "host"
+				}
+			}
+		}
+	}
+
+	filename = common.HostProc("modules")
+	if common.PathExists(filename) {
+		contents, err := common.ReadLines(filename)
+		if err == nil {
+			if common.StringsContains(contents, "kvm") {
+				system = "kvm"
+				role = "host"
+			} else if common.StringsContains(contents, "vboxdrv") {
+				system = "vbox"
+				role = "host"
+			} else if common.StringsContains(contents, "vboxguest") {
+				system = "vbox"
+				role = "guest"
+			}
+		}
+	}
+
+	filename = common.HostProc("cpuinfo")
+	if common.PathExists(filename) {
+		contents, err := common.ReadLines(filename)
+		if err == nil {
+			if common.StringsHas(contents, "QEMU Virtual CPU") ||
+				common.StringsHas(contents, "Common KVM processor") ||
+				common.StringsHas(contents, "Common 32-bit KVM processor") {
+				system = "kvm"
+				role = "guest"
+			}
+		}
+	}
+
+	filename = common.HostProc()
+	if common.PathExists(filename + "/bc/0") {
+		system = "openvz"
+		role = "host"
+	} else if common.PathExists(filename + "/vz") {
+		system = "openvz"
+		role = "guest"
+	}
+
+	// not use dmidecode because it requires root
+	if common.PathExists(filename + "/self/status") {
+		contents, err := common.ReadLines(filename + "/self/status")
+		if err == nil {
+
+			if common.StringsHas(contents, "s_context:") ||
+				common.StringsHas(contents, "VxID:") {
+				system = "linux-vserver"
+			}
+			// TODO: guest or host
+		}
+	}
+
+	if common.PathExists(filename + "/self/cgroup") {
+		contents, err := common.ReadLines(filename + "/self/cgroup")
+		if err == nil {
+			if common.StringsHas(contents, "lxc") ||
+				common.StringsHas(contents, "docker") {
+				system = "lxc"
+				role = "guest"
+			} else if common.PathExists("/usr/bin/lxc-version") { // TODO: which
+				system = "lxc"
+				role = "host"
+			}
+		}
+	}
+
+	return system, role, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_linux_386.go b/go/src/github.com/shirou/gopsutil/host/host_linux_386.go
new file mode 100644
index 0000000..79b5cb5
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_linux_386.go
@@ -0,0 +1,45 @@
+// ATTENTION - FILE MANUAL FIXED AFTER CGO.
+// Fixed line: Tv		_Ctype_struct_timeval -> Tv		UtTv
+// Created by cgo -godefs, MANUAL FIXED
+// cgo -godefs types_linux.go
+
+package host
+
+const (
+	sizeofPtr      = 0x4
+	sizeofShort    = 0x2
+	sizeofInt      = 0x4
+	sizeofLong     = 0x4
+	sizeofLongLong = 0x8
+	sizeOfUtmp     = 0x180
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int32
+	_C_long_long int64
+)
+
+type utmp struct {
+	Type      int16
+	Pad_cgo_0 [2]byte
+	Pid       int32
+	Line      [32]int8
+	ID        [4]int8
+	User      [32]int8
+	Host      [256]int8
+	Exit      exit_status
+	Session   int32
+	Tv        UtTv
+	Addr_v6   [4]int32
+	X__unused [20]int8
+}
+type exit_status struct {
+	Termination int16
+	Exit        int16
+}
+type UtTv struct {
+	Sec  int32
+	Usec int32
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_linux_amd64.go b/go/src/github.com/shirou/gopsutil/host/host_linux_amd64.go
new file mode 100644
index 0000000..9a69652
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_linux_amd64.go
@@ -0,0 +1,48 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_linux.go
+
+package host
+
+const (
+	sizeofPtr      = 0x8
+	sizeofShort    = 0x2
+	sizeofInt      = 0x4
+	sizeofLong     = 0x8
+	sizeofLongLong = 0x8
+	sizeOfUtmp     = 0x180
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int64
+	_C_long_long int64
+)
+
+type utmp struct {
+	Type              int16
+	Pad_cgo_0         [2]byte
+	Pid               int32
+	Line              [32]int8
+	Id                [4]int8
+	User              [32]int8
+	Host              [256]int8
+	Exit              exit_status
+	Session           int32
+	Tv                _Ctype_struct___0
+	Addr_v6           [4]int32
+	X__glibc_reserved [20]int8
+}
+type exit_status struct {
+	Termination int16
+	Exit        int16
+}
+type timeval struct {
+	Sec  int64
+	Usec int64
+}
+
+type _Ctype_struct___0 struct {
+	Sec  int32
+	Usec int32
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_linux_arm.go b/go/src/github.com/shirou/gopsutil/host/host_linux_arm.go
new file mode 100644
index 0000000..e2cf448
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_linux_arm.go
@@ -0,0 +1,43 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_linux.go | sed "s/uint8/int8/g"
+
+package host
+
+const (
+	sizeofPtr      = 0x4
+	sizeofShort    = 0x2
+	sizeofInt      = 0x4
+	sizeofLong     = 0x4
+	sizeofLongLong = 0x8
+	sizeOfUtmp     = 0x180
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int32
+	_C_long_long int64
+)
+
+type utmp struct {
+	Type              int16
+	Pad_cgo_0         [2]byte
+	Pid               int32
+	Line              [32]int8
+	Id                [4]int8
+	User              [32]int8
+	Host              [256]int8
+	Exit              exit_status
+	Session           int32
+	Tv                timeval
+	Addr_v6           [4]int32
+	X__glibc_reserved [20]int8
+}
+type exit_status struct {
+	Termination int16
+	Exit        int16
+}
+type timeval struct {
+	Sec  int32
+	Usec int32
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_linux_arm64.go b/go/src/github.com/shirou/gopsutil/host/host_linux_arm64.go
new file mode 100644
index 0000000..37dbe5c
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_linux_arm64.go
@@ -0,0 +1,43 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_linux.go
+
+package host
+
+const (
+	sizeofPtr      = 0x8
+	sizeofShort    = 0x2
+	sizeofInt      = 0x4
+	sizeofLong     = 0x8
+	sizeofLongLong = 0x8
+	sizeOfUtmp     = 0x180
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int64
+	_C_long_long int64
+)
+
+type utmp struct {
+	Type              int16
+	Pad_cgo_0         [2]byte
+	Pid               int32
+	Line              [32]int8
+	Id                [4]int8
+	User              [32]int8
+	Host              [256]int8
+	Exit              exit_status
+	Session           int32
+	Tv                timeval
+	Addr_v6           [4]int32
+	X__glibc_reserved [20]int8
+}
+type exit_status struct {
+	Termination int16
+	Exit        int16
+}
+type timeval struct {
+	Sec  int64
+	Usec int64
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_linux_ppc64le.go b/go/src/github.com/shirou/gopsutil/host/host_linux_ppc64le.go
new file mode 100644
index 0000000..37dbe5c
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_linux_ppc64le.go
@@ -0,0 +1,43 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_linux.go
+
+package host
+
+const (
+	sizeofPtr      = 0x8
+	sizeofShort    = 0x2
+	sizeofInt      = 0x4
+	sizeofLong     = 0x8
+	sizeofLongLong = 0x8
+	sizeOfUtmp     = 0x180
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int64
+	_C_long_long int64
+)
+
+type utmp struct {
+	Type              int16
+	Pad_cgo_0         [2]byte
+	Pid               int32
+	Line              [32]int8
+	Id                [4]int8
+	User              [32]int8
+	Host              [256]int8
+	Exit              exit_status
+	Session           int32
+	Tv                timeval
+	Addr_v6           [4]int32
+	X__glibc_reserved [20]int8
+}
+type exit_status struct {
+	Termination int16
+	Exit        int16
+}
+type timeval struct {
+	Sec  int64
+	Usec int64
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_linux_test.go b/go/src/github.com/shirou/gopsutil/host/host_linux_test.go
new file mode 100644
index 0000000..7808eee
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_linux_test.go
@@ -0,0 +1,61 @@
+// +build linux
+
+package host
+
+import (
+	"testing"
+)
+
+func TestGetRedhatishVersion(t *testing.T) {
+	var ret string
+	c := []string{"Rawhide"}
+	ret = getRedhatishVersion(c)
+	if ret != "rawhide" {
+		t.Errorf("Could not get version rawhide: %v", ret)
+	}
+
+	c = []string{"Fedora release 15 (Lovelock)"}
+	ret = getRedhatishVersion(c)
+	if ret != "15" {
+		t.Errorf("Could not get version fedora: %v", ret)
+	}
+
+	c = []string{"Enterprise Linux Server release 5.5 (Carthage)"}
+	ret = getRedhatishVersion(c)
+	if ret != "5.5" {
+		t.Errorf("Could not get version redhat enterprise: %v", ret)
+	}
+
+	c = []string{""}
+	ret = getRedhatishVersion(c)
+	if ret != "" {
+		t.Errorf("Could not get version with no value: %v", ret)
+	}
+}
+
+func TestGetRedhatishPlatform(t *testing.T) {
+	var ret string
+	c := []string{"red hat"}
+	ret = getRedhatishPlatform(c)
+	if ret != "redhat" {
+		t.Errorf("Could not get platform redhat: %v", ret)
+	}
+
+	c = []string{"Fedora release 15 (Lovelock)"}
+	ret = getRedhatishPlatform(c)
+	if ret != "fedora" {
+		t.Errorf("Could not get platform fedora: %v", ret)
+	}
+
+	c = []string{"Enterprise Linux Server release 5.5 (Carthage)"}
+	ret = getRedhatishPlatform(c)
+	if ret != "enterprise" {
+		t.Errorf("Could not get platform redhat enterprise: %v", ret)
+	}
+
+	c = []string{""}
+	ret = getRedhatishPlatform(c)
+	if ret != "" {
+		t.Errorf("Could not get platform with no value: %v", ret)
+	}
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_test.go b/go/src/github.com/shirou/gopsutil/host/host_test.go
new file mode 100644
index 0000000..2bf395c
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_test.go
@@ -0,0 +1,71 @@
+package host
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestHostInfo(t *testing.T) {
+	v, err := Info()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	empty := &InfoStat{}
+	if v == empty {
+		t.Errorf("Could not get hostinfo %v", v)
+	}
+}
+
+func TestBoot_time(t *testing.T) {
+	v, err := BootTime()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	if v == 0 {
+		t.Errorf("Could not get boot time %v", v)
+	}
+}
+
+func TestUsers(t *testing.T) {
+	v, err := Users()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	empty := UserStat{}
+	if len(v) == 0 {
+		t.Errorf("Users is empty")
+	}
+	for _, u := range v {
+		if u == empty {
+			t.Errorf("Could not Users %v", v)
+		}
+	}
+}
+
+func TestHostInfoStat_String(t *testing.T) {
+	v := InfoStat{
+		Hostname: "test",
+		Uptime:   3000,
+		Procs:    100,
+		OS:       "linux",
+		Platform: "ubuntu",
+		BootTime: 1447040000,
+	}
+	e := `{"hostname":"test","uptime":3000,"bootTime":1447040000,"procs":100,"os":"linux","platform":"ubuntu","platformFamily":"","platformVersion":"","virtualizationSystem":"","virtualizationRole":""}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("HostInfoStat string is invalid: %v", v)
+	}
+}
+
+func TestUserStat_String(t *testing.T) {
+	v := UserStat{
+		User:     "user",
+		Terminal: "term",
+		Host:     "host",
+		Started:  100,
+	}
+	e := `{"user":"user","terminal":"term","host":"host","started":100}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("UserStat string is invalid: %v", v)
+	}
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/host_windows.go b/go/src/github.com/shirou/gopsutil/host/host_windows.go
new file mode 100644
index 0000000..29f900c
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/host_windows.go
@@ -0,0 +1,135 @@
+// +build windows
+
+package host
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+	"strings"
+	"time"
+
+	"github.com/StackExchange/wmi"
+
+	"github.com/shirou/gopsutil/internal/common"
+	process "github.com/shirou/gopsutil/process"
+)
+
+var (
+	procGetSystemTimeAsFileTime = common.Modkernel32.NewProc("GetSystemTimeAsFileTime")
+	osInfo                      *Win32_OperatingSystem
+)
+
+type Win32_OperatingSystem struct {
+	Version        string
+	Caption        string
+	ProductType    uint32
+	BuildNumber    string
+	LastBootUpTime time.Time
+}
+
+func Info() (*InfoStat, error) {
+	ret := &InfoStat{
+		OS: runtime.GOOS,
+	}
+
+	hostname, err := os.Hostname()
+	if err == nil {
+		ret.Hostname = hostname
+	}
+
+	platform, family, version, err := PlatformInformation()
+	if err == nil {
+		ret.Platform = platform
+		ret.PlatformFamily = family
+		ret.PlatformVersion = version
+	} else {
+		return ret, err
+	}
+
+	boot, err := BootTime()
+	if err == nil {
+		ret.BootTime = boot
+		ret.Uptime = uptime(boot)
+	}
+
+	procs, err := process.Pids()
+	if err != nil {
+		return ret, err
+	}
+
+	ret.Procs = uint64(len(procs))
+
+	return ret, nil
+}
+
+func GetOSInfo() (Win32_OperatingSystem, error) {
+	var dst []Win32_OperatingSystem
+	q := wmi.CreateQuery(&dst, "")
+	err := wmi.Query(q, &dst)
+	if err != nil {
+		return Win32_OperatingSystem{}, err
+	}
+
+	osInfo = &dst[0]
+
+	return dst[0], nil
+}
+
+func BootTime() (uint64, error) {
+	if osInfo == nil {
+		_, err := GetOSInfo()
+		if err != nil {
+			return 0, err
+		}
+	}
+	now := time.Now()
+	t := osInfo.LastBootUpTime.Local()
+	return uint64(now.Sub(t).Seconds()), nil
+}
+
+func uptime(boot uint64) uint64 {
+	return uint64(time.Now().Unix()) - boot
+}
+
+func Uptime() (uint64, error) {
+	boot, err := BootTime()
+	if err != nil {
+		return 0, err
+	}
+	return uptime(boot), nil
+}
+
+func PlatformInformation() (platform string, family string, version string, err error) {
+	if osInfo == nil {
+		_, err = GetOSInfo()
+		if err != nil {
+			return
+		}
+	}
+
+	// Platform
+	platform = strings.Trim(osInfo.Caption, " ")
+
+	// PlatformFamily
+	switch osInfo.ProductType {
+	case 1:
+		family = "Standalone Workstation"
+	case 2:
+		family = "Server (Domain Controller)"
+	case 3:
+		family = "Server"
+	}
+
+	// Platform Version
+	version = fmt.Sprintf("%s Build %s", osInfo.Version, osInfo.BuildNumber)
+
+	return
+}
+
+func Users() ([]UserStat, error) {
+
+	var ret []UserStat
+
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/host/types_darwin.go b/go/src/github.com/shirou/gopsutil/host/types_darwin.go
new file mode 100644
index 0000000..b858227
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/types_darwin.go
@@ -0,0 +1,17 @@
+// +build ignore
+// plus hand editing about timeval
+
+/*
+Input to cgo -godefs.
+*/
+
+package host
+
+/*
+#include <sys/time.h>
+#include <utmpx.h>
+*/
+import "C"
+
+type Utmpx C.struct_utmpx
+type Timeval C.struct_timeval
diff --git a/go/src/github.com/shirou/gopsutil/host/types_freebsd.go b/go/src/github.com/shirou/gopsutil/host/types_freebsd.go
new file mode 100644
index 0000000..e70677f
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/types_freebsd.go
@@ -0,0 +1,44 @@
+// +build ignore
+
+/*
+Input to cgo -godefs.
+*/
+
+package host
+
+/*
+#define KERNEL
+#include <sys/types.h>
+#include <sys/time.h>
+#include <utmpx.h>
+
+enum {
+	sizeofPtr = sizeof(void*),
+};
+
+*/
+import "C"
+
+// Machine characteristics; for internal use.
+
+const (
+	sizeofPtr      = C.sizeofPtr
+	sizeofShort    = C.sizeof_short
+	sizeofInt      = C.sizeof_int
+	sizeofLong     = C.sizeof_long
+	sizeofLongLong = C.sizeof_longlong
+	sizeOfUtmpx    = C.sizeof_struct_utmpx
+)
+
+// Basic types
+
+type (
+	_C_short     C.short
+	_C_int       C.int
+	_C_long      C.long
+	_C_long_long C.longlong
+)
+
+type Utmp C.struct_utmp
+type Utmpx C.struct_utmpx
+type Timeval C.struct_timeval
diff --git a/go/src/github.com/shirou/gopsutil/host/types_linux.go b/go/src/github.com/shirou/gopsutil/host/types_linux.go
new file mode 100644
index 0000000..8adecb6
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/host/types_linux.go
@@ -0,0 +1,42 @@
+// +build ignore
+
+/*
+Input to cgo -godefs.
+*/
+
+package host
+
+/*
+#include <sys/types.h>
+#include <utmp.h>
+
+enum {
+       sizeofPtr = sizeof(void*),
+};
+
+*/
+import "C"
+
+// Machine characteristics; for internal use.
+
+const (
+	sizeofPtr      = C.sizeofPtr
+	sizeofShort    = C.sizeof_short
+	sizeofInt      = C.sizeof_int
+	sizeofLong     = C.sizeof_long
+	sizeofLongLong = C.sizeof_longlong
+	sizeOfUtmp     = C.sizeof_struct_utmp
+)
+
+// Basic types
+
+type (
+	_C_short     C.short
+	_C_int       C.int
+	_C_long      C.long
+	_C_long_long C.longlong
+)
+
+type utmp C.struct_utmp
+type exit_status C.struct_exit_status
+type timeval C.struct_timeval
diff --git a/go/src/github.com/shirou/gopsutil/internal/common/binary.go b/go/src/github.com/shirou/gopsutil/internal/common/binary.go
new file mode 100644
index 0000000..9b5dc55
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/internal/common/binary.go
@@ -0,0 +1,634 @@
+package common
+
+// 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.
+
+// Package binary implements simple translation between numbers and byte
+// sequences and encoding and decoding of varints.
+//
+// Numbers are translated by reading and writing fixed-size values.
+// A fixed-size value is either a fixed-size arithmetic
+// type (int8, uint8, int16, float32, complex64, ...)
+// or an array or struct containing only fixed-size values.
+//
+// The varint functions encode and decode single integer values using
+// a variable-length encoding; smaller values require fewer bytes.
+// For a specification, see
+// http://code.google.com/apis/protocolbuffers/docs/encoding.html.
+//
+// This package favors simplicity over efficiency. Clients that require
+// high-performance serialization, especially for large data structures,
+// should look at more advanced solutions such as the encoding/gob
+// package or protocol buffers.
+import (
+	"errors"
+	"io"
+	"math"
+	"reflect"
+)
+
+// A ByteOrder specifies how to convert byte sequences into
+// 16-, 32-, or 64-bit unsigned integers.
+type ByteOrder interface {
+	Uint16([]byte) uint16
+	Uint32([]byte) uint32
+	Uint64([]byte) uint64
+	PutUint16([]byte, uint16)
+	PutUint32([]byte, uint32)
+	PutUint64([]byte, uint64)
+	String() string
+}
+
+// LittleEndian is the little-endian implementation of ByteOrder.
+var LittleEndian littleEndian
+
+// BigEndian is the big-endian implementation of ByteOrder.
+var BigEndian bigEndian
+
+type littleEndian struct{}
+
+func (littleEndian) Uint16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 }
+
+func (littleEndian) PutUint16(b []byte, v uint16) {
+	b[0] = byte(v)
+	b[1] = byte(v >> 8)
+}
+
+func (littleEndian) Uint32(b []byte) uint32 {
+	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+}
+
+func (littleEndian) PutUint32(b []byte, v uint32) {
+	b[0] = byte(v)
+	b[1] = byte(v >> 8)
+	b[2] = byte(v >> 16)
+	b[3] = byte(v >> 24)
+}
+
+func (littleEndian) Uint64(b []byte) uint64 {
+	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
+		uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+}
+
+func (littleEndian) PutUint64(b []byte, v uint64) {
+	b[0] = byte(v)
+	b[1] = byte(v >> 8)
+	b[2] = byte(v >> 16)
+	b[3] = byte(v >> 24)
+	b[4] = byte(v >> 32)
+	b[5] = byte(v >> 40)
+	b[6] = byte(v >> 48)
+	b[7] = byte(v >> 56)
+}
+
+func (littleEndian) String() string { return "LittleEndian" }
+
+func (littleEndian) GoString() string { return "binary.LittleEndian" }
+
+type bigEndian struct{}
+
+func (bigEndian) Uint16(b []byte) uint16 { return uint16(b[1]) | uint16(b[0])<<8 }
+
+func (bigEndian) PutUint16(b []byte, v uint16) {
+	b[0] = byte(v >> 8)
+	b[1] = byte(v)
+}
+
+func (bigEndian) Uint32(b []byte) uint32 {
+	return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+}
+
+func (bigEndian) PutUint32(b []byte, v uint32) {
+	b[0] = byte(v >> 24)
+	b[1] = byte(v >> 16)
+	b[2] = byte(v >> 8)
+	b[3] = byte(v)
+}
+
+func (bigEndian) Uint64(b []byte) uint64 {
+	return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+}
+
+func (bigEndian) PutUint64(b []byte, v uint64) {
+	b[0] = byte(v >> 56)
+	b[1] = byte(v >> 48)
+	b[2] = byte(v >> 40)
+	b[3] = byte(v >> 32)
+	b[4] = byte(v >> 24)
+	b[5] = byte(v >> 16)
+	b[6] = byte(v >> 8)
+	b[7] = byte(v)
+}
+
+func (bigEndian) String() string { return "BigEndian" }
+
+func (bigEndian) GoString() string { return "binary.BigEndian" }
+
+// Read reads structured binary data from r into data.
+// Data must be a pointer to a fixed-size value or a slice
+// of fixed-size values.
+// Bytes read from r are decoded using the specified byte order
+// and written to successive fields of the data.
+// When reading into structs, the field data for fields with
+// blank (_) field names is skipped; i.e., blank field names
+// may be used for padding.
+// When reading into a struct, all non-blank fields must be exported.
+func Read(r io.Reader, order ByteOrder, data interface{}) error {
+	// Fast path for basic types and slices.
+	if n := intDataSize(data); n != 0 {
+		var b [8]byte
+		var bs []byte
+		if n > len(b) {
+			bs = make([]byte, n)
+		} else {
+			bs = b[:n]
+		}
+		if _, err := io.ReadFull(r, bs); err != nil {
+			return err
+		}
+		switch data := data.(type) {
+		case *int8:
+			*data = int8(b[0])
+		case *uint8:
+			*data = b[0]
+		case *int16:
+			*data = int16(order.Uint16(bs))
+		case *uint16:
+			*data = order.Uint16(bs)
+		case *int32:
+			*data = int32(order.Uint32(bs))
+		case *uint32:
+			*data = order.Uint32(bs)
+		case *int64:
+			*data = int64(order.Uint64(bs))
+		case *uint64:
+			*data = order.Uint64(bs)
+		case []int8:
+			for i, x := range bs { // Easier to loop over the input for 8-bit values.
+				data[i] = int8(x)
+			}
+		case []uint8:
+			copy(data, bs)
+		case []int16:
+			for i := range data {
+				data[i] = int16(order.Uint16(bs[2*i:]))
+			}
+		case []uint16:
+			for i := range data {
+				data[i] = order.Uint16(bs[2*i:])
+			}
+		case []int32:
+			for i := range data {
+				data[i] = int32(order.Uint32(bs[4*i:]))
+			}
+		case []uint32:
+			for i := range data {
+				data[i] = order.Uint32(bs[4*i:])
+			}
+		case []int64:
+			for i := range data {
+				data[i] = int64(order.Uint64(bs[8*i:]))
+			}
+		case []uint64:
+			for i := range data {
+				data[i] = order.Uint64(bs[8*i:])
+			}
+		}
+		return nil
+	}
+
+	// Fallback to reflect-based decoding.
+	v := reflect.ValueOf(data)
+	size := -1
+	switch v.Kind() {
+	case reflect.Ptr:
+		v = v.Elem()
+		size = dataSize(v)
+	case reflect.Slice:
+		size = dataSize(v)
+	}
+	if size < 0 {
+		return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String())
+	}
+	d := &decoder{order: order, buf: make([]byte, size)}
+	if _, err := io.ReadFull(r, d.buf); err != nil {
+		return err
+	}
+	d.value(v)
+	return nil
+}
+
+// Write writes the binary representation of data into w.
+// Data must be a fixed-size value or a slice of fixed-size
+// values, or a pointer to such data.
+// Bytes written to w are encoded using the specified byte order
+// and read from successive fields of the data.
+// When writing structs, zero values are written for fields
+// with blank (_) field names.
+func Write(w io.Writer, order ByteOrder, data interface{}) error {
+	// Fast path for basic types and slices.
+	if n := intDataSize(data); n != 0 {
+		var b [8]byte
+		var bs []byte
+		if n > len(b) {
+			bs = make([]byte, n)
+		} else {
+			bs = b[:n]
+		}
+		switch v := data.(type) {
+		case *int8:
+			bs = b[:1]
+			b[0] = byte(*v)
+		case int8:
+			bs = b[:1]
+			b[0] = byte(v)
+		case []int8:
+			for i, x := range v {
+				bs[i] = byte(x)
+			}
+		case *uint8:
+			bs = b[:1]
+			b[0] = *v
+		case uint8:
+			bs = b[:1]
+			b[0] = byte(v)
+		case []uint8:
+			bs = v
+		case *int16:
+			bs = b[:2]
+			order.PutUint16(bs, uint16(*v))
+		case int16:
+			bs = b[:2]
+			order.PutUint16(bs, uint16(v))
+		case []int16:
+			for i, x := range v {
+				order.PutUint16(bs[2*i:], uint16(x))
+			}
+		case *uint16:
+			bs = b[:2]
+			order.PutUint16(bs, *v)
+		case uint16:
+			bs = b[:2]
+			order.PutUint16(bs, v)
+		case []uint16:
+			for i, x := range v {
+				order.PutUint16(bs[2*i:], x)
+			}
+		case *int32:
+			bs = b[:4]
+			order.PutUint32(bs, uint32(*v))
+		case int32:
+			bs = b[:4]
+			order.PutUint32(bs, uint32(v))
+		case []int32:
+			for i, x := range v {
+				order.PutUint32(bs[4*i:], uint32(x))
+			}
+		case *uint32:
+			bs = b[:4]
+			order.PutUint32(bs, *v)
+		case uint32:
+			bs = b[:4]
+			order.PutUint32(bs, v)
+		case []uint32:
+			for i, x := range v {
+				order.PutUint32(bs[4*i:], x)
+			}
+		case *int64:
+			bs = b[:8]
+			order.PutUint64(bs, uint64(*v))
+		case int64:
+			bs = b[:8]
+			order.PutUint64(bs, uint64(v))
+		case []int64:
+			for i, x := range v {
+				order.PutUint64(bs[8*i:], uint64(x))
+			}
+		case *uint64:
+			bs = b[:8]
+			order.PutUint64(bs, *v)
+		case uint64:
+			bs = b[:8]
+			order.PutUint64(bs, v)
+		case []uint64:
+			for i, x := range v {
+				order.PutUint64(bs[8*i:], x)
+			}
+		}
+		_, err := w.Write(bs)
+		return err
+	}
+
+	// Fallback to reflect-based encoding.
+	v := reflect.Indirect(reflect.ValueOf(data))
+	size := dataSize(v)
+	if size < 0 {
+		return errors.New("binary.Write: invalid type " + reflect.TypeOf(data).String())
+	}
+	buf := make([]byte, size)
+	e := &encoder{order: order, buf: buf}
+	e.value(v)
+	_, err := w.Write(buf)
+	return err
+}
+
+// Size returns how many bytes Write would generate to encode the value v, which
+// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
+// If v is neither of these, Size returns -1.
+func Size(v interface{}) int {
+	return dataSize(reflect.Indirect(reflect.ValueOf(v)))
+}
+
+// dataSize returns the number of bytes the actual data represented by v occupies in memory.
+// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
+// it returns the length of the slice times the element size and does not count the memory
+// occupied by the header. If the type of v is not acceptable, dataSize returns -1.
+func dataSize(v reflect.Value) int {
+	if v.Kind() == reflect.Slice {
+		if s := sizeof(v.Type().Elem()); s >= 0 {
+			return s * v.Len()
+		}
+		return -1
+	}
+	return sizeof(v.Type())
+}
+
+// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
+func sizeof(t reflect.Type) int {
+	switch t.Kind() {
+	case reflect.Array:
+		if s := sizeof(t.Elem()); s >= 0 {
+			return s * t.Len()
+		}
+
+	case reflect.Struct:
+		sum := 0
+		for i, n := 0, t.NumField(); i < n; i++ {
+			s := sizeof(t.Field(i).Type)
+			if s < 0 {
+				return -1
+			}
+			sum += s
+		}
+		return sum
+
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+		reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Ptr:
+		return int(t.Size())
+	}
+
+	return -1
+}
+
+type coder struct {
+	order ByteOrder
+	buf   []byte
+}
+
+type decoder coder
+type encoder coder
+
+func (d *decoder) uint8() uint8 {
+	x := d.buf[0]
+	d.buf = d.buf[1:]
+	return x
+}
+
+func (e *encoder) uint8(x uint8) {
+	e.buf[0] = x
+	e.buf = e.buf[1:]
+}
+
+func (d *decoder) uint16() uint16 {
+	x := d.order.Uint16(d.buf[0:2])
+	d.buf = d.buf[2:]
+	return x
+}
+
+func (e *encoder) uint16(x uint16) {
+	e.order.PutUint16(e.buf[0:2], x)
+	e.buf = e.buf[2:]
+}
+
+func (d *decoder) uint32() uint32 {
+	x := d.order.Uint32(d.buf[0:4])
+	d.buf = d.buf[4:]
+	return x
+}
+
+func (e *encoder) uint32(x uint32) {
+	e.order.PutUint32(e.buf[0:4], x)
+	e.buf = e.buf[4:]
+}
+
+func (d *decoder) uint64() uint64 {
+	x := d.order.Uint64(d.buf[0:8])
+	d.buf = d.buf[8:]
+	return x
+}
+
+func (e *encoder) uint64(x uint64) {
+	e.order.PutUint64(e.buf[0:8], x)
+	e.buf = e.buf[8:]
+}
+
+func (d *decoder) int8() int8 { return int8(d.uint8()) }
+
+func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
+
+func (d *decoder) int16() int16 { return int16(d.uint16()) }
+
+func (e *encoder) int16(x int16) { e.uint16(uint16(x)) }
+
+func (d *decoder) int32() int32 { return int32(d.uint32()) }
+
+func (e *encoder) int32(x int32) { e.uint32(uint32(x)) }
+
+func (d *decoder) int64() int64 { return int64(d.uint64()) }
+
+func (e *encoder) int64(x int64) { e.uint64(uint64(x)) }
+
+func (d *decoder) value(v reflect.Value) {
+	switch v.Kind() {
+	case reflect.Array:
+		l := v.Len()
+		for i := 0; i < l; i++ {
+			d.value(v.Index(i))
+		}
+
+	case reflect.Struct:
+		t := v.Type()
+		l := v.NumField()
+		for i := 0; i < l; i++ {
+			// Note: Calling v.CanSet() below is an optimization.
+			// It would be sufficient to check the field name,
+			// but creating the StructField info for each field is
+			// costly (run "go test -bench=ReadStruct" and compare
+			// results when making changes to this code).
+			if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
+				d.value(v)
+			} else {
+				d.skip(v)
+			}
+		}
+
+	case reflect.Slice:
+		l := v.Len()
+		for i := 0; i < l; i++ {
+			d.value(v.Index(i))
+		}
+
+	case reflect.Int8:
+		v.SetInt(int64(d.int8()))
+	case reflect.Int16:
+		v.SetInt(int64(d.int16()))
+	case reflect.Int32:
+		v.SetInt(int64(d.int32()))
+	case reflect.Int64:
+		v.SetInt(d.int64())
+
+	case reflect.Uint8:
+		v.SetUint(uint64(d.uint8()))
+	case reflect.Uint16:
+		v.SetUint(uint64(d.uint16()))
+	case reflect.Uint32:
+		v.SetUint(uint64(d.uint32()))
+	case reflect.Uint64:
+		v.SetUint(d.uint64())
+
+	case reflect.Float32:
+		v.SetFloat(float64(math.Float32frombits(d.uint32())))
+	case reflect.Float64:
+		v.SetFloat(math.Float64frombits(d.uint64()))
+
+	case reflect.Complex64:
+		v.SetComplex(complex(
+			float64(math.Float32frombits(d.uint32())),
+			float64(math.Float32frombits(d.uint32())),
+		))
+	case reflect.Complex128:
+		v.SetComplex(complex(
+			math.Float64frombits(d.uint64()),
+			math.Float64frombits(d.uint64()),
+		))
+	}
+}
+
+func (e *encoder) value(v reflect.Value) {
+	switch v.Kind() {
+	case reflect.Array:
+		l := v.Len()
+		for i := 0; i < l; i++ {
+			e.value(v.Index(i))
+		}
+
+	case reflect.Struct:
+		t := v.Type()
+		l := v.NumField()
+		for i := 0; i < l; i++ {
+			// see comment for corresponding code in decoder.value()
+			if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
+				e.value(v)
+			} else {
+				e.skip(v)
+			}
+		}
+
+	case reflect.Slice:
+		l := v.Len()
+		for i := 0; i < l; i++ {
+			e.value(v.Index(i))
+		}
+
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		switch v.Type().Kind() {
+		case reflect.Int8:
+			e.int8(int8(v.Int()))
+		case reflect.Int16:
+			e.int16(int16(v.Int()))
+		case reflect.Int32:
+			e.int32(int32(v.Int()))
+		case reflect.Int64:
+			e.int64(v.Int())
+		}
+
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		switch v.Type().Kind() {
+		case reflect.Uint8:
+			e.uint8(uint8(v.Uint()))
+		case reflect.Uint16:
+			e.uint16(uint16(v.Uint()))
+		case reflect.Uint32:
+			e.uint32(uint32(v.Uint()))
+		case reflect.Uint64:
+			e.uint64(v.Uint())
+		}
+
+	case reflect.Float32, reflect.Float64:
+		switch v.Type().Kind() {
+		case reflect.Float32:
+			e.uint32(math.Float32bits(float32(v.Float())))
+		case reflect.Float64:
+			e.uint64(math.Float64bits(v.Float()))
+		}
+
+	case reflect.Complex64, reflect.Complex128:
+		switch v.Type().Kind() {
+		case reflect.Complex64:
+			x := v.Complex()
+			e.uint32(math.Float32bits(float32(real(x))))
+			e.uint32(math.Float32bits(float32(imag(x))))
+		case reflect.Complex128:
+			x := v.Complex()
+			e.uint64(math.Float64bits(real(x)))
+			e.uint64(math.Float64bits(imag(x)))
+		}
+	}
+}
+
+func (d *decoder) skip(v reflect.Value) {
+	d.buf = d.buf[dataSize(v):]
+}
+
+func (e *encoder) skip(v reflect.Value) {
+	n := dataSize(v)
+	for i := range e.buf[0:n] {
+		e.buf[i] = 0
+	}
+	e.buf = e.buf[n:]
+}
+
+// intDataSize returns the size of the data required to represent the data when encoded.
+// It returns zero if the type cannot be implemented by the fast path in Read or Write.
+func intDataSize(data interface{}) int {
+	switch data := data.(type) {
+	case int8, *int8, *uint8:
+		return 1
+	case []int8:
+		return len(data)
+	case []uint8:
+		return len(data)
+	case int16, *int16, *uint16:
+		return 2
+	case []int16:
+		return 2 * len(data)
+	case []uint16:
+		return 2 * len(data)
+	case int32, *int32, *uint32:
+		return 4
+	case []int32:
+		return 4 * len(data)
+	case []uint32:
+		return 4 * len(data)
+	case int64, *int64, *uint64:
+		return 8
+	case []int64:
+		return 8 * len(data)
+	case []uint64:
+		return 8 * len(data)
+	}
+	return 0
+}
diff --git a/go/src/github.com/shirou/gopsutil/internal/common/common.go b/go/src/github.com/shirou/gopsutil/internal/common/common.go
new file mode 100644
index 0000000..e190f4d
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/internal/common/common.go
@@ -0,0 +1,296 @@
+package common
+
+//
+// gopsutil is a port of psutil(http://pythonhosted.org/psutil/).
+// This covers these architectures.
+//  - linux (amd64, arm)
+//  - freebsd (amd64)
+//  - windows (amd64)
+import (
+	"bufio"
+	"errors"
+	"io/ioutil"
+	"net/url"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"strconv"
+	"strings"
+)
+
+type Invoker interface {
+	Command(string, ...string) ([]byte, error)
+}
+
+type Invoke struct{}
+
+func (i Invoke) Command(name string, arg ...string) ([]byte, error) {
+	return exec.Command(name, arg...).Output()
+}
+
+type FakeInvoke struct {
+	CommandExpectedDir string // CommandExpectedDir specifies dir which includes expected outputs.
+	Suffix             string // Suffix species expected file name suffix such as "fail"
+	Error              error  // If Error specfied, return the error.
+}
+
+// Command in FakeInvoke returns from expected file if exists.
+func (i FakeInvoke) Command(name string, arg ...string) ([]byte, error) {
+	if i.Error != nil {
+		return []byte{}, i.Error
+	}
+
+	arch := runtime.GOOS
+
+	fname := strings.Join(append([]string{name}, arg...), "")
+	fname = url.QueryEscape(fname)
+	var dir string
+	if i.CommandExpectedDir == "" {
+		dir = "expected"
+	} else {
+		dir = i.CommandExpectedDir
+	}
+	fpath := path.Join(dir, arch, fname)
+	if i.Suffix != "" {
+		fpath += "_" + i.Suffix
+	}
+	if PathExists(fpath) {
+		return ioutil.ReadFile(fpath)
+	}
+	return exec.Command(name, arg...).Output()
+}
+
+var ErrNotImplementedError = errors.New("not implemented yet")
+
+// ReadLines reads contents from a file and splits them by new lines.
+// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1).
+func ReadLines(filename string) ([]string, error) {
+	return ReadLinesOffsetN(filename, 0, -1)
+}
+
+// ReadLines reads contents from file and splits them by new line.
+// The offset tells at which line number to start.
+// The count determines the number of lines to read (starting from offset):
+//   n >= 0: at most n lines
+//   n < 0: whole file
+func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return []string{""}, err
+	}
+	defer f.Close()
+
+	var ret []string
+
+	r := bufio.NewReader(f)
+	for i := 0; i < n+int(offset) || n < 0; i++ {
+		line, err := r.ReadString('\n')
+		if err != nil {
+			break
+		}
+		if i < int(offset) {
+			continue
+		}
+		ret = append(ret, strings.Trim(line, "\n"))
+	}
+
+	return ret, nil
+}
+
+func IntToString(orig []int8) string {
+	ret := make([]byte, len(orig))
+	size := -1
+	for i, o := range orig {
+		if o == 0 {
+			size = i
+			break
+		}
+		ret[i] = byte(o)
+	}
+	if size == -1 {
+		size = len(orig)
+	}
+
+	return string(ret[0:size])
+}
+
+func UintToString(orig []uint8) string {
+        ret := make([]byte, len(orig))
+        size := -1
+        for i, o := range orig {
+                if o == 0 {
+                        size = i
+                        break
+                }
+                ret[i] = byte(o)
+        }
+        if size == -1 {
+                size = len(orig)
+        }
+
+        return string(ret[0:size])
+}
+
+func ByteToString(orig []byte) string {
+	n := -1
+	l := -1
+	for i, b := range orig {
+		// skip left side null
+		if l == -1 && b == 0 {
+			continue
+		}
+		if l == -1 {
+			l = i
+		}
+
+		if b == 0 {
+			break
+		}
+		n = i + 1
+	}
+	if n == -1 {
+		return string(orig)
+	}
+	return string(orig[l:n])
+}
+
+// ReadInts reads contents from single line file and returns them as []int32.
+func ReadInts(filename string) ([]int64, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return []int64{}, err
+	}
+	defer f.Close()
+
+	var ret []int64
+
+	r := bufio.NewReader(f)
+
+	// The int files that this is concerned with should only be one liners.
+	line, err := r.ReadString('\n')
+	if err != nil {
+		return []int64{}, err
+	}
+
+	i, err := strconv.ParseInt(strings.Trim(line, "\n"), 10, 32)
+	if err != nil {
+		return []int64{}, err
+	}
+	ret = append(ret, i)
+
+	return ret, nil
+}
+
+// Parse to int32 without error
+func mustParseInt32(val string) int32 {
+	vv, _ := strconv.ParseInt(val, 10, 32)
+	return int32(vv)
+}
+
+// Parse to uint64 without error
+func mustParseUint64(val string) uint64 {
+	vv, _ := strconv.ParseInt(val, 10, 64)
+	return uint64(vv)
+}
+
+// Parse to Float64 without error
+func mustParseFloat64(val string) float64 {
+	vv, _ := strconv.ParseFloat(val, 64)
+	return vv
+}
+
+// StringsHas checks the target string slice contains src or not
+func StringsHas(target []string, src string) bool {
+	for _, t := range target {
+		if strings.TrimSpace(t) == src {
+			return true
+		}
+	}
+	return false
+}
+
+// StringsContains checks the src in any string of the target string slice
+func StringsContains(target []string, src string) bool {
+	for _, t := range target {
+		if strings.Contains(t, src) {
+			return true
+		}
+	}
+	return false
+}
+
+// IntContains checks the src in any int of the target int slice.
+func IntContains(target []int, src int) bool {
+	for _, t := range target {
+		if src == t {
+			return true
+		}
+	}
+	return false
+}
+
+// get struct attributes.
+// This method is used only for debugging platform dependent code.
+func attributes(m interface{}) map[string]reflect.Type {
+	typ := reflect.TypeOf(m)
+	if typ.Kind() == reflect.Ptr {
+		typ = typ.Elem()
+	}
+
+	attrs := make(map[string]reflect.Type)
+	if typ.Kind() != reflect.Struct {
+		return nil
+	}
+
+	for i := 0; i < typ.NumField(); i++ {
+		p := typ.Field(i)
+		if !p.Anonymous {
+			attrs[p.Name] = p.Type
+		}
+	}
+
+	return attrs
+}
+
+func PathExists(filename string) bool {
+	if _, err := os.Stat(filename); err == nil {
+		return true
+	}
+	return false
+}
+
+//GetEnv retrieves the environment variable key. If it does not exist it returns the default.
+func GetEnv(key string, dfault string, combineWith ...string) string {
+	value := os.Getenv(key)
+	if value == "" {
+		value = dfault
+	}
+
+	switch len(combineWith) {
+	case 0:
+		return value
+	case 1:
+		return filepath.Join(value, combineWith[0])
+	default:
+		all := make([]string, len(combineWith)+1)
+		all[0] = value
+		copy(all[1:], combineWith)
+		return filepath.Join(all...)
+	}
+	panic("invalid switch case")
+}
+
+func HostProc(combineWith ...string) string {
+	return GetEnv("HOST_PROC", "/proc", combineWith...)
+}
+
+func HostSys(combineWith ...string) string {
+	return GetEnv("HOST_SYS", "/sys", combineWith...)
+}
+
+func HostEtc(combineWith ...string) string {
+	return GetEnv("HOST_ETC", "/etc", combineWith...)
+}
diff --git a/go/src/github.com/shirou/gopsutil/internal/common/common_darwin.go b/go/src/github.com/shirou/gopsutil/internal/common/common_darwin.go
new file mode 100644
index 0000000..2e1552a
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/internal/common/common_darwin.go
@@ -0,0 +1,70 @@
+// +build darwin
+
+package common
+
+import (
+	"os"
+	"os/exec"
+	"strings"
+	"syscall"
+	"unsafe"
+)
+
+func DoSysctrl(mib string) ([]string, error) {
+	err := os.Setenv("LC_ALL", "C")
+	if err != nil {
+		return []string{}, err
+	}
+
+	sysctl, err := exec.LookPath("/usr/sbin/sysctl")
+	if err != nil {
+		return []string{}, err
+	}
+	out, err := exec.Command(sysctl, "-n", mib).Output()
+	if err != nil {
+		return []string{}, err
+	}
+	v := strings.Replace(string(out), "{ ", "", 1)
+	v = strings.Replace(string(v), " }", "", 1)
+	values := strings.Fields(string(v))
+
+	return values, nil
+}
+
+func CallSyscall(mib []int32) ([]byte, uint64, error) {
+	miblen := uint64(len(mib))
+
+	// get required buffer size
+	length := uint64(0)
+	_, _, err := syscall.Syscall6(
+		syscall.SYS___SYSCTL,
+		uintptr(unsafe.Pointer(&mib[0])),
+		uintptr(miblen),
+		0,
+		uintptr(unsafe.Pointer(&length)),
+		0,
+		0)
+	if err != 0 {
+		var b []byte
+		return b, length, err
+	}
+	if length == 0 {
+		var b []byte
+		return b, length, err
+	}
+	// get proc info itself
+	buf := make([]byte, length)
+	_, _, err = syscall.Syscall6(
+		syscall.SYS___SYSCTL,
+		uintptr(unsafe.Pointer(&mib[0])),
+		uintptr(miblen),
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(unsafe.Pointer(&length)),
+		0,
+		0)
+	if err != 0 {
+		return buf, length, err
+	}
+
+	return buf, length, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/internal/common/common_freebsd.go b/go/src/github.com/shirou/gopsutil/internal/common/common_freebsd.go
new file mode 100644
index 0000000..dfdcebd
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/internal/common/common_freebsd.go
@@ -0,0 +1,70 @@
+// +build freebsd
+
+package common
+
+import (
+	"os"
+	"os/exec"
+	"strings"
+	"syscall"
+	"unsafe"
+)
+
+func DoSysctrl(mib string) ([]string, error) {
+	err := os.Setenv("LC_ALL", "C")
+	if err != nil {
+		return []string{}, err
+	}
+	sysctl, err := exec.LookPath("/sbin/sysctl")
+	if err != nil {
+		return []string{}, err
+	}
+	out, err := exec.Command(sysctl, "-n", mib).Output()
+	if err != nil {
+		return []string{}, err
+	}
+	v := strings.Replace(string(out), "{ ", "", 1)
+	v = strings.Replace(string(v), " }", "", 1)
+	values := strings.Fields(string(v))
+
+	return values, nil
+}
+
+func CallSyscall(mib []int32) ([]byte, uint64, error) {
+	mibptr := unsafe.Pointer(&mib[0])
+	miblen := uint64(len(mib))
+
+	// get required buffer size
+	length := uint64(0)
+	_, _, err := syscall.Syscall6(
+		syscall.SYS___SYSCTL,
+		uintptr(mibptr),
+		uintptr(miblen),
+		0,
+		uintptr(unsafe.Pointer(&length)),
+		0,
+		0)
+	if err != 0 {
+		var b []byte
+		return b, length, err
+	}
+	if length == 0 {
+		var b []byte
+		return b, length, err
+	}
+	// get proc info itself
+	buf := make([]byte, length)
+	_, _, err = syscall.Syscall6(
+		syscall.SYS___SYSCTL,
+		uintptr(mibptr),
+		uintptr(miblen),
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(unsafe.Pointer(&length)),
+		0,
+		0)
+	if err != 0 {
+		return buf, length, err
+	}
+
+	return buf, length, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/internal/common/common_linux.go b/go/src/github.com/shirou/gopsutil/internal/common/common_linux.go
new file mode 100644
index 0000000..0a122e9d
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/internal/common/common_linux.go
@@ -0,0 +1,3 @@
+// +build linux
+
+package common
diff --git a/go/src/github.com/shirou/gopsutil/internal/common/common_test.go b/go/src/github.com/shirou/gopsutil/internal/common/common_test.go
new file mode 100644
index 0000000..b7bda8b
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/internal/common/common_test.go
@@ -0,0 +1,97 @@
+package common
+
+import (
+	"fmt"
+	"strings"
+	"testing"
+)
+
+func TestReadlines(t *testing.T) {
+	ret, err := ReadLines("common_test.go")
+	if err != nil {
+		t.Error(err)
+	}
+	if !strings.Contains(ret[0], "package common") {
+		t.Error("could not read correctly")
+	}
+}
+
+func TestReadLinesOffsetN(t *testing.T) {
+	ret, err := ReadLinesOffsetN("common_test.go", 2, 1)
+	if err != nil {
+		t.Error(err)
+	}
+	fmt.Println(ret[0])
+	if !strings.Contains(ret[0], `import (`) {
+		t.Error("could not read correctly")
+	}
+}
+
+func TestIntToString(t *testing.T) {
+	src := []int8{65, 66, 67}
+	dst := IntToString(src)
+	if dst != "ABC" {
+		t.Error("could not convert")
+	}
+}
+func TestByteToString(t *testing.T) {
+	src := []byte{65, 66, 67}
+	dst := ByteToString(src)
+	if dst != "ABC" {
+		t.Error("could not convert")
+	}
+
+	src = []byte{0, 65, 66, 67}
+	dst = ByteToString(src)
+	if dst != "ABC" {
+		t.Error("could not convert")
+	}
+}
+
+func TestmustParseInt32(t *testing.T) {
+	ret := mustParseInt32("11111")
+	if ret != int32(11111) {
+		t.Error("could not parse")
+	}
+}
+func TestmustParseUint64(t *testing.T) {
+	ret := mustParseUint64("11111")
+	if ret != uint64(11111) {
+		t.Error("could not parse")
+	}
+}
+func TestmustParseFloat64(t *testing.T) {
+	ret := mustParseFloat64("11111.11")
+	if ret != float64(11111.11) {
+		t.Error("could not parse")
+	}
+	ret = mustParseFloat64("11111")
+	if ret != float64(11111) {
+		t.Error("could not parse")
+	}
+}
+func TestStringsContains(t *testing.T) {
+	target, err := ReadLines("common_test.go")
+	if err != nil {
+		t.Error(err)
+	}
+	if !StringsContains(target, "func TestStringsContains(t *testing.T) {") {
+		t.Error("cloud not test correctly")
+	}
+}
+
+func TestPathExists(t *testing.T) {
+	if !PathExists("common_test.go") {
+		t.Error("exists but return not exists")
+	}
+	if PathExists("should_not_exists.go") {
+		t.Error("not exists but return exists")
+	}
+}
+
+func TestHostEtc(t *testing.T) {
+	p := HostEtc("mtab")
+	if p != "/etc/mtab" {
+		t.Errorf("invalid HostEtc, %s", p)
+	}
+}
diff --git a/go/src/github.com/shirou/gopsutil/internal/common/common_unix.go b/go/src/github.com/shirou/gopsutil/internal/common/common_unix.go
new file mode 100644
index 0000000..6622eec
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/internal/common/common_unix.go
@@ -0,0 +1,66 @@
+// +build linux freebsd darwin
+
+package common
+
+import (
+	"os/exec"
+	"strconv"
+	"strings"
+)
+
+func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) {
+	var cmd []string
+	if pid == 0 { // will get from all processes.
+		cmd = []string{"-a", "-n", "-P"}
+	} else {
+		cmd = []string{"-a", "-n", "-P", "-p", strconv.Itoa(int(pid))}
+	}
+	cmd = append(cmd, args...)
+	lsof, err := exec.LookPath("lsof")
+	if err != nil {
+		return []string{}, err
+	}
+	out, err := invoke.Command(lsof, cmd...)
+	if err != nil {
+		// if no pid found, lsof returnes code 1.
+		if err.Error() == "exit status 1" && len(out) == 0 {
+			return []string{}, nil
+		}
+	}
+	lines := strings.Split(string(out), "\n")
+
+	var ret []string
+	for _, l := range lines[1:] {
+		if len(l) == 0 {
+			continue
+		}
+		ret = append(ret, l)
+	}
+	return ret, nil
+}
+
+func CallPgrep(invoke Invoker, pid int32) ([]int32, error) {
+	var cmd []string
+	cmd = []string{"-P", strconv.Itoa(int(pid))}
+	pgrep, err := exec.LookPath("pgrep")
+	if err != nil {
+		return []int32{}, err
+	}
+	out, err := invoke.Command(pgrep, cmd...)
+	if err != nil {
+		return []int32{}, err
+	}
+	lines := strings.Split(string(out), "\n")
+	ret := make([]int32, 0, len(lines))
+	for _, l := range lines {
+		if len(l) == 0 {
+			continue
+		}
+		i, err := strconv.Atoi(l)
+		if err != nil {
+			continue
+		}
+		ret = append(ret, int32(i))
+	}
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/internal/common/common_windows.go b/go/src/github.com/shirou/gopsutil/internal/common/common_windows.go
new file mode 100644
index 0000000..d727378
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/internal/common/common_windows.go
@@ -0,0 +1,110 @@
+// +build windows
+
+package common
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+// for double values
+type PDH_FMT_COUNTERVALUE_DOUBLE struct {
+	CStatus     uint32
+	DoubleValue float64
+}
+
+// for 64 bit integer values
+type PDH_FMT_COUNTERVALUE_LARGE struct {
+	CStatus    uint32
+	LargeValue int64
+}
+
+// for long values
+type PDH_FMT_COUNTERVALUE_LONG struct {
+	CStatus   uint32
+	LongValue int32
+	padding   [4]byte
+}
+
+// windows system const
+const (
+	ERROR_SUCCESS        = 0
+	ERROR_FILE_NOT_FOUND = 2
+	DRIVE_REMOVABLE      = 2
+	DRIVE_FIXED          = 3
+	HKEY_LOCAL_MACHINE   = 0x80000002
+	RRF_RT_REG_SZ        = 0x00000002
+	RRF_RT_REG_DWORD     = 0x00000010
+	PDH_FMT_LONG         = 0x00000100
+	PDH_FMT_DOUBLE       = 0x00000200
+	PDH_FMT_LARGE        = 0x00000400
+	PDH_INVALID_DATA     = 0xc0000bc6
+	PDH_INVALID_HANDLE   = 0xC0000bbc
+	PDH_NO_DATA          = 0x800007d5
+)
+
+var (
+	Modkernel32 = syscall.NewLazyDLL("kernel32.dll")
+	ModNt       = syscall.NewLazyDLL("ntdll.dll")
+	ModPdh      = syscall.NewLazyDLL("pdh.dll")
+
+	ProcGetSystemTimes           = Modkernel32.NewProc("GetSystemTimes")
+	ProcNtQuerySystemInformation = ModNt.NewProc("NtQuerySystemInformation")
+	PdhOpenQuery                 = ModPdh.NewProc("PdhOpenQuery")
+	PdhAddCounter                = ModPdh.NewProc("PdhAddCounterW")
+	PdhCollectQueryData          = ModPdh.NewProc("PdhCollectQueryData")
+	PdhGetFormattedCounterValue  = ModPdh.NewProc("PdhGetFormattedCounterValue")
+	PdhCloseQuery                = ModPdh.NewProc("PdhCloseQuery")
+)
+
+type FILETIME struct {
+	DwLowDateTime  uint32
+	DwHighDateTime uint32
+}
+
+// borrowed from net/interface_windows.go
+func BytePtrToString(p *uint8) string {
+	a := (*[10000]uint8)(unsafe.Pointer(p))
+	i := 0
+	for a[i] != 0 {
+		i++
+	}
+	return string(a[:i])
+}
+
+// CounterInfo
+// copied from https://github.com/mackerelio/mackerel-agent/
+type CounterInfo struct {
+	PostName    string
+	CounterName string
+	Counter     syscall.Handle
+}
+
+// CreateQuery XXX
+// copied from https://github.com/mackerelio/mackerel-agent/
+func CreateQuery() (syscall.Handle, error) {
+	var query syscall.Handle
+	r, _, err := PdhOpenQuery.Call(0, 0, uintptr(unsafe.Pointer(&query)))
+	if r != 0 {
+		return 0, err
+	}
+	return query, nil
+}
+
+// CreateCounter XXX
+func CreateCounter(query syscall.Handle, pname, cname string) (*CounterInfo, error) {
+	var counter syscall.Handle
+	r, _, err := PdhAddCounter.Call(
+		uintptr(query),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(cname))),
+		0,
+		uintptr(unsafe.Pointer(&counter)))
+	if r != 0 {
+		return nil, err
+	}
+	return &CounterInfo{
+		PostName:    pname,
+		CounterName: cname,
+		Counter:     counter,
+	}, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/load/load.go b/go/src/github.com/shirou/gopsutil/load/load.go
new file mode 100644
index 0000000..dfe32a1
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/load/load.go
@@ -0,0 +1,35 @@
+package load
+
+import (
+	"encoding/json"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+var invoke common.Invoker
+
+func init() {
+	invoke = common.Invoke{}
+}
+
+type AvgStat struct {
+	Load1  float64 `json:"load1"`
+	Load5  float64 `json:"load5"`
+	Load15 float64 `json:"load15"`
+}
+
+func (l AvgStat) String() string {
+	s, _ := json.Marshal(l)
+	return string(s)
+}
+
+type MiscStat struct {
+	ProcsRunning int `json:"procsRunning"`
+	ProcsBlocked int `json:"procsBlocked"`
+	Ctxt         int `json:"ctxt"`
+}
+
+func (m MiscStat) String() string {
+	s, _ := json.Marshal(m)
+	return string(s)
+}
diff --git a/go/src/github.com/shirou/gopsutil/load/load_darwin.go b/go/src/github.com/shirou/gopsutil/load/load_darwin.go
new file mode 100644
index 0000000..34e0653
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/load/load_darwin.go
@@ -0,0 +1,67 @@
+// +build darwin
+
+package load
+
+import (
+	"os/exec"
+	"strconv"
+	"strings"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func Avg() (*AvgStat, error) {
+	values, err := common.DoSysctrl("vm.loadavg")
+	if err != nil {
+		return nil, err
+	}
+
+	load1, err := strconv.ParseFloat(values[0], 64)
+	if err != nil {
+		return nil, err
+	}
+	load5, err := strconv.ParseFloat(values[1], 64)
+	if err != nil {
+		return nil, err
+	}
+	load15, err := strconv.ParseFloat(values[2], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	ret := &AvgStat{
+		Load1:  float64(load1),
+		Load5:  float64(load5),
+		Load15: float64(load15),
+	}
+
+	return ret, nil
+}
+
+// Misc returnes miscellaneous host-wide statistics.
+// darwin use ps command to get process running/blocked count.
+// Almost same as FreeBSD implementation, but state is different.
+// U means 'Uninterruptible Sleep'.
+func Misc() (*MiscStat, error) {
+	bin, err := exec.LookPath("ps")
+	if err != nil {
+		return nil, err
+	}
+	out, err := invoke.Command(bin, "axo", "state")
+	if err != nil {
+		return nil, err
+	}
+	lines := strings.Split(string(out), "\n")
+
+	ret := MiscStat{}
+	for _, l := range lines {
+		if strings.Contains(l, "R") {
+			ret.ProcsRunning++
+		} else if strings.Contains(l, "U") {
+			// uninterruptible sleep == blocked
+			ret.ProcsBlocked++
+		}
+	}
+
+	return &ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/load/load_freebsd.go b/go/src/github.com/shirou/gopsutil/load/load_freebsd.go
new file mode 100644
index 0000000..6d3a0ba
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/load/load_freebsd.go
@@ -0,0 +1,65 @@
+// +build freebsd
+
+package load
+
+import (
+	"os/exec"
+	"strconv"
+	"strings"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func Avg() (*AvgStat, error) {
+	values, err := common.DoSysctrl("vm.loadavg")
+	if err != nil {
+		return nil, err
+	}
+
+	load1, err := strconv.ParseFloat(values[0], 64)
+	if err != nil {
+		return nil, err
+	}
+	load5, err := strconv.ParseFloat(values[1], 64)
+	if err != nil {
+		return nil, err
+	}
+	load15, err := strconv.ParseFloat(values[2], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	ret := &AvgStat{
+		Load1:  float64(load1),
+		Load5:  float64(load5),
+		Load15: float64(load15),
+	}
+
+	return ret, nil
+}
+
+// Misc returnes miscellaneous host-wide statistics.
+// darwin use ps command to get process running/blocked count.
+// Almost same as Darwin implementation, but state is different.
+func Misc() (*MiscStat, error) {
+	bin, err := exec.LookPath("ps")
+	if err != nil {
+		return nil, err
+	}
+	out, err := invoke.Command(bin, "axo", "state")
+	if err != nil {
+		return nil, err
+	}
+	lines := strings.Split(string(out), "\n")
+
+	ret := MiscStat{}
+	for _, l := range lines {
+		if strings.Contains(l, "R") {
+			ret.ProcsRunning++
+		} else if strings.Contains(l, "D") {
+			ret.ProcsBlocked++
+		}
+	}
+
+	return &ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/load/load_linux.go b/go/src/github.com/shirou/gopsutil/load/load_linux.go
new file mode 100644
index 0000000..c455397
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/load/load_linux.go
@@ -0,0 +1,78 @@
+// +build linux
+
+package load
+
+import (
+	"io/ioutil"
+	"strconv"
+	"strings"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func Avg() (*AvgStat, error) {
+	filename := common.HostProc("loadavg")
+	line, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+
+	values := strings.Fields(string(line))
+
+	load1, err := strconv.ParseFloat(values[0], 64)
+	if err != nil {
+		return nil, err
+	}
+	load5, err := strconv.ParseFloat(values[1], 64)
+	if err != nil {
+		return nil, err
+	}
+	load15, err := strconv.ParseFloat(values[2], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	ret := &AvgStat{
+		Load1:  load1,
+		Load5:  load5,
+		Load15: load15,
+	}
+
+	return ret, nil
+}
+
+// Misc returnes miscellaneous host-wide statistics.
+// Note: the name should be changed near future.
+func Misc() (*MiscStat, error) {
+	filename := common.HostProc("stat")
+	out, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+
+	ret := &MiscStat{}
+	lines := strings.Split(string(out), "\n")
+	for _, line := range lines {
+		fields := strings.Fields(line)
+		if len(fields) != 2 {
+			continue
+		}
+		v, err := strconv.ParseInt(fields[1], 10, 64)
+		if err != nil {
+			continue
+		}
+		switch fields[0] {
+		case "procs_running":
+			ret.ProcsRunning = int(v)
+		case "procs_blocked":
+			ret.ProcsBlocked = int(v)
+		case "ctxt":
+			ret.Ctxt = int(v)
+		default:
+			continue
+		}
+
+	}
+
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/load/load_test.go b/go/src/github.com/shirou/gopsutil/load/load_test.go
new file mode 100644
index 0000000..7db3623
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/load/load_test.go
@@ -0,0 +1,54 @@
+package load
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestLoad(t *testing.T) {
+	v, err := Avg()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+
+	empty := &AvgStat{}
+	if v == empty {
+		t.Errorf("error load: %v", v)
+	}
+}
+
+func TestLoadAvgStat_String(t *testing.T) {
+	v := AvgStat{
+		Load1:  10.1,
+		Load5:  20.1,
+		Load15: 30.1,
+	}
+	e := `{"load1":10.1,"load5":20.1,"load15":30.1}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("LoadAvgStat string is invalid: %v", v)
+	}
+}
+
+func TestMisc(t *testing.T) {
+	v, err := Misc()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+
+	empty := &MiscStat{}
+	if v == empty {
+		t.Errorf("error load: %v", v)
+	}
+}
+
+func TestMiscStatString(t *testing.T) {
+	v := MiscStat{
+		ProcsRunning: 1,
+		ProcsBlocked: 2,
+		Ctxt:         3,
+	}
+	e := `{"procsRunning":1,"procsBlocked":2,"ctxt":3}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("TestMiscString string is invalid: %v", v)
+	}
+}
diff --git a/go/src/github.com/shirou/gopsutil/load/load_windows.go b/go/src/github.com/shirou/gopsutil/load/load_windows.go
new file mode 100644
index 0000000..c45c154
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/load/load_windows.go
@@ -0,0 +1,19 @@
+// +build windows
+
+package load
+
+import (
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func Avg() (*AvgStat, error) {
+	ret := AvgStat{}
+
+	return &ret, common.ErrNotImplementedError
+}
+
+func Misc() (*MiscStat, error) {
+	ret := MiscStat{}
+
+	return &ret, common.ErrNotImplementedError
+}
diff --git a/go/src/github.com/shirou/gopsutil/mem/mem.go b/go/src/github.com/shirou/gopsutil/mem/mem.go
new file mode 100644
index 0000000..5f122d1
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/mem/mem.go
@@ -0,0 +1,64 @@
+package mem
+
+import (
+	"encoding/json"
+)
+
+// Memory usage statistics. Total, Available and Used contain numbers of bytes
+// for human consumption.
+//
+// The other fields in this struct contain kernel specific values.
+type VirtualMemoryStat struct {
+	// Total amount of RAM on this system
+	Total uint64 `json:"total"`
+
+	// RAM available for programs to allocate
+	//
+	// This value is computed from the kernel specific values.
+	Available uint64 `json:"available"`
+
+	// RAM used by programs
+	//
+	// This value is computed from the kernel specific values.
+	Used uint64 `json:"used"`
+
+	// Percentage of RAM used by programs
+	//
+	// This value is computed from the kernel specific values.
+	UsedPercent float64 `json:"usedPercent"`
+
+	// This is the kernel's notion of free memory; RAM chips whose bits nobody
+	// cares about the value of right now. For a human consumable number,
+	// Available is what you really want.
+	Free uint64 `json:"free"`
+
+	// OS X / BSD specific numbers:
+	// http://www.macyourself.com/2010/02/17/what-is-free-wired-active-and-inactive-system-memory-ram/
+	Active   uint64 `json:"active"`
+	Inactive uint64 `json:"inactive"`
+	Wired    uint64 `json:"wired"`
+
+	// Linux specific numbers
+	// https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s2-proc-meminfo.html
+	Buffers uint64 `json:"buffers"`
+	Cached  uint64 `json:"cached"`
+}
+
+type SwapMemoryStat struct {
+	Total       uint64  `json:"total"`
+	Used        uint64  `json:"used"`
+	Free        uint64  `json:"free"`
+	UsedPercent float64 `json:"usedPercent"`
+	Sin         uint64  `json:"sin"`
+	Sout        uint64  `json:"sout"`
+}
+
+func (m VirtualMemoryStat) String() string {
+	s, _ := json.Marshal(m)
+	return string(s)
+}
+
+func (m SwapMemoryStat) String() string {
+	s, _ := json.Marshal(m)
+	return string(s)
+}
diff --git a/go/src/github.com/shirou/gopsutil/mem/mem_darwin.go b/go/src/github.com/shirou/gopsutil/mem/mem_darwin.go
new file mode 100644
index 0000000..922b05c
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/mem/mem_darwin.go
@@ -0,0 +1,69 @@
+// +build darwin
+
+package mem
+
+import (
+	"encoding/binary"
+	"strconv"
+	"strings"
+	"syscall"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func getHwMemsize() (uint64, error) {
+	totalString, err := syscall.Sysctl("hw.memsize")
+	if err != nil {
+		return 0, err
+	}
+
+	// syscall.sysctl() helpfully assumes the result is a null-terminated string and
+	// removes the last byte of the result if it's 0 :/
+	totalString += "\x00"
+
+	total := uint64(binary.LittleEndian.Uint64([]byte(totalString)))
+
+	return total, nil
+}
+
+// SwapMemory returns swapinfo.
+func SwapMemory() (*SwapMemoryStat, error) {
+	var ret *SwapMemoryStat
+
+	swapUsage, err := common.DoSysctrl("vm.swapusage")
+	if err != nil {
+		return ret, err
+	}
+
+	total := strings.Replace(swapUsage[2], "M", "", 1)
+	used := strings.Replace(swapUsage[5], "M", "", 1)
+	free := strings.Replace(swapUsage[8], "M", "", 1)
+
+	total_v, err := strconv.ParseFloat(total, 64)
+	if err != nil {
+		return nil, err
+	}
+	used_v, err := strconv.ParseFloat(used, 64)
+	if err != nil {
+		return nil, err
+	}
+	free_v, err := strconv.ParseFloat(free, 64)
+	if err != nil {
+		return nil, err
+	}
+
+	u := float64(0)
+	if total_v != 0 {
+		u = ((total_v - free_v) / total_v) * 100.0
+	}
+
+	// vm.swapusage shows "M", multiply 1000
+	ret = &SwapMemoryStat{
+		Total:       uint64(total_v * 1000),
+		Used:        uint64(used_v * 1000),
+		Free:        uint64(free_v * 1000),
+		UsedPercent: u,
+	}
+
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/mem/mem_darwin_cgo.go b/go/src/github.com/shirou/gopsutil/mem/mem_darwin_cgo.go
new file mode 100644
index 0000000..4616319
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/mem/mem_darwin_cgo.go
@@ -0,0 +1,53 @@
+// +build darwin
+// +build cgo
+
+package mem
+
+/*
+#include <mach/mach_host.h>
+*/
+import "C"
+
+import (
+	"fmt"
+	"syscall"
+	"unsafe"
+)
+
+// VirtualMemory returns VirtualmemoryStat.
+func VirtualMemory() (*VirtualMemoryStat, error) {
+	count := C.mach_msg_type_number_t(C.HOST_VM_INFO_COUNT)
+	var vmstat C.vm_statistics_data_t
+
+	status := C.host_statistics(C.host_t(C.mach_host_self()),
+		C.HOST_VM_INFO,
+		C.host_info_t(unsafe.Pointer(&vmstat)),
+		&count)
+
+	if status != C.KERN_SUCCESS {
+		return nil, fmt.Errorf("host_statistics error=%d", status)
+	}
+
+	pageSize := uint64(syscall.Getpagesize())
+	total, err := getHwMemsize()
+	if err != nil {
+		return nil, err
+	}
+	totalCount := C.natural_t(total / pageSize)
+
+	availableCount := vmstat.inactive_count + vmstat.free_count
+	usedPercent := 100 * float64(totalCount-availableCount) / float64(totalCount)
+
+	usedCount := totalCount - availableCount
+
+	return &VirtualMemoryStat{
+		Total:       total,
+		Available:   pageSize * uint64(availableCount),
+		Used:        pageSize * uint64(usedCount),
+		UsedPercent: usedPercent,
+		Free:        pageSize * uint64(vmstat.free_count),
+		Active:      pageSize * uint64(vmstat.active_count),
+		Inactive:    pageSize * uint64(vmstat.inactive_count),
+		Wired:       pageSize * uint64(vmstat.wire_count),
+	}, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go b/go/src/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go
new file mode 100644
index 0000000..7094802
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go
@@ -0,0 +1,88 @@
+// +build darwin
+// +build !cgo
+
+package mem
+
+import (
+	"os/exec"
+	"strconv"
+	"strings"
+	"syscall"
+)
+
+// Runs vm_stat and returns Free and inactive pages
+func getVMStat(vms *VirtualMemoryStat) error {
+	vm_stat, err := exec.LookPath("vm_stat")
+	if err != nil {
+		return err
+	}
+	out, err := exec.Command(vm_stat).Output()
+	if err != nil {
+		return err
+	}
+	return parseVMStat(string(out), vms)
+}
+
+func parseVMStat(out string, vms *VirtualMemoryStat) error {
+	var err error
+
+	lines := strings.Split(out, "\n")
+	pagesize := uint64(syscall.Getpagesize())
+	for _, line := range lines {
+		fields := strings.Split(line, ":")
+		if len(fields) < 2 {
+			continue
+		}
+		key := strings.TrimSpace(fields[0])
+		value := strings.Trim(fields[1], " .")
+		switch key {
+		case "Pages free":
+			free, e := strconv.ParseUint(value, 10, 64)
+			if e != nil {
+				err = e
+			}
+			vms.Free = free * pagesize
+		case "Pages inactive":
+			inactive, e := strconv.ParseUint(value, 10, 64)
+			if e != nil {
+				err = e
+			}
+			vms.Inactive = inactive * pagesize
+		case "Pages active":
+			active, e := strconv.ParseUint(value, 10, 64)
+			if e != nil {
+				err = e
+			}
+			vms.Active = active * pagesize
+		case "Pages wired down":
+			wired, e := strconv.ParseUint(value, 10, 64)
+			if e != nil {
+				err = e
+			}
+			vms.Wired = wired * pagesize
+		}
+	}
+	return err
+}
+
+// VirtualMemory returns VirtualmemoryStat.
+func VirtualMemory() (*VirtualMemoryStat, error) {
+	ret := &VirtualMemoryStat{}
+
+	total, err := getHwMemsize()
+	if err != nil {
+		return nil, err
+	}
+	err = getVMStat(ret)
+	if err != nil {
+		return nil, err
+	}
+
+	ret.Available = ret.Free + ret.Inactive
+	ret.Total = total
+
+	ret.Used = ret.Total - ret.Available
+	ret.UsedPercent = 100 * float64(ret.Used) / float64(ret.Total)
+
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/mem/mem_darwin_test.go b/go/src/github.com/shirou/gopsutil/mem/mem_darwin_test.go
new file mode 100644
index 0000000..6d9e6b8
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/mem/mem_darwin_test.go
@@ -0,0 +1,47 @@
+// +build darwin
+
+package mem
+
+import (
+	"os/exec"
+	"strconv"
+	"strings"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestVirtualMemoryDarwin(t *testing.T) {
+	v, err := VirtualMemory()
+	assert.Nil(t, err)
+
+	outBytes, err := exec.Command("/usr/sbin/sysctl", "hw.memsize").Output()
+	assert.Nil(t, err)
+	outString := string(outBytes)
+	outString = strings.TrimSpace(outString)
+	outParts := strings.Split(outString, " ")
+	actualTotal, err := strconv.ParseInt(outParts[1], 10, 64)
+	assert.Nil(t, err)
+	assert.Equal(t, uint64(actualTotal), v.Total)
+
+	assert.True(t, v.Available > 0)
+	assert.Equal(t, v.Available, v.Free+v.Inactive, "%v", v)
+
+	assert.True(t, v.Used > 0)
+	assert.True(t, v.Used < v.Total)
+
+	assert.True(t, v.UsedPercent > 0)
+	assert.True(t, v.UsedPercent < 100)
+
+	assert.True(t, v.Free > 0)
+	assert.True(t, v.Free < v.Available)
+
+	assert.True(t, v.Active > 0)
+	assert.True(t, v.Active < v.Total)
+
+	assert.True(t, v.Inactive > 0)
+	assert.True(t, v.Inactive < v.Total)
+
+	assert.True(t, v.Wired > 0)
+	assert.True(t, v.Wired < v.Total)
+}
diff --git a/go/src/github.com/shirou/gopsutil/mem/mem_freebsd.go b/go/src/github.com/shirou/gopsutil/mem/mem_freebsd.go
new file mode 100644
index 0000000..7194057
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/mem/mem_freebsd.go
@@ -0,0 +1,134 @@
+// +build freebsd
+
+package mem
+
+import (
+	"errors"
+	"os/exec"
+	"strconv"
+	"strings"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func VirtualMemory() (*VirtualMemoryStat, error) {
+	pageSize, err := common.DoSysctrl("vm.stats.vm.v_page_size")
+	if err != nil {
+		return nil, err
+	}
+	p, err := strconv.ParseUint(pageSize[0], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+
+	pageCount, err := common.DoSysctrl("vm.stats.vm.v_page_count")
+	if err != nil {
+		return nil, err
+	}
+	free, err := common.DoSysctrl("vm.stats.vm.v_free_count")
+	if err != nil {
+		return nil, err
+	}
+	active, err := common.DoSysctrl("vm.stats.vm.v_active_count")
+	if err != nil {
+		return nil, err
+	}
+	inactive, err := common.DoSysctrl("vm.stats.vm.v_inactive_count")
+	if err != nil {
+		return nil, err
+	}
+	cache, err := common.DoSysctrl("vm.stats.vm.v_cache_count")
+	if err != nil {
+		return nil, err
+	}
+	buffer, err := common.DoSysctrl("vfs.bufspace")
+	if err != nil {
+		return nil, err
+	}
+	wired, err := common.DoSysctrl("vm.stats.vm.v_wire_count")
+	if err != nil {
+		return nil, err
+	}
+
+	parsed := make([]uint64, 0, 7)
+	vv := []string{
+		pageCount[0],
+		free[0],
+		active[0],
+		inactive[0],
+		cache[0],
+		buffer[0],
+		wired[0],
+	}
+	for _, target := range vv {
+		t, err := strconv.ParseUint(target, 10, 64)
+		if err != nil {
+			return nil, err
+		}
+		parsed = append(parsed, t)
+	}
+
+	ret := &VirtualMemoryStat{
+		Total:    parsed[0] * p,
+		Free:     parsed[1] * p,
+		Active:   parsed[2] * p,
+		Inactive: parsed[3] * p,
+		Cached:   parsed[4] * p,
+		Buffers:  parsed[5],
+		Wired:    parsed[6] * p,
+	}
+
+	ret.Available = ret.Inactive + ret.Cached + ret.Free
+	ret.Used = ret.Total - ret.Available
+	ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
+
+	return ret, nil
+}
+
+// Return swapinfo
+// FreeBSD can have multiple swap devices. but use only first device
+func SwapMemory() (*SwapMemoryStat, error) {
+	swapinfo, err := exec.LookPath("swapinfo")
+	if err != nil {
+		return nil, err
+	}
+
+	out, err := exec.Command(swapinfo).Output()
+	if err != nil {
+		return nil, err
+	}
+	for _, line := range strings.Split(string(out), "\n") {
+		values := strings.Fields(line)
+		// skip title line
+		if len(values) == 0 || values[0] == "Device" {
+			continue
+		}
+
+		u := strings.Replace(values[4], "%", "", 1)
+		total_v, err := strconv.ParseUint(values[1], 10, 64)
+		if err != nil {
+			return nil, err
+		}
+		used_v, err := strconv.ParseUint(values[2], 10, 64)
+		if err != nil {
+			return nil, err
+		}
+		free_v, err := strconv.ParseUint(values[3], 10, 64)
+		if err != nil {
+			return nil, err
+		}
+		up_v, err := strconv.ParseFloat(u, 64)
+		if err != nil {
+			return nil, err
+		}
+
+		return &SwapMemoryStat{
+			Total:       total_v,
+			Used:        used_v,
+			Free:        free_v,
+			UsedPercent: up_v,
+		}, nil
+	}
+
+	return nil, errors.New("no swap devices found")
+}
diff --git a/go/src/github.com/shirou/gopsutil/mem/mem_linux.go b/go/src/github.com/shirou/gopsutil/mem/mem_linux.go
new file mode 100644
index 0000000..899da83
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/mem/mem_linux.go
@@ -0,0 +1,100 @@
+// +build linux
+
+package mem
+
+import (
+	"strconv"
+	"strings"
+	"syscall"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func VirtualMemory() (*VirtualMemoryStat, error) {
+	filename := common.HostProc("meminfo")
+	lines, _ := common.ReadLines(filename)
+	// flag if MemAvailable is in /proc/meminfo (kernel 3.14+)
+	memavail := false
+
+	ret := &VirtualMemoryStat{}
+	for _, line := range lines {
+		fields := strings.Split(line, ":")
+		if len(fields) != 2 {
+			continue
+		}
+		key := strings.TrimSpace(fields[0])
+		value := strings.TrimSpace(fields[1])
+		value = strings.Replace(value, " kB", "", -1)
+
+		t, err := strconv.ParseUint(value, 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		switch key {
+		case "MemTotal":
+			ret.Total = t * 1024
+		case "MemFree":
+			ret.Free = t * 1024
+		case "MemAvailable":
+			memavail = true
+			ret.Available = t * 1024
+		case "Buffers":
+			ret.Buffers = t * 1024
+		case "Cached":
+			ret.Cached = t * 1024
+		case "Active":
+			ret.Active = t * 1024
+		case "Inactive":
+			ret.Inactive = t * 1024
+		}
+	}
+	if !memavail {
+		ret.Available = ret.Free + ret.Buffers + ret.Cached
+	}
+	ret.Used = ret.Total - ret.Available
+	ret.UsedPercent = float64(ret.Total-ret.Available) / float64(ret.Total) * 100.0
+
+	return ret, nil
+}
+
+func SwapMemory() (*SwapMemoryStat, error) {
+	sysinfo := &syscall.Sysinfo_t{}
+
+	if err := syscall.Sysinfo(sysinfo); err != nil {
+		return nil, err
+	}
+	ret := &SwapMemoryStat{
+		Total: uint64(sysinfo.Totalswap),
+		Free:  uint64(sysinfo.Freeswap),
+	}
+	ret.Used = ret.Total - ret.Free
+	//check Infinity
+	if ret.Total != 0 {
+		ret.UsedPercent = float64(ret.Total-ret.Free) / float64(ret.Total) * 100.0
+	} else {
+		ret.UsedPercent = 0
+	}
+	filename := common.HostProc("vmstat")
+	lines, _ := common.ReadLines(filename)
+	for _, l := range lines {
+		fields := strings.Fields(l)
+		if len(fields) < 2 {
+			continue
+		}
+		switch fields[0] {
+		case "pswpin":
+			value, err := strconv.ParseUint(fields[1], 10, 64)
+			if err != nil {
+				continue
+			}
+			ret.Sin = value * 4 * 1024
+		case "pswpout":
+			value, err := strconv.ParseUint(fields[1], 10, 64)
+			if err != nil {
+				continue
+			}
+			ret.Sout = value * 4 * 1024
+		}
+	}
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/mem/mem_test.go b/go/src/github.com/shirou/gopsutil/mem/mem_test.go
new file mode 100644
index 0000000..f7074d8
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/mem/mem_test.go
@@ -0,0 +1,72 @@
+package mem
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestVirtual_memory(t *testing.T) {
+	v, err := VirtualMemory()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	empty := &VirtualMemoryStat{}
+	if v == empty {
+		t.Errorf("error %v", v)
+	}
+
+	assert.True(t, v.Total > 0)
+	assert.True(t, v.Available > 0)
+	assert.True(t, v.Used > 0)
+
+	assert.Equal(t, v.Total, v.Available+v.Used,
+		"Total should be computable from available + used: %v", v)
+
+	assert.True(t, v.Free > 0)
+	assert.True(t, v.Available > v.Free,
+		"Free should be a subset of Available: %v", v)
+
+	assert.InDelta(t, v.UsedPercent,
+		100*float64(v.Used)/float64(v.Total), 0.1,
+		"UsedPercent should be how many percent of Total is Used: %v", v)
+}
+
+func TestSwap_memory(t *testing.T) {
+	v, err := SwapMemory()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	empty := &SwapMemoryStat{}
+	if v == empty {
+		t.Errorf("error %v", v)
+	}
+}
+
+func TestVirtualMemoryStat_String(t *testing.T) {
+	v := VirtualMemoryStat{
+		Total:       10,
+		Available:   20,
+		Used:        30,
+		UsedPercent: 30.1,
+		Free:        40,
+	}
+	e := `{"total":10,"available":20,"used":30,"usedPercent":30.1,"free":40,"active":0,"inactive":0,"wired":0,"buffers":0,"cached":0}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("VirtualMemoryStat string is invalid: %v", v)
+	}
+}
+
+func TestSwapMemoryStat_String(t *testing.T) {
+	v := SwapMemoryStat{
+		Total:       10,
+		Used:        30,
+		Free:        40,
+		UsedPercent: 30.1,
+	}
+	e := `{"total":10,"used":30,"free":40,"usedPercent":30.1,"sin":0,"sout":0}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("SwapMemoryStat string is invalid: %v", v)
+	}
+}
diff --git a/go/src/github.com/shirou/gopsutil/mem/mem_windows.go b/go/src/github.com/shirou/gopsutil/mem/mem_windows.go
new file mode 100644
index 0000000..045af49
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/mem/mem_windows.go
@@ -0,0 +1,50 @@
+// +build windows
+
+package mem
+
+import (
+	"syscall"
+	"unsafe"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+var (
+	procGlobalMemoryStatusEx = common.Modkernel32.NewProc("GlobalMemoryStatusEx")
+)
+
+type memoryStatusEx struct {
+	cbSize                  uint32
+	dwMemoryLoad            uint32
+	ullTotalPhys            uint64 // in bytes
+	ullAvailPhys            uint64
+	ullTotalPageFile        uint64
+	ullAvailPageFile        uint64
+	ullTotalVirtual         uint64
+	ullAvailVirtual         uint64
+	ullAvailExtendedVirtual uint64
+}
+
+func VirtualMemory() (*VirtualMemoryStat, error) {
+	var memInfo memoryStatusEx
+	memInfo.cbSize = uint32(unsafe.Sizeof(memInfo))
+	mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo)))
+	if mem == 0 {
+		return nil, syscall.GetLastError()
+	}
+
+	ret := &VirtualMemoryStat{
+		Total:       memInfo.ullTotalPhys,
+		Available:   memInfo.ullAvailPhys,
+		UsedPercent: float64(memInfo.dwMemoryLoad),
+	}
+
+	ret.Used = ret.Total - ret.Available
+	return ret, nil
+}
+
+func SwapMemory() (*SwapMemoryStat, error) {
+	ret := &SwapMemoryStat{}
+
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/mktypes.sh b/go/src/github.com/shirou/gopsutil/mktypes.sh
new file mode 100644
index 0000000..7bf2e24
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/mktypes.sh
@@ -0,0 +1,37 @@
+
+DIRS="cpu disk docker host load mem net process"
+
+GOOS=`uname | tr '[:upper:]' '[:lower:]'`
+ARCH=`uname -m`
+
+case $ARCH in
+	amd64)
+		GOARCH="amd64"
+		;;
+	x86_64)
+		GOARCH="amd64"
+		;;
+	i386)
+		GOARCH="386"
+		;;
+	i686)
+		GOARCH="386"
+		;;
+	arm)
+		GOARCH="arm"
+		;;
+	*)
+		echo "unknown arch: $ARCH"
+		exit 1
+esac
+
+for DIR in $DIRS
+do
+	if [ -e ${DIR}/types_${GOOS}.go ]; then
+		echo "// +build $GOOS" > ${DIR}/${DIR}_${GOOS}_${GOARCH}.go
+		echo "// +build $GOARCH" >> ${DIR}/${DIR}_${GOOS}_${GOARCH}.go
+		go tool cgo -godefs ${DIR}/types_${GOOS}.go >> ${DIR}/${DIR}_${GOOS}_${GOARCH}.go
+	fi
+done
+
+
diff --git a/go/src/github.com/shirou/gopsutil/net/net.go b/go/src/github.com/shirou/gopsutil/net/net.go
new file mode 100644
index 0000000..60f1069
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/net/net.go
@@ -0,0 +1,243 @@
+package net
+
+import (
+	"encoding/json"
+	"fmt"
+	"net"
+	"strconv"
+	"strings"
+	"syscall"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+var invoke common.Invoker
+
+func init() {
+	invoke = common.Invoke{}
+}
+
+type IOCountersStat struct {
+	Name        string `json:"name"`         // interface name
+	BytesSent   uint64 `json:"bytesSent"`   // number of bytes sent
+	BytesRecv   uint64 `json:"bytesRecv"`   // number of bytes received
+	PacketsSent uint64 `json:"packetsSent"` // number of packets sent
+	PacketsRecv uint64 `json:"packetsRecv"` // number of packets received
+	Errin       uint64 `json:"errin"`        // total number of errors while receiving
+	Errout      uint64 `json:"errout"`       // total number of errors while sending
+	Dropin      uint64 `json:"dropin"`       // total number of incoming packets which were dropped
+	Dropout     uint64 `json:"dropout"`      // total number of outgoing packets which were dropped (always 0 on OSX and BSD)
+}
+
+// Addr is implemented compatibility to psutil
+type Addr struct {
+	IP   string `json:"ip"`
+	Port uint32 `json:"port"`
+}
+
+type ConnectionStat struct {
+	Fd     uint32 `json:"fd"`
+	Family uint32 `json:"family"`
+	Type   uint32 `json:"type"`
+	Laddr  Addr   `json:"localaddr"`
+	Raddr  Addr   `json:"remoteaddr"`
+	Status string `json:"status"`
+	Pid    int32  `json:"pid"`
+}
+
+// System wide stats about different network protocols
+type ProtoCountersStat struct {
+	Protocol string           `json:"protocol"`
+	Stats    map[string]int64 `json:"stats"`
+}
+
+// NetInterfaceAddr is designed for represent interface addresses
+type InterfaceAddr struct {
+	Addr string `json:"addr"`
+}
+
+type InterfaceStat struct {
+	MTU          int             `json:"mtu"`          // maximum transmission unit
+	Name         string          `json:"name"`         // e.g., "en0", "lo0", "eth0.100"
+	HardwareAddr string          `json:"hardwareaddr"` // IEEE MAC-48, EUI-48 and EUI-64 form
+	Flags        []string        `json:"flags"`        // e.g., FlagUp, FlagLoopback, FlagMulticast
+	Addrs        []InterfaceAddr `json:"addrs"`
+}
+
+type FilterStat struct {
+	ConnTrackCount int64 `json:"conntrackCount"`
+	ConnTrackMax   int64 `json:"conntrackMax"`
+}
+
+var constMap = map[string]int{
+	"TCP":  syscall.SOCK_STREAM,
+	"UDP":  syscall.SOCK_DGRAM,
+	"IPv4": syscall.AF_INET,
+	"IPv6": syscall.AF_INET6,
+}
+
+func (n IOCountersStat) String() string {
+	s, _ := json.Marshal(n)
+	return string(s)
+}
+
+func (n ConnectionStat) String() string {
+	s, _ := json.Marshal(n)
+	return string(s)
+}
+
+func (n ProtoCountersStat) String() string {
+	s, _ := json.Marshal(n)
+	return string(s)
+}
+
+func (a Addr) String() string {
+	s, _ := json.Marshal(a)
+	return string(s)
+}
+
+func (n InterfaceStat) String() string {
+	s, _ := json.Marshal(n)
+	return string(s)
+}
+
+func (n InterfaceAddr) String() string {
+	s, _ := json.Marshal(n)
+	return string(s)
+}
+
+func Interfaces() ([]InterfaceStat, error) {
+	is, err := net.Interfaces()
+	if err != nil {
+		return nil, err
+	}
+	ret := make([]InterfaceStat, 0, len(is))
+	for _, ifi := range is {
+
+		var flags []string
+		if ifi.Flags&net.FlagUp != 0 {
+			flags = append(flags, "up")
+		}
+		if ifi.Flags&net.FlagBroadcast != 0 {
+			flags = append(flags, "broadcast")
+		}
+		if ifi.Flags&net.FlagLoopback != 0 {
+			flags = append(flags, "loopback")
+		}
+		if ifi.Flags&net.FlagPointToPoint != 0 {
+			flags = append(flags, "pointtopoint")
+		}
+		if ifi.Flags&net.FlagMulticast != 0 {
+			flags = append(flags, "multicast")
+		}
+
+		r := InterfaceStat{
+			Name:         ifi.Name,
+			MTU:          ifi.MTU,
+			HardwareAddr: ifi.HardwareAddr.String(),
+			Flags:        flags,
+		}
+		addrs, err := ifi.Addrs()
+		if err == nil {
+			r.Addrs = make([]InterfaceAddr, 0, len(addrs))
+			for _, addr := range addrs {
+				r.Addrs = append(r.Addrs, InterfaceAddr{
+					Addr: addr.String(),
+				})
+			}
+
+		}
+		ret = append(ret, r)
+	}
+
+	return ret, nil
+}
+
+func getIOCountersAll(n []IOCountersStat) ([]IOCountersStat, error) {
+	r := IOCountersStat{
+		Name: "all",
+	}
+	for _, nic := range n {
+		r.BytesRecv += nic.BytesRecv
+		r.PacketsRecv += nic.PacketsRecv
+		r.Errin += nic.Errin
+		r.Dropin += nic.Dropin
+		r.BytesSent += nic.BytesSent
+		r.PacketsSent += nic.PacketsSent
+		r.Errout += nic.Errout
+		r.Dropout += nic.Dropout
+	}
+
+	return []IOCountersStat{r}, nil
+}
+
+func parseNetLine(line string) (ConnectionStat, error) {
+	f := strings.Fields(line)
+	if len(f) < 9 {
+		return ConnectionStat{}, fmt.Errorf("wrong line,%s", line)
+	}
+
+	pid, err := strconv.Atoi(f[1])
+	if err != nil {
+		return ConnectionStat{}, err
+	}
+	fd, err := strconv.Atoi(strings.Trim(f[3], "u"))
+	if err != nil {
+		return ConnectionStat{}, fmt.Errorf("unknown fd, %s", f[3])
+	}
+	netFamily, ok := constMap[f[4]]
+	if !ok {
+		return ConnectionStat{}, fmt.Errorf("unknown family, %s", f[4])
+	}
+	netType, ok := constMap[f[7]]
+	if !ok {
+		return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[7])
+	}
+
+	laddr, raddr, err := parseNetAddr(f[8])
+	if err != nil {
+		return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s", f[8])
+	}
+
+	n := ConnectionStat{
+		Fd:     uint32(fd),
+		Family: uint32(netFamily),
+		Type:   uint32(netType),
+		Laddr:  laddr,
+		Raddr:  raddr,
+		Pid:    int32(pid),
+	}
+	if len(f) == 10 {
+		n.Status = strings.Trim(f[9], "()")
+	}
+
+	return n, nil
+}
+
+func parseNetAddr(line string) (laddr Addr, raddr Addr, err error) {
+	parse := func(l string) (Addr, error) {
+		host, port, err := net.SplitHostPort(l)
+		if err != nil {
+			return Addr{}, fmt.Errorf("wrong addr, %s", l)
+		}
+		lport, err := strconv.Atoi(port)
+		if err != nil {
+			return Addr{}, err
+		}
+		return Addr{IP: host, Port: uint32(lport)}, nil
+	}
+
+	addrs := strings.Split(line, "->")
+	if len(addrs) == 0 {
+		return laddr, raddr, fmt.Errorf("wrong netaddr, %s", line)
+	}
+	laddr, err = parse(addrs[0])
+	if len(addrs) == 2 { // remote addr exists
+		raddr, err = parse(addrs[1])
+		if err != nil {
+			return laddr, raddr, err
+		}
+	}
+
+	return laddr, raddr, err
+}
diff --git a/go/src/github.com/shirou/gopsutil/net/net_darwin.go b/go/src/github.com/shirou/gopsutil/net/net_darwin.go
new file mode 100644
index 0000000..4fa358a
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/net/net_darwin.go
@@ -0,0 +1,114 @@
+// +build darwin
+
+package net
+
+import (
+	"errors"
+	"os/exec"
+	"strconv"
+	"strings"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+// example of netstat -idbn output on yosemite
+// Name  Mtu   Network       Address            Ipkts Ierrs     Ibytes    Opkts Oerrs     Obytes  Coll Drop
+// lo0   16384 <Link#1>                        869107     0  169411755   869107     0  169411755     0   0
+// lo0   16384 ::1/128     ::1                 869107     -  169411755   869107     -  169411755     -   -
+// lo0   16384 127           127.0.0.1         869107     -  169411755   869107     -  169411755     -   -
+func IOCounters(pernic bool) ([]IOCountersStat, error) {
+	netstat, err := exec.LookPath("/usr/sbin/netstat")
+	if err != nil {
+		return nil, err
+	}
+	out, err := exec.Command(netstat, "-ibdnW").Output()
+	if err != nil {
+		return nil, err
+	}
+
+	lines := strings.Split(string(out), "\n")
+	ret := make([]IOCountersStat, 0, len(lines)-1)
+	exists := make([]string, 0, len(ret))
+
+	for _, line := range lines {
+		values := strings.Fields(line)
+		if len(values) < 1 || values[0] == "Name" {
+			// skip first line
+			continue
+		}
+		if common.StringsHas(exists, values[0]) {
+			// skip if already get
+			continue
+		}
+		exists = append(exists, values[0])
+
+		base := 1
+		// sometimes Address is ommitted
+		if len(values) < 11 {
+			base = 0
+		}
+
+		parsed := make([]uint64, 0, 7)
+		vv := []string{
+			values[base+3], // Ipkts == PacketsRecv
+			values[base+4], // Ierrs == Errin
+			values[base+5], // Ibytes == BytesRecv
+			values[base+6], // Opkts == PacketsSent
+			values[base+7], // Oerrs == Errout
+			values[base+8], // Obytes == BytesSent
+		}
+		if len(values) == 12 {
+			vv = append(vv, values[base+10])
+		}
+
+		for _, target := range vv {
+			if target == "-" {
+				parsed = append(parsed, 0)
+				continue
+			}
+
+			t, err := strconv.ParseUint(target, 10, 64)
+			if err != nil {
+				return nil, err
+			}
+			parsed = append(parsed, t)
+		}
+
+		n := IOCountersStat{
+			Name:        values[0],
+			PacketsRecv: parsed[0],
+			Errin:       parsed[1],
+			BytesRecv:   parsed[2],
+			PacketsSent: parsed[3],
+			Errout:      parsed[4],
+			BytesSent:   parsed[5],
+		}
+		if len(parsed) == 7 {
+			n.Dropout = parsed[6]
+		}
+		ret = append(ret, n)
+	}
+
+	if pernic == false {
+		return getIOCountersAll(ret)
+	}
+
+	return ret, nil
+}
+
+// NetIOCountersByFile is an method which is added just a compatibility for linux.
+func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
+	return IOCounters(pernic)
+}
+
+func FilterCounters() ([]FilterStat, error) {
+	return nil, errors.New("NetFilterCounters not implemented for darwin")
+}
+
+// NetProtoCounters returns network statistics for the entire system
+// If protocols is empty then all protocols are returned, otherwise
+// just the protocols in the list are returned.
+// Not Implemented for Darwin
+func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
+	return nil, errors.New("NetProtoCounters not implemented for darwin")
+}
diff --git a/go/src/github.com/shirou/gopsutil/net/net_freebsd.go b/go/src/github.com/shirou/gopsutil/net/net_freebsd.go
new file mode 100644
index 0000000..3a67b4a
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/net/net_freebsd.go
@@ -0,0 +1,108 @@
+// +build freebsd
+
+package net
+
+import (
+	"errors"
+	"os/exec"
+	"strconv"
+	"strings"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func IOCounters(pernic bool) ([]IOCountersStat, error) {
+	netstat, err := exec.LookPath("/usr/bin/netstat")
+	if err != nil {
+		return nil, err
+	}
+	out, err := exec.Command(netstat, "-ibdnW").Output()
+	if err != nil {
+		return nil, err
+	}
+
+	lines := strings.Split(string(out), "\n")
+	ret := make([]IOCountersStat, 0, len(lines)-1)
+	exists := make([]string, 0, len(ret))
+
+	for _, line := range lines {
+		values := strings.Fields(line)
+		if len(values) < 1 || values[0] == "Name" {
+			continue
+		}
+		if common.StringsHas(exists, values[0]) {
+			// skip if already get
+			continue
+		}
+		exists = append(exists, values[0])
+
+		if len(values) < 12 {
+			continue
+		}
+		base := 1
+		// sometimes Address is ommitted
+		if len(values) < 13 {
+			base = 0
+		}
+
+		parsed := make([]uint64, 0, 8)
+		vv := []string{
+			values[base+3],  // PacketsRecv
+			values[base+4],  // Errin
+			values[base+5],  // Dropin
+			values[base+6],  // BytesRecvn
+			values[base+7],  // PacketSent
+			values[base+8],  // Errout
+			values[base+9],  // BytesSent
+			values[base+11], // Dropout
+		}
+		for _, target := range vv {
+			if target == "-" {
+				parsed = append(parsed, 0)
+				continue
+			}
+
+			t, err := strconv.ParseUint(target, 10, 64)
+			if err != nil {
+				return nil, err
+			}
+			parsed = append(parsed, t)
+		}
+
+		n := IOCountersStat{
+			Name:        values[0],
+			PacketsRecv: parsed[0],
+			Errin:       parsed[1],
+			Dropin:      parsed[2],
+			BytesRecv:   parsed[3],
+			PacketsSent: parsed[4],
+			Errout:      parsed[5],
+			BytesSent:   parsed[6],
+			Dropout:     parsed[7],
+		}
+		ret = append(ret, n)
+	}
+
+	if pernic == false {
+		return getIOCountersAll(ret)
+	}
+
+	return ret, nil
+}
+
+// NetIOCountersByFile is an method which is added just a compatibility for linux.
+func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
+	return IOCounters(pernic)
+}
+
+func FilterCounters() ([]FilterStat, error) {
+	return nil, errors.New("NetFilterCounters not implemented for freebsd")
+}
+
+// NetProtoCounters returns network statistics for the entire system
+// If protocols is empty then all protocols are returned, otherwise
+// just the protocols in the list are returned.
+// Not Implemented for FreeBSD
+func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
+	return nil, errors.New("NetProtoCounters not implemented for freebsd")
+}
diff --git a/go/src/github.com/shirou/gopsutil/net/net_linux.go b/go/src/github.com/shirou/gopsutil/net/net_linux.go
new file mode 100644
index 0000000..e024771
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/net/net_linux.go
@@ -0,0 +1,620 @@
+// +build linux
+
+package net
+
+import (
+	"encoding/hex"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"net"
+	"os"
+	"strconv"
+	"strings"
+	"syscall"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+// NetIOCounters returnes network I/O statistics for every network
+// interface installed on the system.  If pernic argument is false,
+// return only sum of all information (which name is 'all'). If true,
+// every network interface installed on the system is returned
+// separately.
+func IOCounters(pernic bool) ([]IOCountersStat, error) {
+	filename := common.HostProc("net/dev")
+	return IOCountersByFile(pernic, filename)
+}
+
+func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
+	lines, err := common.ReadLines(filename)
+	if err != nil {
+		return nil, err
+	}
+
+	statlen := len(lines) - 1
+
+	ret := make([]IOCountersStat, 0, statlen)
+
+	for _, line := range lines[2:] {
+		parts := strings.SplitN(line, ":", 2)
+		if len(parts) != 2 {
+			continue
+		}
+		interfaceName := strings.TrimSpace(parts[0])
+		if interfaceName == "" {
+			continue
+		}
+
+		fields := strings.Fields(strings.TrimSpace(parts[1]))
+		bytesRecv, err := strconv.ParseUint(fields[0], 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		packetsRecv, err := strconv.ParseUint(fields[1], 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		errIn, err := strconv.ParseUint(fields[2], 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		dropIn, err := strconv.ParseUint(fields[3], 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		bytesSent, err := strconv.ParseUint(fields[8], 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		packetsSent, err := strconv.ParseUint(fields[9], 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		errOut, err := strconv.ParseUint(fields[10], 10, 64)
+		if err != nil {
+			return ret, err
+		}
+		dropOut, err := strconv.ParseUint(fields[13], 10, 64)
+		if err != nil {
+			return ret, err
+		}
+
+		nic := IOCountersStat{
+			Name:        interfaceName,
+			BytesRecv:   bytesRecv,
+			PacketsRecv: packetsRecv,
+			Errin:       errIn,
+			Dropin:      dropIn,
+			BytesSent:   bytesSent,
+			PacketsSent: packetsSent,
+			Errout:      errOut,
+			Dropout:     dropOut,
+		}
+		ret = append(ret, nic)
+	}
+
+	if pernic == false {
+		return getIOCountersAll(ret)
+	}
+
+	return ret, nil
+}
+
+var netProtocols = []string{
+	"ip",
+	"icmp",
+	"icmpmsg",
+	"tcp",
+	"udp",
+	"udplite",
+}
+
+// NetProtoCounters returns network statistics for the entire system
+// If protocols is empty then all protocols are returned, otherwise
+// just the protocols in the list are returned.
+// Available protocols:
+//   ip,icmp,icmpmsg,tcp,udp,udplite
+func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
+	if len(protocols) == 0 {
+		protocols = netProtocols
+	}
+
+	stats := make([]ProtoCountersStat, 0, len(protocols))
+	protos := make(map[string]bool, len(protocols))
+	for _, p := range protocols {
+		protos[p] = true
+	}
+
+	filename := common.HostProc("net/snmp")
+	lines, err := common.ReadLines(filename)
+	if err != nil {
+		return nil, err
+	}
+
+	linecount := len(lines)
+	for i := 0; i < linecount; i++ {
+		line := lines[i]
+		r := strings.IndexRune(line, ':')
+		if r == -1 {
+			return nil, errors.New(filename + " is not fomatted correctly, expected ':'.")
+		}
+		proto := strings.ToLower(line[:r])
+		if !protos[proto] {
+			// skip protocol and data line
+			i++
+			continue
+		}
+
+		// Read header line
+		statNames := strings.Split(line[r+2:], " ")
+
+		// Read data line
+		i++
+		statValues := strings.Split(lines[i][r+2:], " ")
+		if len(statNames) != len(statValues) {
+			return nil, errors.New(filename + " is not fomatted correctly, expected same number of columns.")
+		}
+		stat := ProtoCountersStat{
+			Protocol: proto,
+			Stats:    make(map[string]int64, len(statNames)),
+		}
+		for j := range statNames {
+			value, err := strconv.ParseInt(statValues[j], 10, 64)
+			if err != nil {
+				return nil, err
+			}
+			stat.Stats[statNames[j]] = value
+		}
+		stats = append(stats, stat)
+	}
+	return stats, nil
+}
+
+// NetFilterCounters returns iptables conntrack statistics
+// the currently in use conntrack count and the max.
+// If the file does not exist or is invalid it will return nil.
+func FilterCounters() ([]FilterStat, error) {
+	countfile := common.HostProc("sys/net/netfilter/nf_conntrackCount")
+	maxfile := common.HostProc("sys/net/netfilter/nf_conntrackMax")
+
+	count, err := common.ReadInts(countfile)
+
+	if err != nil {
+		return nil, err
+	}
+	stats := make([]FilterStat, 0, 1)
+
+	max, err := common.ReadInts(maxfile)
+	if err != nil {
+		return nil, err
+	}
+
+	payload := FilterStat{
+		ConnTrackCount: count[0],
+		ConnTrackMax:   max[0],
+	}
+
+	stats = append(stats, payload)
+	return stats, nil
+}
+
+// http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
+var TCPStatuses = map[string]string{
+	"01": "ESTABLISHED",
+	"02": "SYN_SENT",
+	"03": "SYN_RECV",
+	"04": "FIN_WAIT1",
+	"05": "FIN_WAIT2",
+	"06": "TIME_WAIT",
+	"07": "CLOSE",
+	"08": "CLOSE_WAIT",
+	"09": "LAST_ACK",
+	"0A": "LISTEN",
+	"0B": "CLOSING",
+}
+
+type netConnectionKindType struct {
+	family   uint32
+	sockType uint32
+	filename string
+}
+
+var kindTCP4 = netConnectionKindType{
+	family:   syscall.AF_INET,
+	sockType: syscall.SOCK_STREAM,
+	filename: "tcp",
+}
+var kindTCP6 = netConnectionKindType{
+	family:   syscall.AF_INET6,
+	sockType: syscall.SOCK_STREAM,
+	filename: "tcp6",
+}
+var kindUDP4 = netConnectionKindType{
+	family:   syscall.AF_INET,
+	sockType: syscall.SOCK_DGRAM,
+	filename: "udp",
+}
+var kindUDP6 = netConnectionKindType{
+	family:   syscall.AF_INET6,
+	sockType: syscall.SOCK_DGRAM,
+	filename: "udp6",
+}
+var kindUNIX = netConnectionKindType{
+	family:   syscall.AF_UNIX,
+	filename: "unix",
+}
+
+var netConnectionKindMap = map[string][]netConnectionKindType{
+	"all":   []netConnectionKindType{kindTCP4, kindTCP6, kindUDP4, kindUDP6, kindUNIX},
+	"tcp":   []netConnectionKindType{kindTCP4, kindTCP6},
+	"tcp4":  []netConnectionKindType{kindTCP4},
+	"tcp6":  []netConnectionKindType{kindTCP6},
+	"udp":   []netConnectionKindType{kindUDP4, kindUDP6},
+	"udp4":  []netConnectionKindType{kindUDP4},
+	"udp6":  []netConnectionKindType{kindUDP6},
+	"unix":  []netConnectionKindType{kindUNIX},
+	"inet":  []netConnectionKindType{kindTCP4, kindTCP6, kindUDP4, kindUDP6},
+	"inet4": []netConnectionKindType{kindTCP4, kindUDP4},
+	"inet6": []netConnectionKindType{kindTCP6, kindUDP6},
+}
+
+type inodeMap struct {
+	pid int32
+	fd  uint32
+}
+
+type connTmp struct {
+	fd       uint32
+	family   uint32
+	sockType uint32
+	laddr    Addr
+	raddr    Addr
+	status   string
+	pid      int32
+	boundPid int32
+	path     string
+}
+
+// Return a list of network connections opened.
+func Connections(kind string) ([]ConnectionStat, error) {
+	return ConnectionsPid(kind, 0)
+}
+
+// Return a list of network connections opened by a process.
+func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) {
+	tmap, ok := netConnectionKindMap[kind]
+	if !ok {
+		return nil, fmt.Errorf("invalid kind, %s", kind)
+	}
+	root := common.HostProc()
+	var err error
+	var inodes map[string][]inodeMap
+	if pid == 0 {
+		inodes, err = getProcInodesAll(root)
+	} else {
+		inodes, err = getProcInodes(root, pid)
+		if len(inodes) == 0 {
+			// no connection for the pid
+			return []ConnectionStat{}, nil
+		}
+	}
+	if err != nil {
+		return nil, fmt.Errorf("cound not get pid(s), %d", pid)
+	}
+
+	dupCheckMap := make(map[string]bool)
+	var ret []ConnectionStat
+
+	for _, t := range tmap {
+		var path string
+		var ls []connTmp
+		path = fmt.Sprintf("%s/net/%s", root, t.filename)
+		switch t.family {
+		case syscall.AF_INET:
+			fallthrough
+		case syscall.AF_INET6:
+			ls, err = processInet(path, t, inodes, pid)
+		case syscall.AF_UNIX:
+			ls, err = processUnix(path, t, inodes, pid)
+		}
+		if err != nil {
+			return nil, err
+		}
+		for _, c := range ls {
+			conn := ConnectionStat{
+				Fd:     c.fd,
+				Family: c.family,
+				Type:   c.sockType,
+				Laddr:  c.laddr,
+				Raddr:  c.raddr,
+				Status: c.status,
+				Pid:    c.pid,
+			}
+			if c.pid == 0 {
+				conn.Pid = c.boundPid
+			} else {
+				conn.Pid = c.pid
+			}
+			// check duplicate using JSON format
+			json := conn.String()
+			_, exists := dupCheckMap[json]
+			if !exists {
+				ret = append(ret, conn)
+				dupCheckMap[json] = true
+			}
+		}
+
+	}
+
+	return ret, nil
+}
+
+// getProcInodes returnes fd of the pid.
+func getProcInodes(root string, pid int32) (map[string][]inodeMap, error) {
+	ret := make(map[string][]inodeMap)
+
+	dir := fmt.Sprintf("%s/%d/fd", root, pid)
+	files, err := ioutil.ReadDir(dir)
+	if err != nil {
+		return ret, nil
+	}
+	for _, fd := range files {
+		inodePath := fmt.Sprintf("%s/%d/fd/%s", root, pid, fd.Name())
+
+		inode, err := os.Readlink(inodePath)
+		if err != nil {
+			continue
+		}
+		if !strings.HasPrefix(inode, "socket:[") {
+			continue
+		}
+		// the process is using a socket
+		l := len(inode)
+		inode = inode[8 : l-1]
+		_, ok := ret[inode]
+		if !ok {
+			ret[inode] = make([]inodeMap, 0)
+		}
+		fd, err := strconv.Atoi(fd.Name())
+		if err != nil {
+			continue
+		}
+
+		i := inodeMap{
+			pid: pid,
+			fd:  uint32(fd),
+		}
+		ret[inode] = append(ret[inode], i)
+	}
+	return ret, nil
+}
+
+// Pids retunres all pids.
+// Note: this is a copy of process_linux.Pids()
+// FIXME: Import process occures import cycle.
+// move to common made other platform breaking. Need consider.
+func Pids() ([]int32, error) {
+	var ret []int32
+
+	d, err := os.Open(common.HostProc())
+	if err != nil {
+		return nil, err
+	}
+	defer d.Close()
+
+	fnames, err := d.Readdirnames(-1)
+	if err != nil {
+		return nil, err
+	}
+	for _, fname := range fnames {
+		pid, err := strconv.ParseInt(fname, 10, 32)
+		if err != nil {
+			// if not numeric name, just skip
+			continue
+		}
+		ret = append(ret, int32(pid))
+	}
+
+	return ret, nil
+}
+
+func getProcInodesAll(root string) (map[string][]inodeMap, error) {
+	pids, err := Pids()
+	if err != nil {
+		return nil, err
+	}
+	ret := make(map[string][]inodeMap)
+
+	for _, pid := range pids {
+		t, err := getProcInodes(root, pid)
+		if err != nil {
+			return ret, err
+		}
+		if len(t) == 0 {
+			continue
+		}
+		// TODO: update ret.
+		ret = updateMap(ret, t)
+	}
+	return ret, nil
+}
+
+// decodeAddress decode addresse represents addr in proc/net/*
+// ex:
+// "0500000A:0016" -> "10.0.0.5", 22
+// "0085002452100113070057A13F025401:0035" -> "2400:8500:1301:1052:a157:7:154:23f", 53
+func decodeAddress(family uint32, src string) (Addr, error) {
+	t := strings.Split(src, ":")
+	if len(t) != 2 {
+		return Addr{}, fmt.Errorf("does not contain port, %s", src)
+	}
+	addr := t[0]
+	port, err := strconv.ParseInt("0x"+t[1], 0, 64)
+	if err != nil {
+		return Addr{}, fmt.Errorf("invalid port, %s", src)
+	}
+	decoded, err := hex.DecodeString(addr)
+	if err != nil {
+		return Addr{}, fmt.Errorf("decode error, %s", err)
+	}
+	var ip net.IP
+	// Assumes this is little_endian
+	if family == syscall.AF_INET {
+		ip = net.IP(Reverse(decoded))
+	} else { // IPv6
+		ip, err = parseIPv6HexString(decoded)
+		if err != nil {
+			return Addr{}, err
+		}
+	}
+	return Addr{
+		IP:   ip.String(),
+		Port: uint32(port),
+	}, nil
+}
+
+// Reverse reverses array of bytes.
+func Reverse(s []byte) []byte {
+	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
+		s[i], s[j] = s[j], s[i]
+	}
+	return s
+}
+
+// parseIPv6HexString parse array of bytes to IPv6 string
+func parseIPv6HexString(src []byte) (net.IP, error) {
+	if len(src) != 16 {
+		return nil, fmt.Errorf("invalid IPv6 string")
+	}
+
+	buf := make([]byte, 0, 16)
+	for i := 0; i < len(src); i += 4 {
+		r := Reverse(src[i : i+4])
+		buf = append(buf, r...)
+	}
+	return net.IP(buf), nil
+}
+
+func processInet(file string, kind netConnectionKindType, inodes map[string][]inodeMap, filterPid int32) ([]connTmp, error) {
+
+	if strings.HasSuffix(file, "6") && !common.PathExists(file) {
+		// IPv6 not supported, return empty.
+		return []connTmp{}, nil
+	}
+	lines, err := common.ReadLines(file)
+	if err != nil {
+		return nil, err
+	}
+	var ret []connTmp
+	// skip first line
+	for _, line := range lines[1:] {
+		l := strings.Fields(line)
+		if len(l) < 10 {
+			continue
+		}
+		laddr := l[1]
+		raddr := l[2]
+		status := l[3]
+		inode := l[9]
+		pid := int32(0)
+		fd := uint32(0)
+		i, exists := inodes[inode]
+		if exists {
+			pid = i[0].pid
+			fd = i[0].fd
+		}
+		if filterPid > 0 && filterPid != pid {
+			continue
+		}
+		if kind.sockType == syscall.SOCK_STREAM {
+			status = TCPStatuses[status]
+		} else {
+			status = "NONE"
+		}
+		la, err := decodeAddress(kind.family, laddr)
+		if err != nil {
+			continue
+		}
+		ra, err := decodeAddress(kind.family, raddr)
+		if err != nil {
+			continue
+		}
+
+		ret = append(ret, connTmp{
+			fd:       fd,
+			family:   kind.family,
+			sockType: kind.sockType,
+			laddr:    la,
+			raddr:    ra,
+			status:   status,
+			pid:      pid,
+		})
+	}
+
+	return ret, nil
+}
+
+func processUnix(file string, kind netConnectionKindType, inodes map[string][]inodeMap, filterPid int32) ([]connTmp, error) {
+	lines, err := common.ReadLines(file)
+	if err != nil {
+		return nil, err
+	}
+
+	var ret []connTmp
+	// skip first line
+	for _, line := range lines[1:] {
+		tokens := strings.Fields(line)
+		if len(tokens) < 6 {
+			continue
+		}
+		st, err := strconv.Atoi(tokens[4])
+		if err != nil {
+			return nil, err
+		}
+
+		inode := tokens[6]
+
+		var pairs []inodeMap
+		pairs, exists := inodes[inode]
+		if !exists {
+			pairs = []inodeMap{
+				inodeMap{},
+			}
+		}
+		for _, pair := range pairs {
+			if filterPid > 0 && filterPid != pair.pid {
+				continue
+			}
+			var path string
+			if len(tokens) == 8 {
+				path = tokens[len(tokens)-1]
+			}
+			ret = append(ret, connTmp{
+				fd:       pair.fd,
+				family:   kind.family,
+				sockType: uint32(st),
+				laddr: Addr{
+					IP: path,
+				},
+				pid:    pair.pid,
+				status: "NONE",
+				path:   path,
+			})
+		}
+	}
+
+	return ret, nil
+}
+
+func updateMap(src map[string][]inodeMap, add map[string][]inodeMap) map[string][]inodeMap {
+	for key, value := range add {
+		a, exists := src[key]
+		if !exists {
+			src[key] = value
+			continue
+		}
+		src[key] = append(a, value...)
+	}
+	return src
+}
diff --git a/go/src/github.com/shirou/gopsutil/net/net_linux_test.go b/go/src/github.com/shirou/gopsutil/net/net_linux_test.go
new file mode 100644
index 0000000..47faeb9
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/net/net_linux_test.go
@@ -0,0 +1,75 @@
+package net
+
+import (
+	"os"
+	"syscall"
+	"testing"
+
+	"github.com/shirou/gopsutil/internal/common"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestGetProcInodesAll(t *testing.T) {
+	if os.Getenv("CIRCLECI") == "true" {
+		t.Skip("Skip CI")
+	}
+
+	root := common.HostProc("")
+	v, err := getProcInodesAll(root)
+	assert.Nil(t, err)
+	assert.NotEmpty(t, v)
+}
+
+type AddrTest struct {
+	IP    string
+	Port  int
+	Error bool
+}
+
+func TestDecodeAddress(t *testing.T) {
+	assert := assert.New(t)
+
+	addr := map[string]AddrTest{
+		"0500000A:0016": AddrTest{
+			IP:   "10.0.0.5",
+			Port: 22,
+		},
+		"0100007F:D1C2": AddrTest{
+			IP:   "127.0.0.1",
+			Port: 53698,
+		},
+		"11111:0035": AddrTest{
+			Error: true,
+		},
+		"0100007F:BLAH": AddrTest{
+			Error: true,
+		},
+		"0085002452100113070057A13F025401:0035": AddrTest{
+			IP:   "2400:8500:1301:1052:a157:7:154:23f",
+			Port: 53,
+		},
+		"00855210011307F025401:0035": AddrTest{
+			Error: true,
+		},
+	}
+
+	for src, dst := range addr {
+		family := syscall.AF_INET
+		if len(src) > 13 {
+			family = syscall.AF_INET6
+		}
+		addr, err := decodeAddress(uint32(family), src)
+		if dst.Error {
+			assert.NotNil(err, src)
+		} else {
+			assert.Nil(err, src)
+			assert.Equal(dst.IP, addr.IP, src)
+			assert.Equal(dst.Port, int(addr.Port), src)
+		}
+	}
+}
+
+func TestReverse(t *testing.T) {
+	src := []byte{0x01, 0x02, 0x03}
+	assert.Equal(t, []byte{0x03, 0x02, 0x01}, Reverse(src))
+}
diff --git a/go/src/github.com/shirou/gopsutil/net/net_test.go b/go/src/github.com/shirou/gopsutil/net/net_test.go
new file mode 100644
index 0000000..88748be
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/net/net_test.go
@@ -0,0 +1,228 @@
+package net
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+	"testing"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+func TestAddrString(t *testing.T) {
+	v := Addr{IP: "192.168.0.1", Port: 8000}
+
+	s := fmt.Sprintf("%v", v)
+	if s != "{\"ip\":\"192.168.0.1\",\"port\":8000}" {
+		t.Errorf("Addr string is invalid: %v", v)
+	}
+}
+
+func TestNetIOCountersStatString(t *testing.T) {
+	v := IOCountersStat{
+		Name:      "test",
+		BytesSent: 100,
+	}
+	e := `{"name":"test","bytesSent":100,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("NetIOCountersStat string is invalid: %v", v)
+	}
+}
+
+func TestNetProtoCountersStatString(t *testing.T) {
+	v := ProtoCountersStat{
+		Protocol: "tcp",
+		Stats: map[string]int64{
+			"MaxConn":      -1,
+			"ActiveOpens":  4000,
+			"PassiveOpens": 3000,
+		},
+	}
+	e := `{"protocol":"tcp","stats":{"ActiveOpens":4000,"MaxConn":-1,"PassiveOpens":3000}}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("NetProtoCountersStat string is invalid: %v", v)
+	}
+
+}
+
+func TestNetConnectionStatString(t *testing.T) {
+	v := ConnectionStat{
+		Fd:     10,
+		Family: 10,
+		Type:   10,
+	}
+	e := `{"fd":10,"family":10,"type":10,"localaddr":{"ip":"","port":0},"remoteaddr":{"ip":"","port":0},"status":"","pid":0}`
+	if e != fmt.Sprintf("%v", v) {
+		t.Errorf("NetConnectionStat string is invalid: %v", v)
+	}
+
+}
+
+func TestNetIOCountersAll(t *testing.T) {
+	v, err := IOCounters(false)
+	per, err := IOCounters(true)
+	if err != nil {
+		t.Errorf("Could not get NetIOCounters: %v", err)
+	}
+	if len(v) != 1 {
+		t.Errorf("Could not get NetIOCounters: %v", v)
+	}
+	if v[0].Name != "all" {
+		t.Errorf("Invalid NetIOCounters: %v", v)
+	}
+	var pr uint64
+	for _, p := range per {
+		pr += p.PacketsRecv
+	}
+	if v[0].PacketsRecv != pr {
+		t.Errorf("invalid sum value: %v, %v", v[0].PacketsRecv, pr)
+	}
+}
+
+func TestNetIOCountersPerNic(t *testing.T) {
+	v, err := IOCounters(true)
+	if err != nil {
+		t.Errorf("Could not get NetIOCounters: %v", err)
+	}
+	if len(v) == 0 {
+		t.Errorf("Could not get NetIOCounters: %v", v)
+	}
+	for _, vv := range v {
+		if vv.Name == "" {
+			t.Errorf("Invalid NetIOCounters: %v", vv)
+		}
+	}
+}
+
+func TestGetNetIOCountersAll(t *testing.T) {
+	n := []IOCountersStat{
+		IOCountersStat{
+			Name:        "a",
+			BytesRecv:   10,
+			PacketsRecv: 10,
+		},
+		IOCountersStat{
+			Name:        "b",
+			BytesRecv:   10,
+			PacketsRecv: 10,
+			Errin:       10,
+		},
+	}
+	ret, err := getIOCountersAll(n)
+	if err != nil {
+		t.Error(err)
+	}
+	if len(ret) != 1 {
+		t.Errorf("invalid return count")
+	}
+	if ret[0].Name != "all" {
+		t.Errorf("invalid return name")
+	}
+	if ret[0].BytesRecv != 20 {
+		t.Errorf("invalid count bytesrecv")
+	}
+	if ret[0].Errin != 10 {
+		t.Errorf("invalid count errin")
+	}
+}
+
+func TestNetInterfaces(t *testing.T) {
+	v, err := Interfaces()
+	if err != nil {
+		t.Errorf("Could not get NetInterfaceStat: %v", err)
+	}
+	if len(v) == 0 {
+		t.Errorf("Could not get NetInterfaceStat: %v", err)
+	}
+	for _, vv := range v {
+		if vv.Name == "" {
+			t.Errorf("Invalid NetInterface: %v", vv)
+		}
+	}
+}
+
+func TestNetProtoCountersStatsAll(t *testing.T) {
+	v, err := ProtoCounters(nil)
+	if err != nil {
+		t.Fatalf("Could not get NetProtoCounters: %v", err)
+	}
+	if len(v) == 0 {
+		t.Fatalf("Could not get NetProtoCounters: %v", err)
+	}
+	for _, vv := range v {
+		if vv.Protocol == "" {
+			t.Errorf("Invalid NetProtoCountersStat: %v", vv)
+		}
+		if len(vv.Stats) == 0 {
+			t.Errorf("Invalid NetProtoCountersStat: %v", vv)
+		}
+	}
+}
+
+func TestNetProtoCountersStats(t *testing.T) {
+	v, err := ProtoCounters([]string{"tcp", "ip"})
+	if err != nil {
+		t.Fatalf("Could not get NetProtoCounters: %v", err)
+	}
+	if len(v) == 0 {
+		t.Fatalf("Could not get NetProtoCounters: %v", err)
+	}
+	if len(v) != 2 {
+		t.Fatalf("Go incorrect number of NetProtoCounters: %v", err)
+	}
+	for _, vv := range v {
+		if vv.Protocol != "tcp" && vv.Protocol != "ip" {
+			t.Errorf("Invalid NetProtoCountersStat: %v", vv)
+		}
+		if len(vv.Stats) == 0 {
+			t.Errorf("Invalid NetProtoCountersStat: %v", vv)
+		}
+	}
+}
+
+func TestNetConnections(t *testing.T) {
+	if ci := os.Getenv("CI"); ci != "" { // skip if test on drone.io
+		return
+	}
+
+	v, err := Connections("inet")
+	if err != nil {
+		t.Errorf("could not get NetConnections: %v", err)
+	}
+	if len(v) == 0 {
+		t.Errorf("could not get NetConnections: %v", v)
+	}
+	for _, vv := range v {
+		if vv.Family == 0 {
+			t.Errorf("invalid NetConnections: %v", vv)
+		}
+	}
+
+}
+
+func TestNetFilterCounters(t *testing.T) {
+	if ci := os.Getenv("CI"); ci != "" { // skip if test on drone.io
+		return
+	}
+
+	if runtime.GOOS == "linux" {
+		// some test environment has not the path.
+		if !common.PathExists("/proc/sys/net/netfilter/nf_conntrackCount") {
+			t.SkipNow()
+		}
+	}
+
+	v, err := FilterCounters()
+	if err != nil {
+		t.Errorf("could not get NetConnections: %v", err)
+	}
+	if len(v) == 0 {
+		t.Errorf("could not get NetConnections: %v", v)
+	}
+	for _, vv := range v {
+		if vv.ConnTrackMax == 0 {
+			t.Errorf("nf_conntrackMax needs to be greater than zero: %v", vv)
+		}
+	}
+
+}
diff --git a/go/src/github.com/shirou/gopsutil/net/net_unix.go b/go/src/github.com/shirou/gopsutil/net/net_unix.go
new file mode 100644
index 0000000..45de6b1
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/net/net_unix.go
@@ -0,0 +1,68 @@
+// +build freebsd darwin
+
+package net
+
+import (
+	"strings"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+// Return a list of network connections opened.
+func Connections(kind string) ([]ConnectionStat, error) {
+	return ConnectionsPid(kind, 0)
+}
+
+// Return a list of network connections opened by a process.
+func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) {
+	var ret []ConnectionStat
+
+	args := []string{"-i"}
+	switch strings.ToLower(kind) {
+	default:
+		fallthrough
+	case "":
+		fallthrough
+	case "all":
+		fallthrough
+	case "inet":
+		args = append(args, "tcp", "-i", "udp")
+	case "inet4":
+		args = append(args, "4")
+	case "inet6":
+		args = append(args, "6")
+	case "tcp":
+		args = append(args, "tcp")
+	case "tcp4":
+		args = append(args, "4tcp")
+	case "tcp6":
+		args = append(args, "6tcp")
+	case "udp":
+		args = append(args, "udp")
+	case "udp4":
+		args = append(args, "6udp")
+	case "udp6":
+		args = append(args, "6udp")
+	case "unix":
+		return ret, common.ErrNotImplementedError
+	}
+
+	r, err := common.CallLsof(invoke, pid, args...)
+	if err != nil {
+		return nil, err
+	}
+	for _, rr := range r {
+		if strings.HasPrefix(rr, "COMMAND") {
+			continue
+		}
+		n, err := parseNetLine(rr)
+		if err != nil {
+
+			continue
+		}
+
+		ret = append(ret, n)
+	}
+
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/net/net_windows.go b/go/src/github.com/shirou/gopsutil/net/net_windows.go
new file mode 100644
index 0000000..f125260
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/net/net_windows.go
@@ -0,0 +1,116 @@
+// +build windows
+
+package net
+
+import (
+	"errors"
+	"net"
+	"os"
+	"syscall"
+	"unsafe"
+
+	"github.com/shirou/gopsutil/internal/common"
+)
+
+var (
+	modiphlpapi             = syscall.NewLazyDLL("iphlpapi.dll")
+	procGetExtendedTCPTable = modiphlpapi.NewProc("GetExtendedTcpTable")
+	procGetExtendedUDPTable = modiphlpapi.NewProc("GetExtendedUdpTable")
+)
+
+const (
+	TCPTableBasicListener = iota
+	TCPTableBasicConnections
+	TCPTableBasicAll
+	TCPTableOwnerPIDListener
+	TCPTableOwnerPIDConnections
+	TCPTableOwnerPIDAll
+	TCPTableOwnerModuleListener
+	TCPTableOwnerModuleConnections
+	TCPTableOwnerModuleAll
+)
+
+func IOCounters(pernic bool) ([]IOCountersStat, error) {
+	ifs, err := net.Interfaces()
+	if err != nil {
+		return nil, err
+	}
+
+	ai, err := getAdapterList()
+	if err != nil {
+		return nil, err
+	}
+	var ret []IOCountersStat
+
+	for _, ifi := range ifs {
+		name := ifi.Name
+		for ; ai != nil; ai = ai.Next {
+			name = common.BytePtrToString(&ai.Description[0])
+			c := IOCountersStat{
+				Name: name,
+			}
+
+			row := syscall.MibIfRow{Index: ai.Index}
+			e := syscall.GetIfEntry(&row)
+			if e != nil {
+				return nil, os.NewSyscallError("GetIfEntry", e)
+			}
+			c.BytesSent = uint64(row.OutOctets)
+			c.BytesRecv = uint64(row.InOctets)
+			c.PacketsSent = uint64(row.OutUcastPkts)
+			c.PacketsRecv = uint64(row.InUcastPkts)
+			c.Errin = uint64(row.InErrors)
+			c.Errout = uint64(row.OutErrors)
+			c.Dropin = uint64(row.InDiscards)
+			c.Dropout = uint64(row.OutDiscards)
+
+			ret = append(ret, c)
+		}
+	}
+
+	if pernic == false {
+		return getIOCountersAll(ret)
+	}
+	return ret, nil
+}
+
+// NetIOCountersByFile is an method which is added just a compatibility for linux.
+func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
+	return IOCounters(pernic)
+}
+
+// Return a list of network connections opened by a process
+func Connections(kind string) ([]ConnectionStat, error) {
+	var ret []ConnectionStat
+
+	return ret, common.ErrNotImplementedError
+}
+
+// borrowed from src/pkg/net/interface_windows.go
+func getAdapterList() (*syscall.IpAdapterInfo, error) {
+	b := make([]byte, 1000)
+	l := uint32(len(b))
+	a := (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
+	err := syscall.GetAdaptersInfo(a, &l)
+	if err == syscall.ERROR_BUFFER_OVERFLOW {
+		b = make([]byte, l)
+		a = (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
+		err = syscall.GetAdaptersInfo(a, &l)
+	}
+	if err != nil {
+		return nil, os.NewSyscallError("GetAdaptersInfo", err)
+	}
+	return a, nil
+}
+
+func FilterCounters() ([]FilterStat, error) {
+	return nil, errors.New("NetFilterCounters not implemented for windows")
+}
+
+// NetProtoCounters returns network statistics for the entire system
+// If protocols is empty then all protocols are returned, otherwise
+// just the protocols in the list are returned.
+// Not Implemented for Windows
+func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
+	return nil, errors.New("NetProtoCounters not implemented for windows")
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/expected/darwin/%2Fbin%2Fps-ax-opid_fail b/go/src/github.com/shirou/gopsutil/process/expected/darwin/%2Fbin%2Fps-ax-opid_fail
new file mode 100644
index 0000000..fce59ef
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/expected/darwin/%2Fbin%2Fps-ax-opid_fail
@@ -0,0 +1,10 @@
+  PID
+  245
+  247
+  248
+  249
+  254
+  262
+  264
+  265
+  267
diff --git a/go/src/github.com/shirou/gopsutil/process/process.go b/go/src/github.com/shirou/gopsutil/process/process.go
new file mode 100644
index 0000000..4b69224
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process.go
@@ -0,0 +1,167 @@
+package process
+
+import (
+	"encoding/json"
+	"runtime"
+	"time"
+
+	"github.com/shirou/gopsutil/cpu"
+	"github.com/shirou/gopsutil/internal/common"
+	"github.com/shirou/gopsutil/mem"
+)
+
+var invoke common.Invoker
+
+func init() {
+	invoke = common.Invoke{}
+}
+
+type Process struct {
+	Pid            int32 `json:"pid"`
+	name           string
+	status         string
+	parent         int32
+	numCtxSwitches *NumCtxSwitchesStat
+	uids           []int32
+	gids           []int32
+	numThreads     int32
+	memInfo        *MemoryInfoStat
+
+	lastCPUTimes *cpu.TimesStat
+	lastCPUTime  time.Time
+}
+
+type OpenFilesStat struct {
+	Path string `json:"path"`
+	Fd   uint64 `json:"fd"`
+}
+
+type MemoryInfoStat struct {
+	RSS  uint64 `json:"rss"`  // bytes
+	VMS  uint64 `json:"vms"`  // bytes
+	Swap uint64 `json:"swap"` // bytes
+}
+
+type RlimitStat struct {
+	Resource int32 `json:"resource"`
+	Soft     int32 `json:"soft"`
+	Hard     int32 `json:"hard"`
+}
+
+type IOCountersStat struct {
+	ReadCount  uint64 `json:"readCount"`
+	WriteCount uint64 `json:"writeCount"`
+	ReadBytes  uint64 `json:"readBytes"`
+	WriteBytes uint64 `json:"writeBytes"`
+}
+
+type NumCtxSwitchesStat struct {
+	Voluntary   int64 `json:"voluntary"`
+	Involuntary int64 `json:"involuntary"`
+}
+
+func (p Process) String() string {
+	s, _ := json.Marshal(p)
+	return string(s)
+}
+
+func (o OpenFilesStat) String() string {
+	s, _ := json.Marshal(o)
+	return string(s)
+}
+
+func (m MemoryInfoStat) String() string {
+	s, _ := json.Marshal(m)
+	return string(s)
+}
+
+func (r RlimitStat) String() string {
+	s, _ := json.Marshal(r)
+	return string(s)
+}
+
+func (i IOCountersStat) String() string {
+	s, _ := json.Marshal(i)
+	return string(s)
+}
+
+func (p NumCtxSwitchesStat) String() string {
+	s, _ := json.Marshal(p)
+	return string(s)
+}
+
+func PidExists(pid int32) (bool, error) {
+	pids, err := Pids()
+	if err != nil {
+		return false, err
+	}
+
+	for _, i := range pids {
+		if i == pid {
+			return true, err
+		}
+	}
+
+	return false, err
+}
+
+// If interval is 0, return difference from last call(non-blocking).
+// If interval > 0, wait interval sec and return diffrence between start and end.
+func (p *Process) Percent(interval time.Duration) (float64, error) {
+	cpuTimes, err := p.Times()
+	if err != nil {
+		return 0, err
+	}
+	now := time.Now()
+
+	if interval > 0 {
+		p.lastCPUTimes = cpuTimes
+		p.lastCPUTime = now
+		time.Sleep(interval)
+		cpuTimes, err = p.Times()
+		now = time.Now()
+		if err != nil {
+			return 0, err
+		}
+	} else {
+		if p.lastCPUTimes == nil {
+			// invoked first time
+			p.lastCPUTimes = cpuTimes
+			p.lastCPUTime = now
+			return 0, nil
+		}
+	}
+
+	numcpu := runtime.NumCPU()
+	delta := (now.Sub(p.lastCPUTime).Seconds()) * float64(numcpu)
+	ret := calculatePercent(p.lastCPUTimes, cpuTimes, delta, numcpu)
+	p.lastCPUTimes = cpuTimes
+	p.lastCPUTime = now
+	return ret, nil
+}
+
+func calculatePercent(t1, t2 *cpu.TimesStat, delta float64, numcpu int) float64 {
+	if delta == 0 {
+		return 0
+	}
+	delta_proc := t2.Total() - t1.Total()
+	overall_percent := ((delta_proc / delta) * 100) * float64(numcpu)
+	return overall_percent
+}
+
+// MemoryPercent returns how many percent of the total RAM this process uses
+func (p *Process) MemoryPercent() (float32, error) {
+	machineMemory, err := mem.VirtualMemory()
+	if err != nil {
+		return 0, err
+	}
+	total := machineMemory.Total
+
+	processMemory, err := p.MemoryInfo()
+	if err != nil {
+		return 0, err
+	}
+	used := processMemory.RSS
+
+	return (100 * float32(used) / float32(total)), nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/process_darwin.go b/go/src/github.com/shirou/gopsutil/process/process_darwin.go
new file mode 100644
index 0000000..cea0803
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_darwin.go
@@ -0,0 +1,451 @@
+// +build darwin
+
+package process
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"os/exec"
+	"strconv"
+	"strings"
+	"syscall"
+	"unsafe"
+
+	"github.com/shirou/gopsutil/cpu"
+	"github.com/shirou/gopsutil/internal/common"
+	"github.com/shirou/gopsutil/net"
+)
+
+// copied from sys/sysctl.h
+const (
+	CTLKern          = 1  // "high kernel": proc, limits
+	KernProc         = 14 // struct: process entries
+	KernProcPID      = 1  // by process id
+	KernProcProc     = 8  // only return procs
+	KernProcAll      = 0  // everything
+	KernProcPathname = 12 // path to executable
+)
+
+const (
+	ClockTicks = 100 // C.sysconf(C._SC_CLK_TCK)
+)
+
+type _Ctype_struct___0 struct {
+	Pad uint64
+}
+
+// MemoryInfoExStat is different between OSes
+type MemoryInfoExStat struct {
+}
+
+type MemoryMapsStat struct {
+}
+
+func Pids() ([]int32, error) {
+	var ret []int32
+
+	pids, err := callPs("pid", 0, false)
+	if err != nil {
+		return ret, err
+	}
+
+	for _, pid := range pids {
+		v, err := strconv.Atoi(pid[0])
+		if err != nil {
+			return ret, err
+		}
+		ret = append(ret, int32(v))
+	}
+
+	return ret, nil
+}
+
+func (p *Process) Ppid() (int32, error) {
+	r, err := callPs("ppid", p.Pid, false)
+	v, err := strconv.Atoi(r[0][0])
+	if err != nil {
+		return 0, err
+	}
+
+	return int32(v), err
+}
+func (p *Process) Name() (string, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return "", err
+	}
+
+	return common.IntToString(k.Proc.P_comm[:]), nil
+}
+func (p *Process) Exe() (string, error) {
+	return "", common.ErrNotImplementedError
+}
+
+// Cmdline returns the command line arguments of the process as a string with
+// each argument separated by 0x20 ascii character.
+func (p *Process) Cmdline() (string, error) {
+	r, err := callPs("command", p.Pid, false)
+	if err != nil {
+		return "", err
+	}
+	return strings.Join(r[0], " "), err
+}
+
+// CmdlineSlice returns the command line arguments of the process as a slice with each
+// element being an argument. Because of current deficiencies in the way that the command
+// line arguments are found, single arguments that have spaces in the will actually be
+// reported as two separate items. In order to do something better CGO would be needed
+// to use the native darwin functions.
+func (p *Process) CmdlineSlice() ([]string, error) {
+	r, err := callPs("command", p.Pid, false)
+	if err != nil {
+		return nil, err
+	}
+	return r[0], err
+}
+func (p *Process) CreateTime() (int64, error) {
+	return 0, common.ErrNotImplementedError
+}
+func (p *Process) Cwd() (string, error) {
+	return "", common.ErrNotImplementedError
+}
+func (p *Process) Parent() (*Process, error) {
+	rr, err := common.CallLsof(invoke, p.Pid, "-FR")
+	if err != nil {
+		return nil, err
+	}
+	for _, r := range rr {
+		if strings.HasPrefix(r, "p") { // skip if process
+			continue
+		}
+		l := string(r)
+		v, err := strconv.Atoi(strings.Replace(l, "R", "", 1))
+		if err != nil {
+			return nil, err
+		}
+		return NewProcess(int32(v))
+	}
+	return nil, fmt.Errorf("could not find parent line")
+}
+func (p *Process) Status() (string, error) {
+	r, err := callPs("state", p.Pid, false)
+	if err != nil {
+		return "", err
+	}
+
+	return r[0][0], err
+}
+func (p *Process) Uids() ([]int32, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return nil, err
+	}
+
+	// See: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/ucred.h.html
+	userEffectiveUID := int32(k.Eproc.Ucred.UID)
+
+	return []int32{userEffectiveUID}, nil
+}
+func (p *Process) Gids() ([]int32, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return nil, err
+	}
+
+	gids := make([]int32, 0, 3)
+	gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Ucred.Ngroups), int32(k.Eproc.Pcred.P_svgid))
+
+	return gids, nil
+}
+func (p *Process) Terminal() (string, error) {
+	return "", common.ErrNotImplementedError
+	/*
+		k, err := p.getKProc()
+		if err != nil {
+			return "", err
+		}
+
+		ttyNr := uint64(k.Eproc.Tdev)
+		termmap, err := getTerminalMap()
+		if err != nil {
+			return "", err
+		}
+
+		return termmap[ttyNr], nil
+	*/
+}
+func (p *Process) Nice() (int32, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return 0, err
+	}
+	return int32(k.Proc.P_nice), nil
+}
+func (p *Process) IOnice() (int32, error) {
+	return 0, common.ErrNotImplementedError
+}
+func (p *Process) Rlimit() ([]RlimitStat, error) {
+	var rlimit []RlimitStat
+	return rlimit, common.ErrNotImplementedError
+}
+func (p *Process) IOCounters() (*IOCountersStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+func (p *Process) NumFDs() (int32, error) {
+	return 0, common.ErrNotImplementedError
+}
+func (p *Process) NumThreads() (int32, error) {
+	r, err := callPs("utime,stime", p.Pid, true)
+	if err != nil {
+		return 0, err
+	}
+	return int32(len(r)), nil
+}
+func (p *Process) Threads() (map[string]string, error) {
+	ret := make(map[string]string, 0)
+	return ret, common.ErrNotImplementedError
+}
+
+func convertCPUTimes(s string) (ret float64, err error) {
+	var t int
+	var _tmp string
+	if strings.Contains(s, ":") {
+		_t := strings.Split(s, ":")
+		hour, err := strconv.Atoi(_t[0])
+		if err != nil {
+			return ret, err
+		}
+		t += hour * 60 * 100
+		_tmp = _t[1]
+	} else {
+		_tmp = s
+	}
+
+	_t := strings.Split(_tmp, ".")
+	if err != nil {
+		return ret, err
+	}
+	h, err := strconv.Atoi(_t[0])
+	t += h * 100
+	h, err = strconv.Atoi(_t[1])
+	t += h
+	return float64(t) / ClockTicks, nil
+}
+func (p *Process) Times() (*cpu.TimesStat, error) {
+	r, err := callPs("utime,stime", p.Pid, false)
+
+	if err != nil {
+		return nil, err
+	}
+
+	utime, err := convertCPUTimes(r[0][0])
+	if err != nil {
+		return nil, err
+	}
+	stime, err := convertCPUTimes(r[0][1])
+	if err != nil {
+		return nil, err
+	}
+
+	ret := &cpu.TimesStat{
+		CPU:    "cpu",
+		User:   utime,
+		System: stime,
+	}
+	return ret, nil
+}
+func (p *Process) CPUAffinity() ([]int32, error) {
+	return nil, common.ErrNotImplementedError
+}
+func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
+	r, err := callPs("rss,vsize,pagein", p.Pid, false)
+	if err != nil {
+		return nil, err
+	}
+	rss, err := strconv.Atoi(r[0][0])
+	if err != nil {
+		return nil, err
+	}
+	vms, err := strconv.Atoi(r[0][1])
+	if err != nil {
+		return nil, err
+	}
+	pagein, err := strconv.Atoi(r[0][2])
+	if err != nil {
+		return nil, err
+	}
+
+	ret := &MemoryInfoStat{
+		RSS:  uint64(rss) * 1024,
+		VMS:  uint64(vms) * 1024,
+		Swap: uint64(pagein),
+	}
+
+	return ret, nil
+}
+func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) Children() ([]*Process, error) {
+	pids, err := common.CallPgrep(invoke, p.Pid)
+	if err != nil {
+		return nil, err
+	}
+	ret := make([]*Process, 0, len(pids))
+	for _, pid := range pids {
+		np, err := NewProcess(pid)
+		if err != nil {
+			return nil, err
+		}
+		ret = append(ret, np)
+	}
+	return ret, nil
+}
+
+func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) Connections() ([]net.ConnectionStat, error) {
+	return net.ConnectionsPid("all", p.Pid)
+}
+
+func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) IsRunning() (bool, error) {
+	return true, common.ErrNotImplementedError
+}
+func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
+	var ret []MemoryMapsStat
+	return &ret, common.ErrNotImplementedError
+}
+
+func processes() ([]Process, error) {
+	results := make([]Process, 0, 50)
+
+	mib := []int32{CTLKern, KernProc, KernProcAll, 0}
+	buf, length, err := common.CallSyscall(mib)
+	if err != nil {
+		return results, err
+	}
+
+	// get kinfo_proc size
+	k := KinfoProc{}
+	procinfoLen := int(unsafe.Sizeof(k))
+	count := int(length / uint64(procinfoLen))
+	/*
+		fmt.Println(length, procinfoLen, count)
+		b := buf[0*procinfoLen : 0*procinfoLen+procinfoLen]
+		fmt.Println(b)
+		kk, err := parseKinfoProc(b)
+		fmt.Printf("%#v", kk)
+	*/
+
+	// parse buf to procs
+	for i := 0; i < count; i++ {
+		b := buf[i*procinfoLen : i*procinfoLen+procinfoLen]
+		k, err := parseKinfoProc(b)
+		if err != nil {
+			continue
+		}
+		p, err := NewProcess(int32(k.Proc.P_pid))
+		if err != nil {
+			continue
+		}
+		results = append(results, *p)
+	}
+
+	return results, nil
+}
+
+func parseKinfoProc(buf []byte) (KinfoProc, error) {
+	var k KinfoProc
+	br := bytes.NewReader(buf)
+
+	err := common.Read(br, binary.LittleEndian, &k)
+	if err != nil {
+		return k, err
+	}
+
+	return k, nil
+}
+
+// Returns a proc as defined here:
+// http://unix.superglobalmegacorp.com/Net2/newsrc/sys/kinfo_proc.h.html
+func (p *Process) getKProc() (*KinfoProc, error) {
+	mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
+	procK := KinfoProc{}
+	length := uint64(unsafe.Sizeof(procK))
+	buf := make([]byte, length)
+	_, _, syserr := syscall.Syscall6(
+		syscall.SYS___SYSCTL,
+		uintptr(unsafe.Pointer(&mib[0])),
+		uintptr(len(mib)),
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(unsafe.Pointer(&length)),
+		0,
+		0)
+	if syserr != 0 {
+		return nil, syserr
+	}
+	k, err := parseKinfoProc(buf)
+	if err != nil {
+		return nil, err
+	}
+
+	return &k, nil
+}
+
+func NewProcess(pid int32) (*Process, error) {
+	p := &Process{Pid: pid}
+
+	return p, nil
+}
+
+// call ps command.
+// Return value deletes Header line(you must not input wrong arg).
+// And splited by Space. Caller have responsibility to manage.
+// If passed arg pid is 0, get information from all process.
+func callPs(arg string, pid int32, threadOption bool) ([][]string, error) {
+	bin, err := exec.LookPath("ps")
+	if err != nil {
+		return [][]string{}, err
+	}
+
+	var cmd []string
+	if pid == 0 { // will get from all processes.
+		cmd = []string{"-ax", "-o", arg}
+	} else if threadOption {
+		cmd = []string{"-x", "-o", arg, "-M", "-p", strconv.Itoa(int(pid))}
+	} else {
+		cmd = []string{"-x", "-o", arg, "-p", strconv.Itoa(int(pid))}
+	}
+	out, err := invoke.Command(bin, cmd...)
+	if err != nil {
+		return [][]string{}, err
+	}
+	lines := strings.Split(string(out), "\n")
+
+	var ret [][]string
+	for _, l := range lines[1:] {
+		var lr []string
+		for _, r := range strings.Split(l, " ") {
+			if r == "" {
+				continue
+			}
+			lr = append(lr, strings.TrimSpace(r))
+		}
+		if len(lr) != 0 {
+			ret = append(ret, lr)
+		}
+	}
+
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/process_darwin_amd64.go b/go/src/github.com/shirou/gopsutil/process/process_darwin_amd64.go
new file mode 100644
index 0000000..f8e9223
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_darwin_amd64.go
@@ -0,0 +1,234 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_darwin.go
+
+package process
+
+const (
+	sizeofPtr      = 0x8
+	sizeofShort    = 0x2
+	sizeofInt      = 0x4
+	sizeofLong     = 0x8
+	sizeofLongLong = 0x8
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int64
+	_C_long_long int64
+)
+
+type Timespec struct {
+	Sec  int64
+	Nsec int64
+}
+
+type Timeval struct {
+	Sec       int64
+	Usec      int32
+	Pad_cgo_0 [4]byte
+}
+
+type Rusage struct {
+	Utime    Timeval
+	Stime    Timeval
+	Maxrss   int64
+	Ixrss    int64
+	Idrss    int64
+	Isrss    int64
+	Minflt   int64
+	Majflt   int64
+	Nswap    int64
+	Inblock  int64
+	Oublock  int64
+	Msgsnd   int64
+	Msgrcv   int64
+	Nsignals int64
+	Nvcsw    int64
+	Nivcsw   int64
+}
+
+type Rlimit struct {
+	Cur uint64
+	Max uint64
+}
+
+type UGid_t uint32
+
+type KinfoProc struct {
+	Proc  ExternProc
+	Eproc Eproc
+}
+
+type Eproc struct {
+	Paddr     *uint64
+	Sess      *Session
+	Pcred     Upcred
+	Ucred     Uucred
+	Pad_cgo_0 [4]byte
+	Vm        Vmspace
+	Ppid      int32
+	Pgid      int32
+	Jobc      int16
+	Pad_cgo_1 [2]byte
+	Tdev      int32
+	Tpgid     int32
+	Pad_cgo_2 [4]byte
+	Tsess     *Session
+	Wmesg     [8]int8
+	Xsize     int32
+	Xrssize   int16
+	Xccount   int16
+	Xswrss    int16
+	Pad_cgo_3 [2]byte
+	Flag      int32
+	Login     [12]int8
+	Spare     [4]int32
+	Pad_cgo_4 [4]byte
+}
+
+type Proc struct{}
+
+type Session struct{}
+
+type ucred struct {
+	Link  _Ctype_struct___0
+	Ref   uint64
+	Posix Posix_cred
+	Label *Label
+	Audit Au_session
+}
+
+type Uucred struct {
+	Ref       int32
+	UID       uint32
+	Ngroups   int16
+	Pad_cgo_0 [2]byte
+	Groups    [16]uint32
+}
+
+type Upcred struct {
+	Pc_lock   [72]int8
+	Pc_ucred  *ucred
+	P_ruid    uint32
+	P_svuid   uint32
+	P_rgid    uint32
+	P_svgid   uint32
+	P_refcnt  int32
+	Pad_cgo_0 [4]byte
+}
+
+type Vmspace struct {
+	Dummy     int32
+	Pad_cgo_0 [4]byte
+	Dummy2    *int8
+	Dummy3    [5]int32
+	Pad_cgo_1 [4]byte
+	Dummy4    [3]*int8
+}
+
+type Sigacts struct{}
+
+type ExternProc struct {
+	P_un        [16]byte
+	P_vmspace   uint64
+	P_sigacts   uint64
+	Pad_cgo_0   [3]byte
+	P_flag      int32
+	P_stat      int8
+	P_pid       int32
+	P_oppid     int32
+	P_dupfd     int32
+	Pad_cgo_1   [4]byte
+	User_stack  uint64
+	Exit_thread uint64
+	P_debugger  int32
+	Sigwait     int32
+	P_estcpu    uint32
+	P_cpticks   int32
+	P_pctcpu    uint32
+	Pad_cgo_2   [4]byte
+	P_wchan     uint64
+	P_wmesg     uint64
+	P_swtime    uint32
+	P_slptime   uint32
+	P_realtimer Itimerval
+	P_rtime     Timeval
+	P_uticks    uint64
+	P_sticks    uint64
+	P_iticks    uint64
+	P_traceflag int32
+	Pad_cgo_3   [4]byte
+	P_tracep    uint64
+	P_siglist   int32
+	Pad_cgo_4   [4]byte
+	P_textvp    uint64
+	P_holdcnt   int32
+	P_sigmask   uint32
+	P_sigignore uint32
+	P_sigcatch  uint32
+	P_priority  uint8
+	P_usrpri    uint8
+	P_nice      int8
+	P_comm      [17]int8
+	Pad_cgo_5   [4]byte
+	P_pgrp      uint64
+	P_addr      uint64
+	P_xstat     uint16
+	P_acflag    uint16
+	Pad_cgo_6   [4]byte
+	P_ru        uint64
+}
+
+type Itimerval struct {
+	Interval Timeval
+	Value    Timeval
+}
+
+type Vnode struct{}
+
+type Pgrp struct{}
+
+type UserStruct struct{}
+
+type Au_session struct {
+	Aia_p *AuditinfoAddr
+	Mask  AuMask
+}
+
+type Posix_cred struct {
+	UID       uint32
+	Ruid      uint32
+	Svuid     uint32
+	Ngroups   int16
+	Pad_cgo_0 [2]byte
+	Groups    [16]uint32
+	Rgid      uint32
+	Svgid     uint32
+	Gmuid     uint32
+	Flags     int32
+}
+
+type Label struct{}
+
+type AuditinfoAddr struct {
+	Auid   uint32
+	Mask   AuMask
+	Termid AuTidAddr
+	Asid   int32
+	Flags  uint64
+}
+type AuMask struct {
+	Success uint32
+	Failure uint32
+}
+type AuTidAddr struct {
+	Port int32
+	Type uint32
+	Addr [4]uint32
+}
+
+type UcredQueue struct {
+	Next *ucred
+	Prev **ucred
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/process_freebsd.go b/go/src/github.com/shirou/gopsutil/process/process_freebsd.go
new file mode 100644
index 0000000..5362128
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_freebsd.go
@@ -0,0 +1,336 @@
+// +build freebsd
+
+package process
+
+import (
+	"bytes"
+	"encoding/binary"
+	"strings"
+	"syscall"
+
+	cpu "github.com/shirou/gopsutil/cpu"
+	"github.com/shirou/gopsutil/internal/common"
+	net "github.com/shirou/gopsutil/net"
+)
+
+// MemoryInfoExStat is different between OSes
+type MemoryInfoExStat struct {
+}
+
+type MemoryMapsStat struct {
+}
+
+func Pids() ([]int32, error) {
+	var ret []int32
+	procs, err := processes()
+	if err != nil {
+		return ret, nil
+	}
+
+	for _, p := range procs {
+		ret = append(ret, p.Pid)
+	}
+
+	return ret, nil
+}
+
+func (p *Process) Ppid() (int32, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return 0, err
+	}
+
+	return k.Ppid, nil
+}
+func (p *Process) Name() (string, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return "", err
+	}
+
+	return common.IntToString(k.Comm[:]), nil
+}
+func (p *Process) Exe() (string, error) {
+	return "", common.ErrNotImplementedError
+}
+
+func (p *Process) Cmdline() (string, error) {
+	mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid}
+	buf, _, err := common.CallSyscall(mib)
+	if err != nil {
+		return "", err
+	}
+	ret := strings.FieldsFunc(string(buf), func(r rune) bool {
+		if r == '\u0000' {
+			return true
+		}
+		return false
+	})
+
+	return strings.Join(ret, " "), nil
+}
+
+func (p *Process) CmdlineSlice() ([]string, error) {
+	mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid}
+	buf, _, err := common.CallSyscall(mib)
+	if err != nil {
+		return nil, err
+	}
+	if len(buf) == 0 {
+		return nil, nil
+	}
+	if buf[len(buf)-1] == 0 {
+		buf = buf[:len(buf)-1]
+	}
+	parts := bytes.Split(buf, []byte{0})
+	var strParts []string
+	for _, p := range parts {
+		strParts = append(strParts, string(p))
+	}
+
+	return strParts, nil
+}
+func (p *Process) CreateTime() (int64, error) {
+	return 0, common.ErrNotImplementedError
+}
+func (p *Process) Cwd() (string, error) {
+	return "", common.ErrNotImplementedError
+}
+func (p *Process) Parent() (*Process, error) {
+	return p, common.ErrNotImplementedError
+}
+func (p *Process) Status() (string, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return "", err
+	}
+	var s string
+	switch k.Stat {
+	case SIDL:
+		s = "I"
+	case SRUN:
+		s = "R"
+	case SSLEEP:
+		s = "S"
+	case SSTOP:
+		s = "T"
+	case SZOMB:
+		s = "Z"
+	case SWAIT:
+		s = "W"
+	case SLOCK:
+		s = "L"
+	}
+
+	return s, nil
+}
+func (p *Process) Uids() ([]int32, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return nil, err
+	}
+
+	uids := make([]int32, 0, 3)
+
+	uids = append(uids, int32(k.Ruid), int32(k.Uid), int32(k.Svuid))
+
+	return uids, nil
+}
+func (p *Process) Gids() ([]int32, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return nil, err
+	}
+
+	gids := make([]int32, 0, 3)
+	gids = append(gids, int32(k.Rgid), int32(k.Ngroups), int32(k.Svgid))
+
+	return gids, nil
+}
+func (p *Process) Terminal() (string, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return "", err
+	}
+
+	ttyNr := uint64(k.Tdev)
+
+	termmap, err := getTerminalMap()
+	if err != nil {
+		return "", err
+	}
+
+	return termmap[ttyNr], nil
+}
+func (p *Process) Nice() (int32, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return 0, err
+	}
+	return int32(k.Nice), nil
+}
+func (p *Process) IOnice() (int32, error) {
+	return 0, common.ErrNotImplementedError
+}
+func (p *Process) Rlimit() ([]RlimitStat, error) {
+	var rlimit []RlimitStat
+	return rlimit, common.ErrNotImplementedError
+}
+func (p *Process) IOCounters() (*IOCountersStat, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return nil, err
+	}
+	return &IOCountersStat{
+		ReadCount:  uint64(k.Rusage.Inblock),
+		WriteCount: uint64(k.Rusage.Oublock),
+	}, nil
+}
+func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+func (p *Process) NumFDs() (int32, error) {
+	return 0, common.ErrNotImplementedError
+}
+func (p *Process) NumThreads() (int32, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return 0, err
+	}
+
+	return k.Numthreads, nil
+}
+func (p *Process) Threads() (map[string]string, error) {
+	ret := make(map[string]string, 0)
+	return ret, common.ErrNotImplementedError
+}
+func (p *Process) Times() (*cpu.TimesStat, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return nil, err
+	}
+	return &cpu.TimesStat{
+		CPU:    "cpu",
+		User:   float64(k.Rusage.Utime.Sec) + float64(k.Rusage.Utime.Usec)/1000000,
+		System: float64(k.Rusage.Stime.Sec) + float64(k.Rusage.Stime.Usec)/1000000,
+	}, nil
+}
+func (p *Process) CPUAffinity() ([]int32, error) {
+	return nil, common.ErrNotImplementedError
+}
+func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
+	k, err := p.getKProc()
+	if err != nil {
+		return nil, err
+	}
+	v, err := syscall.Sysctl("vm.stats.vm.v_page_size")
+	if err != nil {
+		return nil, err
+	}
+	pageSize := common.LittleEndian.Uint16([]byte(v))
+
+	return &MemoryInfoStat{
+		RSS: uint64(k.Rssize) * uint64(pageSize),
+		VMS: uint64(k.Size),
+	}, nil
+}
+func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) Children() ([]*Process, error) {
+	pids, err := common.CallPgrep(invoke, p.Pid)
+	if err != nil {
+		return nil, err
+	}
+	ret := make([]*Process, 0, len(pids))
+	for _, pid := range pids {
+		np, err := NewProcess(pid)
+		if err != nil {
+			return nil, err
+		}
+		ret = append(ret, np)
+	}
+	return ret, nil
+}
+
+func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) Connections() ([]net.ConnectionStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) IsRunning() (bool, error) {
+	return true, common.ErrNotImplementedError
+}
+func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
+	var ret []MemoryMapsStat
+	return &ret, common.ErrNotImplementedError
+}
+
+func processes() ([]Process, error) {
+	results := make([]Process, 0, 50)
+
+	mib := []int32{CTLKern, KernProc, KernProcProc, 0}
+	buf, length, err := common.CallSyscall(mib)
+	if err != nil {
+		return results, err
+	}
+
+	// get kinfo_proc size
+	count := int(length / uint64(sizeOfKinfoProc))
+
+	// parse buf to procs
+	for i := 0; i < count; i++ {
+		b := buf[i*sizeOfKinfoProc : (i+1)*sizeOfKinfoProc]
+		k, err := parseKinfoProc(b)
+		if err != nil {
+			continue
+		}
+		p, err := NewProcess(int32(k.Pid))
+		if err != nil {
+			continue
+		}
+
+		results = append(results, *p)
+	}
+
+	return results, nil
+}
+
+func parseKinfoProc(buf []byte) (KinfoProc, error) {
+	var k KinfoProc
+	br := bytes.NewReader(buf)
+	err := common.Read(br, binary.LittleEndian, &k)
+	return k, err
+}
+
+func (p *Process) getKProc() (*KinfoProc, error) {
+	mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
+
+	buf, length, err := common.CallSyscall(mib)
+	if err != nil {
+		return nil, err
+	}
+	if length != sizeOfKinfoProc {
+		return nil, err
+	}
+
+	k, err := parseKinfoProc(buf)
+	if err != nil {
+		return nil, err
+	}
+	return &k, nil
+}
+
+func NewProcess(pid int32) (*Process, error) {
+	p := &Process{Pid: pid}
+
+	return p, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/process_freebsd_386.go b/go/src/github.com/shirou/gopsutil/process/process_freebsd_386.go
new file mode 100644
index 0000000..05e96d0
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_freebsd_386.go
@@ -0,0 +1,192 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_freebsd.go
+
+package process
+
+const (
+	CTLKern			= 1
+	KernProc		= 14
+	KernProcPID		= 1
+	KernProcProc		= 8
+	KernProcPathname	= 12
+	KernProcArgs		= 7
+)
+
+const (
+	sizeofPtr	= 0x4
+	sizeofShort	= 0x2
+	sizeofInt	= 0x4
+	sizeofLong	= 0x4
+	sizeofLongLong	= 0x8
+)
+
+const (
+	sizeOfKinfoVmentry	= 0x488
+	sizeOfKinfoProc		= 0x300
+)
+
+const (
+	SIDL	= 1
+	SRUN	= 2
+	SSLEEP	= 3
+	SSTOP	= 4
+	SZOMB	= 5
+	SWAIT	= 6
+	SLOCK	= 7
+)
+
+type (
+	_C_short	int16
+	_C_int		int32
+	_C_long		int32
+	_C_long_long	int64
+)
+
+type Timespec struct {
+	Sec	int32
+	Nsec	int32
+}
+
+type Timeval struct {
+	Sec	int32
+	Usec	int32
+}
+
+type Rusage struct {
+	Utime		Timeval
+	Stime		Timeval
+	Maxrss		int32
+	Ixrss		int32
+	Idrss		int32
+	Isrss		int32
+	Minflt		int32
+	Majflt		int32
+	Nswap		int32
+	Inblock		int32
+	Oublock		int32
+	Msgsnd		int32
+	Msgrcv		int32
+	Nsignals	int32
+	Nvcsw		int32
+	Nivcsw		int32
+}
+
+type Rlimit struct {
+	Cur	int64
+	Max	int64
+}
+
+type KinfoProc struct {
+	Structsize	int32
+	Layout		int32
+	Args		int32 /* pargs */
+	Paddr		int32 /* proc */
+	Addr		int32 /* user */
+	Tracep		int32 /* vnode */
+	Textvp		int32 /* vnode */
+	Fd		int32 /* filedesc */
+	Vmspace		int32 /* vmspace */
+	Wchan		int32
+	Pid		int32
+	Ppid		int32
+	Pgid		int32
+	Tpgid		int32
+	Sid		int32
+	Tsid		int32
+	Jobc		int16
+	Spare_short1	int16
+	Tdev		uint32
+	Siglist		[16]byte /* sigset */
+	Sigmask		[16]byte /* sigset */
+	Sigignore	[16]byte /* sigset */
+	Sigcatch	[16]byte /* sigset */
+	Uid		uint32
+	Ruid		uint32
+	Svuid		uint32
+	Rgid		uint32
+	Svgid		uint32
+	Ngroups		int16
+	Spare_short2	int16
+	Groups		[16]uint32
+	Size		uint32
+	Rssize		int32
+	Swrss		int32
+	Tsize		int32
+	Dsize		int32
+	Ssize		int32
+	Xstat		uint16
+	Acflag		uint16
+	Pctcpu		uint32
+	Estcpu		uint32
+	Slptime		uint32
+	Swtime		uint32
+	Cow		uint32
+	Runtime		uint64
+	Start		Timeval
+	Childtime	Timeval
+	Flag		int32
+	Kiflag		int32
+	Traceflag	int32
+	Stat		int8
+	Nice		int8
+	Lock		int8
+	Rqindex		int8
+	Oncpu		uint8
+	Lastcpu		uint8
+	Tdname		[17]int8
+	Wmesg		[9]int8
+	Login		[18]int8
+	Lockname	[9]int8
+	Comm		[20]int8
+	Emul		[17]int8
+	Loginclass	[18]int8
+	Sparestrings	[50]int8
+	Spareints	[7]int32
+	Flag2		int32
+	Fibnum		int32
+	Cr_flags	uint32
+	Jid		int32
+	Numthreads	int32
+	Tid		int32
+	Pri		Priority
+	Rusage		Rusage
+	Rusage_ch	Rusage
+	Pcb		int32 /* pcb */
+	Kstack		int32
+	Udata		int32
+	Tdaddr		int32 /* thread */
+	Spareptrs	[6]int32
+	Sparelongs	[12]int32
+	Sflag		int32
+	Tdflags		int32
+}
+
+type Priority struct {
+	Class	uint8
+	Level	uint8
+	Native	uint8
+	User	uint8
+}
+
+type KinfoVmentry struct {
+	Structsize		int32
+	Type			int32
+	Start			uint64
+	End			uint64
+	Offset			uint64
+	Vn_fileid		uint64
+	Vn_fsid			uint32
+	Flags			int32
+	Resident		int32
+	Private_resident	int32
+	Protection		int32
+	Ref_count		int32
+	Shadow_count		int32
+	Vn_type			int32
+	Vn_size			uint64
+	Vn_rdev			uint32
+	Vn_mode			uint16
+	Status			uint16
+	X_kve_ispare		[12]int32
+	Path			[1024]int8
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/process_freebsd_amd64.go b/go/src/github.com/shirou/gopsutil/process/process_freebsd_amd64.go
new file mode 100644
index 0000000..79e2ba8
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_freebsd_amd64.go
@@ -0,0 +1,192 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_freebsd.go
+
+package process
+
+const (
+	CTLKern			= 1
+	KernProc		= 14
+	KernProcPID		= 1
+	KernProcProc		= 8
+	KernProcPathname	= 12
+	KernProcArgs		= 7
+)
+
+const (
+	sizeofPtr	= 0x8
+	sizeofShort	= 0x2
+	sizeofInt	= 0x4
+	sizeofLong	= 0x8
+	sizeofLongLong	= 0x8
+)
+
+const (
+	sizeOfKinfoVmentry	= 0x488
+	sizeOfKinfoProc		= 0x440
+)
+
+const (
+	SIDL	= 1
+	SRUN	= 2
+	SSLEEP	= 3
+	SSTOP	= 4
+	SZOMB	= 5
+	SWAIT	= 6
+	SLOCK	= 7
+)
+
+type (
+	_C_short	int16
+	_C_int		int32
+	_C_long		int64
+	_C_long_long	int64
+)
+
+type Timespec struct {
+	Sec	int64
+	Nsec	int64
+}
+
+type Timeval struct {
+	Sec	int64
+	Usec	int64
+}
+
+type Rusage struct {
+	Utime		Timeval
+	Stime		Timeval
+	Maxrss		int64
+	Ixrss		int64
+	Idrss		int64
+	Isrss		int64
+	Minflt		int64
+	Majflt		int64
+	Nswap		int64
+	Inblock		int64
+	Oublock		int64
+	Msgsnd		int64
+	Msgrcv		int64
+	Nsignals	int64
+	Nvcsw		int64
+	Nivcsw		int64
+}
+
+type Rlimit struct {
+	Cur	int64
+	Max	int64
+}
+
+type KinfoProc struct {
+	Structsize	int32
+	Layout		int32
+	Args		int64 /* pargs */
+	Paddr		int64 /* proc */
+	Addr		int64 /* user */
+	Tracep		int64 /* vnode */
+	Textvp		int64 /* vnode */
+	Fd		int64 /* filedesc */
+	Vmspace		int64 /* vmspace */
+	Wchan		int64
+	Pid		int32
+	Ppid		int32
+	Pgid		int32
+	Tpgid		int32
+	Sid		int32
+	Tsid		int32
+	Jobc		int16
+	Spare_short1	int16
+	Tdev		uint32
+	Siglist		[16]byte /* sigset */
+	Sigmask		[16]byte /* sigset */
+	Sigignore	[16]byte /* sigset */
+	Sigcatch	[16]byte /* sigset */
+	Uid		uint32
+	Ruid		uint32
+	Svuid		uint32
+	Rgid		uint32
+	Svgid		uint32
+	Ngroups		int16
+	Spare_short2	int16
+	Groups		[16]uint32
+	Size		uint64
+	Rssize		int64
+	Swrss		int64
+	Tsize		int64
+	Dsize		int64
+	Ssize		int64
+	Xstat		uint16
+	Acflag		uint16
+	Pctcpu		uint32
+	Estcpu		uint32
+	Slptime		uint32
+	Swtime		uint32
+	Cow		uint32
+	Runtime		uint64
+	Start		Timeval
+	Childtime	Timeval
+	Flag		int64
+	Kiflag		int64
+	Traceflag	int32
+	Stat		int8
+	Nice		int8
+	Lock		int8
+	Rqindex		int8
+	Oncpu		uint8
+	Lastcpu		uint8
+	Tdname		[17]int8
+	Wmesg		[9]int8
+	Login		[18]int8
+	Lockname	[9]int8
+	Comm		[20]int8
+	Emul		[17]int8
+	Loginclass	[18]int8
+	Sparestrings	[50]int8
+	Spareints	[7]int32
+	Flag2		int32
+	Fibnum		int32
+	Cr_flags	uint32
+	Jid		int32
+	Numthreads	int32
+	Tid		int32
+	Pri		Priority
+	Rusage		Rusage
+	Rusage_ch	Rusage
+	Pcb		int64 /* pcb */
+	Kstack		int64
+	Udata		int64
+	Tdaddr		int64 /* thread */
+	Spareptrs	[6]int64
+	Sparelongs	[12]int64
+	Sflag		int64
+	Tdflags		int64
+}
+
+type Priority struct {
+	Class	uint8
+	Level	uint8
+	Native	uint8
+	User	uint8
+}
+
+type KinfoVmentry struct {
+	Structsize		int32
+	Type			int32
+	Start			uint64
+	End			uint64
+	Offset			uint64
+	Vn_fileid		uint64
+	Vn_fsid			uint32
+	Flags			int32
+	Resident		int32
+	Private_resident	int32
+	Protection		int32
+	Ref_count		int32
+	Shadow_count		int32
+	Vn_type			int32
+	Vn_size			uint64
+	Vn_rdev			uint32
+	Vn_mode			uint16
+	Status			uint16
+	X_kve_ispare		[12]int32
+	Path			[1024]int8
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/process_linux.go b/go/src/github.com/shirou/gopsutil/process/process_linux.go
new file mode 100644
index 0000000..ae30041
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_linux.go
@@ -0,0 +1,767 @@
+// +build linux
+
+package process
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"syscall"
+
+	"github.com/shirou/gopsutil/cpu"
+	"github.com/shirou/gopsutil/host"
+	"github.com/shirou/gopsutil/internal/common"
+	"github.com/shirou/gopsutil/net"
+)
+
+var ErrorNoChildren = errors.New("process does not have children")
+
+const (
+	PrioProcess = 0 // linux/resource.h
+)
+
+// MemoryInfoExStat is different between OSes
+type MemoryInfoExStat struct {
+	RSS    uint64 `json:"rss"`    // bytes
+	VMS    uint64 `json:"vms"`    // bytes
+	Shared uint64 `json:"shared"` // bytes
+	Text   uint64 `json:"text"`   // bytes
+	Lib    uint64 `json:"lib"`    // bytes
+	Data   uint64 `json:"data"`   // bytes
+	Dirty  uint64 `json:"dirty"`  // bytes
+}
+
+func (m MemoryInfoExStat) String() string {
+	s, _ := json.Marshal(m)
+	return string(s)
+}
+
+type MemoryMapsStat struct {
+	Path         string `json:"path"`
+	Rss          uint64 `json:"rss"`
+	Size         uint64 `json:"size"`
+	Pss          uint64 `json:"pss"`
+	SharedClean  uint64 `json:"sharedClean"`
+	SharedDirty  uint64 `json:"sharedDirty"`
+	PrivateClean uint64 `json:"privateClean"`
+	PrivateDirty uint64 `json:"privateDirty"`
+	Referenced   uint64 `json:"referenced"`
+	Anonymous    uint64 `json:"anonymous"`
+	Swap         uint64 `json:"swap"`
+}
+
+// String returns JSON value of the process.
+func (m MemoryMapsStat) String() string {
+	s, _ := json.Marshal(m)
+	return string(s)
+}
+
+// NewProcess creates a new Process instance, it only stores the pid and
+// checks that the process exists. Other method on Process can be used
+// to get more information about the process. An error will be returned
+// if the process does not exist.
+func NewProcess(pid int32) (*Process, error) {
+	p := &Process{
+		Pid: int32(pid),
+	}
+	file, err := os.Open(common.HostProc(strconv.Itoa(int(p.Pid))))
+	defer file.Close()
+	return p, err
+}
+
+// Ppid returns Parent Process ID of the process.
+func (p *Process) Ppid() (int32, error) {
+	_, ppid, _, _, _, err := p.fillFromStat()
+	if err != nil {
+		return -1, err
+	}
+	return ppid, nil
+}
+
+// Name returns name of the process.
+func (p *Process) Name() (string, error) {
+	if p.name == "" {
+		if err := p.fillFromStatus(); err != nil {
+			return "", err
+		}
+	}
+	return p.name, nil
+}
+
+// Exe returns executable path of the process.
+func (p *Process) Exe() (string, error) {
+	return p.fillFromExe()
+}
+
+// Cmdline returns the command line arguments of the process as a string with
+// each argument separated by 0x20 ascii character.
+func (p *Process) Cmdline() (string, error) {
+	return p.fillFromCmdline()
+}
+
+// CmdlineSlice returns the command line arguments of the process as a slice with each
+// element being an argument.
+func (p *Process) CmdlineSlice() ([]string, error) {
+	return p.fillSliceFromCmdline()
+}
+
+// CreateTime returns created time of the process in seconds since the epoch, in UTC.
+func (p *Process) CreateTime() (int64, error) {
+	_, _, _, createTime, _, err := p.fillFromStat()
+	if err != nil {
+		return 0, err
+	}
+	return createTime, nil
+}
+
+// Cwd returns current working directory of the process.
+func (p *Process) Cwd() (string, error) {
+	return p.fillFromCwd()
+}
+
+// Parent returns parent Process of the process.
+func (p *Process) Parent() (*Process, error) {
+	err := p.fillFromStatus()
+	if err != nil {
+		return nil, err
+	}
+	if p.parent == 0 {
+		return nil, fmt.Errorf("wrong number of parents")
+	}
+	return NewProcess(p.parent)
+}
+
+// Status returns the process status.
+// Return value could be one of these.
+// R: Running S: Sleep T: Stop I: Idle
+// Z: Zombie W: Wait L: Lock
+// The charactor is same within all supported platforms.
+func (p *Process) Status() (string, error) {
+	err := p.fillFromStatus()
+	if err != nil {
+		return "", err
+	}
+	return p.status, nil
+}
+
+// Uids returns user ids of the process as a slice of the int
+func (p *Process) Uids() ([]int32, error) {
+	err := p.fillFromStatus()
+	if err != nil {
+		return []int32{}, err
+	}
+	return p.uids, nil
+}
+
+// Gids returns group ids of the process as a slice of the int
+func (p *Process) Gids() ([]int32, error) {
+	err := p.fillFromStatus()
+	if err != nil {
+		return []int32{}, err
+	}
+	return p.gids, nil
+}
+
+// Terminal returns a terminal which is associated with the process.
+func (p *Process) Terminal() (string, error) {
+	terminal, _, _, _, _, err := p.fillFromStat()
+	if err != nil {
+		return "", err
+	}
+	return terminal, nil
+}
+
+// Nice returns a nice value (priority).
+// Notice: gopsutil can not set nice value.
+func (p *Process) Nice() (int32, error) {
+	_, _, _, _, nice, err := p.fillFromStat()
+	if err != nil {
+		return 0, err
+	}
+	return nice, nil
+}
+
+// IOnice returns process I/O nice value (priority).
+func (p *Process) IOnice() (int32, error) {
+	return 0, common.ErrNotImplementedError
+}
+
+// Rlimit returns Resource Limits.
+func (p *Process) Rlimit() ([]RlimitStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+// IOCounters returns IO Counters.
+func (p *Process) IOCounters() (*IOCountersStat, error) {
+	return p.fillFromIO()
+}
+
+// NumCtxSwitches returns the number of the context switches of the process.
+func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
+	err := p.fillFromStatus()
+	if err != nil {
+		return nil, err
+	}
+	return p.numCtxSwitches, nil
+}
+
+// NumFDs returns the number of File Descriptors used by the process.
+func (p *Process) NumFDs() (int32, error) {
+	numFds, _, err := p.fillFromfd()
+	return numFds, err
+}
+
+// NumThreads returns the number of threads used by the process.
+func (p *Process) NumThreads() (int32, error) {
+	err := p.fillFromStatus()
+	if err != nil {
+		return 0, err
+	}
+	return p.numThreads, nil
+}
+
+// Threads returns a map of threads
+//
+// Notice: Not implemented yet. always returns empty map.
+func (p *Process) Threads() (map[string]string, error) {
+	ret := make(map[string]string, 0)
+	return ret, nil
+}
+
+// Times returns CPU times of the process.
+func (p *Process) Times() (*cpu.TimesStat, error) {
+	_, _, cpuTimes, _, _, err := p.fillFromStat()
+	if err != nil {
+		return nil, err
+	}
+	return cpuTimes, nil
+}
+
+// CPUAffinity returns CPU affinity of the process.
+//
+// Notice: Not implemented yet.
+func (p *Process) CPUAffinity() ([]int32, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+// MemoryInfo returns platform in-dependend memory information, such as RSS, VMS and Swap
+func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
+	meminfo, _, err := p.fillFromStatm()
+	if err != nil {
+		return nil, err
+	}
+	return meminfo, nil
+}
+
+// MemoryInfoEx returns platform dependend memory information.
+func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
+	_, memInfoEx, err := p.fillFromStatm()
+	if err != nil {
+		return nil, err
+	}
+	return memInfoEx, nil
+}
+
+// Children returns a slice of Process of the process.
+func (p *Process) Children() ([]*Process, error) {
+	pids, err := common.CallPgrep(invoke, p.Pid)
+	if err != nil {
+		if pids == nil || len(pids) == 0 {
+			return nil, ErrorNoChildren
+		}
+		return nil, err
+	}
+	ret := make([]*Process, 0, len(pids))
+	for _, pid := range pids {
+		np, err := NewProcess(pid)
+		if err != nil {
+			return nil, err
+		}
+		ret = append(ret, np)
+	}
+	return ret, nil
+}
+
+// OpenFiles returns a slice of OpenFilesStat opend by the process.
+// OpenFilesStat includes a file path and file descriptor.
+func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
+	_, ofs, err := p.fillFromfd()
+	if err != nil {
+		return nil, err
+	}
+	ret := make([]OpenFilesStat, len(ofs))
+	for i, o := range ofs {
+		ret[i] = *o
+	}
+
+	return ret, nil
+}
+
+// Connections returns a slice of net.ConnectionStat used by the process.
+// This returns all kind of the connection. This measn TCP, UDP or UNIX.
+func (p *Process) Connections() ([]net.ConnectionStat, error) {
+	return net.ConnectionsPid("all", p.Pid)
+}
+
+// NetIOCounters returns NetIOCounters of the process.
+func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
+	filename := common.HostProc(strconv.Itoa(int(p.Pid)), "net/dev")
+	return net.IOCountersByFile(pernic, filename)
+}
+
+// IsRunning returns whether the process is running or not.
+// Not implemented yet.
+func (p *Process) IsRunning() (bool, error) {
+	return true, common.ErrNotImplementedError
+}
+
+// MemoryMaps get memory maps from /proc/(pid)/smaps
+func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
+	pid := p.Pid
+	var ret []MemoryMapsStat
+	smapsPath := common.HostProc(strconv.Itoa(int(pid)), "smaps")
+	contents, err := ioutil.ReadFile(smapsPath)
+	if err != nil {
+		return nil, err
+	}
+	lines := strings.Split(string(contents), "\n")
+
+	// function of parsing a block
+	getBlock := func(first_line []string, block []string) (MemoryMapsStat, error) {
+		m := MemoryMapsStat{}
+		m.Path = first_line[len(first_line)-1]
+
+		for _, line := range block {
+			if strings.Contains(line, "VmFlags") {
+				continue
+			}
+			field := strings.Split(line, ":")
+			if len(field) < 2 {
+				continue
+			}
+			v := strings.Trim(field[1], " kB") // remove last "kB"
+			t, err := strconv.ParseUint(v, 10, 64)
+			if err != nil {
+				return m, err
+			}
+
+			switch field[0] {
+			case "Size":
+				m.Size = t
+			case "Rss":
+				m.Rss = t
+			case "Pss":
+				m.Pss = t
+			case "Shared_Clean":
+				m.SharedClean = t
+			case "Shared_Dirty":
+				m.SharedDirty = t
+			case "Private_Clean":
+				m.PrivateClean = t
+			case "Private_Dirty":
+				m.PrivateDirty = t
+			case "Referenced":
+				m.Referenced = t
+			case "Anonymous":
+				m.Anonymous = t
+			case "Swap":
+				m.Swap = t
+			}
+		}
+		return m, nil
+	}
+
+	blocks := make([]string, 16)
+	for _, line := range lines {
+		field := strings.Split(line, " ")
+		if strings.HasSuffix(field[0], ":") == false {
+			// new block section
+			if len(blocks) > 0 {
+				g, err := getBlock(field, blocks)
+				if err != nil {
+					return &ret, err
+				}
+				ret = append(ret, g)
+			}
+			// starts new block
+			blocks = make([]string, 16)
+		} else {
+			blocks = append(blocks, line)
+		}
+	}
+
+	return &ret, nil
+}
+
+/**
+** Internal functions
+**/
+
+// Get num_fds from /proc/(pid)/fd
+func (p *Process) fillFromfd() (int32, []*OpenFilesStat, error) {
+	pid := p.Pid
+	statPath := common.HostProc(strconv.Itoa(int(pid)), "fd")
+	d, err := os.Open(statPath)
+	if err != nil {
+		return 0, nil, err
+	}
+	defer d.Close()
+	fnames, err := d.Readdirnames(-1)
+	numFDs := int32(len(fnames))
+
+	var openfiles []*OpenFilesStat
+	for _, fd := range fnames {
+		fpath := filepath.Join(statPath, fd)
+		filepath, err := os.Readlink(fpath)
+		if err != nil {
+			continue
+		}
+		t, err := strconv.ParseUint(fd, 10, 64)
+		if err != nil {
+			return numFDs, openfiles, err
+		}
+		o := &OpenFilesStat{
+			Path: filepath,
+			Fd:   t,
+		}
+		openfiles = append(openfiles, o)
+	}
+
+	return numFDs, openfiles, nil
+}
+
+// Get cwd from /proc/(pid)/cwd
+func (p *Process) fillFromCwd() (string, error) {
+	pid := p.Pid
+	cwdPath := common.HostProc(strconv.Itoa(int(pid)), "cwd")
+	cwd, err := os.Readlink(cwdPath)
+	if err != nil {
+		return "", err
+	}
+	return string(cwd), nil
+}
+
+// Get exe from /proc/(pid)/exe
+func (p *Process) fillFromExe() (string, error) {
+	pid := p.Pid
+	exePath := common.HostProc(strconv.Itoa(int(pid)), "exe")
+	exe, err := os.Readlink(exePath)
+	if err != nil {
+		return "", err
+	}
+	return string(exe), nil
+}
+
+// Get cmdline from /proc/(pid)/cmdline
+func (p *Process) fillFromCmdline() (string, error) {
+	pid := p.Pid
+	cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline")
+	cmdline, err := ioutil.ReadFile(cmdPath)
+	if err != nil {
+		return "", err
+	}
+	ret := strings.FieldsFunc(string(cmdline), func(r rune) bool {
+		if r == '\u0000' {
+			return true
+		}
+		return false
+	})
+
+	return strings.Join(ret, " "), nil
+}
+
+func (p *Process) fillSliceFromCmdline() ([]string, error) {
+	pid := p.Pid
+	cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline")
+	cmdline, err := ioutil.ReadFile(cmdPath)
+	if err != nil {
+		return nil, err
+	}
+	if len(cmdline) == 0 {
+		return nil, nil
+	}
+	if cmdline[len(cmdline)-1] == 0 {
+		cmdline = cmdline[:len(cmdline)-1]
+	}
+	parts := bytes.Split(cmdline, []byte{0})
+	var strParts []string
+	for _, p := range parts {
+		strParts = append(strParts, string(p))
+	}
+
+	return strParts, nil
+}
+
+// Get IO status from /proc/(pid)/io
+func (p *Process) fillFromIO() (*IOCountersStat, error) {
+	pid := p.Pid
+	ioPath := common.HostProc(strconv.Itoa(int(pid)), "io")
+	ioline, err := ioutil.ReadFile(ioPath)
+	if err != nil {
+		return nil, err
+	}
+	lines := strings.Split(string(ioline), "\n")
+	ret := &IOCountersStat{}
+
+	for _, line := range lines {
+		field := strings.Fields(line)
+		if len(field) < 2 {
+			continue
+		}
+		t, err := strconv.ParseUint(field[1], 10, 64)
+		if err != nil {
+			return nil, err
+		}
+		param := field[0]
+		if strings.HasSuffix(param, ":") {
+			param = param[:len(param)-1]
+		}
+		switch param {
+		case "syscr":
+			ret.ReadCount = t
+		case "syscw":
+			ret.WriteCount = t
+		case "readBytes":
+			ret.ReadBytes = t
+		case "writeBytes":
+			ret.WriteBytes = t
+		}
+	}
+
+	return ret, nil
+}
+
+// Get memory info from /proc/(pid)/statm
+func (p *Process) fillFromStatm() (*MemoryInfoStat, *MemoryInfoExStat, error) {
+	pid := p.Pid
+	memPath := common.HostProc(strconv.Itoa(int(pid)), "statm")
+	contents, err := ioutil.ReadFile(memPath)
+	if err != nil {
+		return nil, nil, err
+	}
+	fields := strings.Split(string(contents), " ")
+
+	vms, err := strconv.ParseUint(fields[0], 10, 64)
+	if err != nil {
+		return nil, nil, err
+	}
+	rss, err := strconv.ParseUint(fields[1], 10, 64)
+	if err != nil {
+		return nil, nil, err
+	}
+	memInfo := &MemoryInfoStat{
+		RSS: rss * PageSize,
+		VMS: vms * PageSize,
+	}
+
+	shared, err := strconv.ParseUint(fields[2], 10, 64)
+	if err != nil {
+		return nil, nil, err
+	}
+	text, err := strconv.ParseUint(fields[3], 10, 64)
+	if err != nil {
+		return nil, nil, err
+	}
+	lib, err := strconv.ParseUint(fields[4], 10, 64)
+	if err != nil {
+		return nil, nil, err
+	}
+	dirty, err := strconv.ParseUint(fields[5], 10, 64)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	memInfoEx := &MemoryInfoExStat{
+		RSS:    rss * PageSize,
+		VMS:    vms * PageSize,
+		Shared: shared * PageSize,
+		Text:   text * PageSize,
+		Lib:    lib * PageSize,
+		Dirty:  dirty * PageSize,
+	}
+
+	return memInfo, memInfoEx, nil
+}
+
+// Get various status from /proc/(pid)/status
+func (p *Process) fillFromStatus() error {
+	pid := p.Pid
+	statPath := common.HostProc(strconv.Itoa(int(pid)), "status")
+	contents, err := ioutil.ReadFile(statPath)
+	if err != nil {
+		return err
+	}
+	lines := strings.Split(string(contents), "\n")
+	p.numCtxSwitches = &NumCtxSwitchesStat{}
+	p.memInfo = &MemoryInfoStat{}
+	for _, line := range lines {
+		tabParts := strings.SplitN(line, "\t", 2)
+		if len(tabParts) < 2 {
+			continue
+		}
+		value := tabParts[1]
+		switch strings.TrimRight(tabParts[0], ":") {
+		case "Name":
+			p.name = strings.Trim(value, " \t")
+		case "State":
+			p.status = value[0:1]
+		case "PPid", "Ppid":
+			pval, err := strconv.ParseInt(value, 10, 32)
+			if err != nil {
+				return err
+			}
+			p.parent = int32(pval)
+		case "Uid":
+			p.uids = make([]int32, 0, 4)
+			for _, i := range strings.Split(value, "\t") {
+				v, err := strconv.ParseInt(i, 10, 32)
+				if err != nil {
+					return err
+				}
+				p.uids = append(p.uids, int32(v))
+			}
+		case "Gid":
+			p.gids = make([]int32, 0, 4)
+			for _, i := range strings.Split(value, "\t") {
+				v, err := strconv.ParseInt(i, 10, 32)
+				if err != nil {
+					return err
+				}
+				p.gids = append(p.gids, int32(v))
+			}
+		case "Threads":
+			v, err := strconv.ParseInt(value, 10, 32)
+			if err != nil {
+				return err
+			}
+			p.numThreads = int32(v)
+		case "voluntary_ctxt_switches":
+			v, err := strconv.ParseInt(value, 10, 64)
+			if err != nil {
+				return err
+			}
+			p.numCtxSwitches.Voluntary = v
+		case "nonvoluntary_ctxt_switches":
+			v, err := strconv.ParseInt(value, 10, 64)
+			if err != nil {
+				return err
+			}
+			p.numCtxSwitches.Involuntary = v
+		case "VmRSS":
+			value := strings.Trim(value, " kB") // remove last "kB"
+			v, err := strconv.ParseUint(value, 10, 64)
+			if err != nil {
+				return err
+			}
+			p.memInfo.RSS = v * 1024
+		case "VmSize":
+			value := strings.Trim(value, " kB") // remove last "kB"
+			v, err := strconv.ParseUint(value, 10, 64)
+			if err != nil {
+				return err
+			}
+			p.memInfo.VMS = v * 1024
+		case "VmSwap":
+			value := strings.Trim(value, " kB") // remove last "kB"
+			v, err := strconv.ParseUint(value, 10, 64)
+			if err != nil {
+				return err
+			}
+			p.memInfo.Swap = v * 1024
+		}
+
+	}
+	return nil
+}
+
+func (p *Process) fillFromStat() (string, int32, *cpu.TimesStat, int64, int32, error) {
+	pid := p.Pid
+	statPath := common.HostProc(strconv.Itoa(int(pid)), "stat")
+	contents, err := ioutil.ReadFile(statPath)
+	if err != nil {
+		return "", 0, nil, 0, 0, err
+	}
+	fields := strings.Fields(string(contents))
+
+	i := 1
+	for !strings.HasSuffix(fields[i], ")") {
+		i++
+	}
+
+	termmap, err := getTerminalMap()
+	terminal := ""
+	if err == nil {
+		t, err := strconv.ParseUint(fields[i+5], 10, 64)
+		if err != nil {
+			return "", 0, nil, 0, 0, err
+		}
+		terminal = termmap[t]
+	}
+
+	ppid, err := strconv.ParseInt(fields[i+2], 10, 32)
+	if err != nil {
+		return "", 0, nil, 0, 0, err
+	}
+	utime, err := strconv.ParseFloat(fields[i+12], 64)
+	if err != nil {
+		return "", 0, nil, 0, 0, err
+	}
+
+	stime, err := strconv.ParseFloat(fields[i+13], 64)
+	if err != nil {
+		return "", 0, nil, 0, 0, err
+	}
+
+	cpuTimes := &cpu.TimesStat{
+		CPU:    "cpu",
+		User:   float64(utime / ClockTicks),
+		System: float64(stime / ClockTicks),
+	}
+
+	bootTime, _ := host.BootTime()
+	t, err := strconv.ParseUint(fields[i+20], 10, 64)
+	if err != nil {
+		return "", 0, nil, 0, 0, err
+	}
+	ctime := (t / uint64(ClockTicks)) + uint64(bootTime)
+	createTime := int64(ctime * 1000)
+
+	//	p.Nice = mustParseInt32(fields[18])
+	// use syscall instead of parse Stat file
+	snice, _ := syscall.Getpriority(PrioProcess, int(pid))
+	nice := int32(snice) // FIXME: is this true?
+
+	return terminal, int32(ppid), cpuTimes, createTime, nice, nil
+}
+
+// Pids returns a slice of process ID list which are running now.
+func Pids() ([]int32, error) {
+	var ret []int32
+
+	d, err := os.Open(common.HostProc())
+	if err != nil {
+		return nil, err
+	}
+	defer d.Close()
+
+	fnames, err := d.Readdirnames(-1)
+	if err != nil {
+		return nil, err
+	}
+	for _, fname := range fnames {
+		pid, err := strconv.ParseInt(fname, 10, 32)
+		if err != nil {
+			// if not numeric name, just skip
+			continue
+		}
+		ret = append(ret, int32(pid))
+	}
+
+	return ret, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/process_linux_386.go b/go/src/github.com/shirou/gopsutil/process/process_linux_386.go
new file mode 100644
index 0000000..541b854
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_linux_386.go
@@ -0,0 +1,9 @@
+// +build linux
+// +build 386
+
+package process
+
+const (
+	ClockTicks = 100  // C.sysconf(C._SC_CLK_TCK)
+	PageSize   = 4096 // C.sysconf(C._SC_PAGE_SIZE)
+)
diff --git a/go/src/github.com/shirou/gopsutil/process/process_linux_amd64.go b/go/src/github.com/shirou/gopsutil/process/process_linux_amd64.go
new file mode 100644
index 0000000..b4a4ce8
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_linux_amd64.go
@@ -0,0 +1,9 @@
+// +build linux
+// +build amd64
+
+package process
+
+const (
+	ClockTicks = 100  // C.sysconf(C._SC_CLK_TCK)
+	PageSize   = 4096 // C.sysconf(C._SC_PAGE_SIZE)
+)
diff --git a/go/src/github.com/shirou/gopsutil/process/process_linux_arm.go b/go/src/github.com/shirou/gopsutil/process/process_linux_arm.go
new file mode 100644
index 0000000..c6123a4
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_linux_arm.go
@@ -0,0 +1,9 @@
+// +build linux
+// +build arm
+
+package process
+
+const (
+	ClockTicks = 100  // C.sysconf(C._SC_CLK_TCK)
+	PageSize   = 4096 // C.sysconf(C._SC_PAGE_SIZE)
+)
diff --git a/go/src/github.com/shirou/gopsutil/process/process_posix.go b/go/src/github.com/shirou/gopsutil/process/process_posix.go
new file mode 100644
index 0000000..8853118
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_posix.go
@@ -0,0 +1,117 @@
+// +build linux freebsd darwin
+
+package process
+
+import (
+	"os"
+	"os/exec"
+	"os/user"
+	"strconv"
+	"strings"
+	"syscall"
+)
+
+// POSIX
+func getTerminalMap() (map[uint64]string, error) {
+	ret := make(map[uint64]string)
+	var termfiles []string
+
+	d, err := os.Open("/dev")
+	if err != nil {
+		return nil, err
+	}
+	defer d.Close()
+
+	devnames, err := d.Readdirnames(-1)
+	for _, devname := range devnames {
+		if strings.HasPrefix(devname, "/dev/tty") {
+			termfiles = append(termfiles, "/dev/tty/"+devname)
+		}
+	}
+
+	ptsd, err := os.Open("/dev/pts")
+	if err != nil {
+		return nil, err
+	}
+	defer ptsd.Close()
+
+	ptsnames, err := ptsd.Readdirnames(-1)
+	for _, ptsname := range ptsnames {
+		termfiles = append(termfiles, "/dev/pts/"+ptsname)
+	}
+
+	for _, name := range termfiles {
+		stat := syscall.Stat_t{}
+		if err = syscall.Stat(name, &stat); err != nil {
+			return nil, err
+		}
+		rdev := uint64(stat.Rdev)
+		ret[rdev] = strings.Replace(name, "/dev", "", -1)
+	}
+	return ret, nil
+}
+
+// SendSignal sends a syscall.Signal to the process.
+// Currently, SIGSTOP, SIGCONT, SIGTERM and SIGKILL are supported.
+func (p *Process) SendSignal(sig syscall.Signal) error {
+	sigAsStr := "INT"
+	switch sig {
+	case syscall.SIGSTOP:
+		sigAsStr = "STOP"
+	case syscall.SIGCONT:
+		sigAsStr = "CONT"
+	case syscall.SIGTERM:
+		sigAsStr = "TERM"
+	case syscall.SIGKILL:
+		sigAsStr = "KILL"
+	}
+
+	kill, err := exec.LookPath("kill")
+	if err != nil {
+		return err
+	}
+	cmd := exec.Command(kill, "-s", sigAsStr, strconv.Itoa(int(p.Pid)))
+	cmd.Stderr = os.Stderr
+	err = cmd.Run()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Suspend sends SIGSTOP to the process.
+func (p *Process) Suspend() error {
+	return p.SendSignal(syscall.SIGSTOP)
+}
+
+// Resume sends SIGCONT to the process.
+func (p *Process) Resume() error {
+	return p.SendSignal(syscall.SIGCONT)
+}
+
+// Terminate sends SIGTERM to the process.
+func (p *Process) Terminate() error {
+	return p.SendSignal(syscall.SIGTERM)
+}
+
+// Kill sends SIGKILL to the process.
+func (p *Process) Kill() error {
+	return p.SendSignal(syscall.SIGKILL)
+}
+
+// Username returns a username of the process.
+func (p *Process) Username() (string, error) {
+	uids, err := p.Uids()
+	if err != nil {
+		return "", err
+	}
+	if len(uids) > 0 {
+		u, err := user.LookupId(strconv.Itoa(int(uids[0])))
+		if err != nil {
+			return "", err
+		}
+		return u.Username, nil
+	}
+	return "", nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/process_posix_test.go b/go/src/github.com/shirou/gopsutil/process/process_posix_test.go
new file mode 100644
index 0000000..eb91292
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_posix_test.go
@@ -0,0 +1,19 @@
+// +build linux freebsd
+
+package process
+
+import (
+	"os"
+	"syscall"
+	"testing"
+)
+
+func Test_SendSignal(t *testing.T) {
+	checkPid := os.Getpid()
+
+	p, _ := NewProcess(int32(checkPid))
+	err := p.SendSignal(syscall.SIGCONT)
+	if err != nil {
+		t.Errorf("send signal %v", err)
+	}
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/process_test.go b/go/src/github.com/shirou/gopsutil/process/process_test.go
new file mode 100644
index 0000000..a5f41da
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_test.go
@@ -0,0 +1,400 @@
+package process
+
+import (
+	"fmt"
+	"os"
+	"os/user"
+	"reflect"
+	"runtime"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/shirou/gopsutil/internal/common"
+	"github.com/stretchr/testify/assert"
+)
+
+var mu sync.Mutex
+
+func testGetProcess() Process {
+	checkPid := os.Getpid() // process.test
+	ret, _ := NewProcess(int32(checkPid))
+	return *ret
+}
+
+func Test_Pids(t *testing.T) {
+	ret, err := Pids()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	if len(ret) == 0 {
+		t.Errorf("could not get pids %v", ret)
+	}
+}
+
+func Test_Pids_Fail(t *testing.T) {
+	if runtime.GOOS != "darwin" {
+		t.Skip("darwin only")
+	}
+
+	mu.Lock()
+	defer mu.Unlock()
+
+	invoke = common.FakeInvoke{Suffix: "fail"}
+	ret, err := Pids()
+	invoke = common.Invoke{}
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	if len(ret) != 9 {
+		t.Errorf("wrong getted pid nums: %v/%d", ret, len(ret))
+	}
+}
+func Test_Pid_exists(t *testing.T) {
+	checkPid := os.Getpid()
+
+	ret, err := PidExists(int32(checkPid))
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+
+	if ret == false {
+		t.Errorf("could not get process exists: %v", ret)
+	}
+}
+
+func Test_NewProcess(t *testing.T) {
+	checkPid := os.Getpid()
+
+	ret, err := NewProcess(int32(checkPid))
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	empty := &Process{}
+	if runtime.GOOS != "windows" { // Windows pid is 0
+		if empty == ret {
+			t.Errorf("error %v", ret)
+		}
+	}
+
+}
+
+func Test_Process_memory_maps(t *testing.T) {
+	checkPid := os.Getpid()
+
+	ret, err := NewProcess(int32(checkPid))
+
+	mmaps, err := ret.MemoryMaps(false)
+	if err != nil {
+		t.Errorf("memory map get error %v", err)
+	}
+	empty := MemoryMapsStat{}
+	for _, m := range *mmaps {
+		if m == empty {
+			t.Errorf("memory map get error %v", m)
+		}
+	}
+}
+func Test_Process_MemoryInfo(t *testing.T) {
+	p := testGetProcess()
+
+	v, err := p.MemoryInfo()
+	if err != nil {
+		t.Errorf("geting memory info error %v", err)
+	}
+	empty := MemoryInfoStat{}
+	if v == nil || *v == empty {
+		t.Errorf("could not get memory info %v", v)
+	}
+}
+
+func Test_Process_CmdLine(t *testing.T) {
+	p := testGetProcess()
+
+	v, err := p.Cmdline()
+	if err != nil {
+		t.Errorf("geting cmdline error %v", err)
+	}
+	if !strings.Contains(v, "process.test") {
+		t.Errorf("invalid cmd line %v", v)
+	}
+}
+
+func Test_Process_CmdLineSlice(t *testing.T) {
+	p := testGetProcess()
+
+	v, err := p.CmdlineSlice()
+	if err != nil {
+		t.Fatalf("geting cmdline slice error %v", err)
+	}
+	if !reflect.DeepEqual(v, os.Args) {
+		t.Errorf("returned cmdline slice not as expected:\nexp: %v\ngot: %v", os.Args, v)
+	}
+}
+
+func Test_Process_Ppid(t *testing.T) {
+	p := testGetProcess()
+
+	v, err := p.Ppid()
+	if err != nil {
+		t.Errorf("geting ppid error %v", err)
+	}
+	if v == 0 {
+		t.Errorf("return value is 0 %v", v)
+	}
+}
+
+func Test_Process_Status(t *testing.T) {
+	p := testGetProcess()
+
+	v, err := p.Status()
+	if err != nil {
+		t.Errorf("geting status error %v", err)
+	}
+	if v != "R" && v != "S" {
+		t.Errorf("could not get state %v", v)
+	}
+}
+
+func Test_Process_Terminal(t *testing.T) {
+	p := testGetProcess()
+
+	_, err := p.Terminal()
+	if err != nil {
+		t.Errorf("geting terminal error %v", err)
+	}
+
+	/*
+		if v == "" {
+			t.Errorf("could not get terminal %v", v)
+		}
+	*/
+}
+
+func Test_Process_IOCounters(t *testing.T) {
+	p := testGetProcess()
+
+	v, err := p.IOCounters()
+	if err != nil {
+		t.Errorf("geting iocounter error %v", err)
+		return
+	}
+	empty := &IOCountersStat{}
+	if v == empty {
+		t.Errorf("error %v", v)
+	}
+}
+
+func Test_Process_NumCtx(t *testing.T) {
+	p := testGetProcess()
+
+	_, err := p.NumCtxSwitches()
+	if err != nil {
+		t.Errorf("geting numctx error %v", err)
+		return
+	}
+}
+
+func Test_Process_Nice(t *testing.T) {
+	p := testGetProcess()
+
+	n, err := p.Nice()
+	if err != nil {
+		t.Errorf("geting nice error %v", err)
+	}
+	if n != 0 && n != 20 && n != 8 {
+		t.Errorf("invalid nice: %d", n)
+	}
+}
+func Test_Process_NumThread(t *testing.T) {
+	p := testGetProcess()
+
+	n, err := p.NumThreads()
+	if err != nil {
+		t.Errorf("geting NumThread error %v", err)
+	}
+	if n < 0 {
+		t.Errorf("invalid NumThread: %d", n)
+	}
+}
+
+func Test_Process_Name(t *testing.T) {
+	p := testGetProcess()
+
+	n, err := p.Name()
+	if err != nil {
+		t.Errorf("geting name error %v", err)
+	}
+	if !strings.Contains(n, "process.test") {
+		t.Errorf("invalid Exe %s", n)
+	}
+}
+func Test_Process_Exe(t *testing.T) {
+	p := testGetProcess()
+
+	n, err := p.Exe()
+	if err != nil {
+		t.Errorf("geting Exe error %v", err)
+	}
+	if !strings.Contains(n, "process.test") {
+		t.Errorf("invalid Exe %s", n)
+	}
+}
+
+func Test_Process_CpuPercent(t *testing.T) {
+	p := testGetProcess()
+	percent, err := p.Percent(0)
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+	duration := time.Duration(1000) * time.Microsecond
+	time.Sleep(duration)
+	percent, err = p.Percent(0)
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+
+	numcpu := runtime.NumCPU()
+	//	if percent < 0.0 || percent > 100.0*float64(numcpu) { // TODO
+	if percent < 0.0 {
+		t.Fatalf("CPUPercent value is invalid: %f, %d", percent, numcpu)
+	}
+}
+
+func Test_Process_CpuPercentLoop(t *testing.T) {
+	p := testGetProcess()
+	numcpu := runtime.NumCPU()
+
+	for i := 0; i < 2; i++ {
+		duration := time.Duration(100) * time.Microsecond
+		percent, err := p.Percent(duration)
+		if err != nil {
+			t.Errorf("error %v", err)
+		}
+		//	if percent < 0.0 || percent > 100.0*float64(numcpu) { // TODO
+		if percent < 0.0 {
+			t.Fatalf("CPUPercent value is invalid: %f, %d", percent, numcpu)
+		}
+	}
+}
+
+func Test_Process_CreateTime(t *testing.T) {
+	p := testGetProcess()
+
+	c, err := p.CreateTime()
+	if err != nil {
+		t.Errorf("error %v", err)
+	}
+
+	if c < 1420000000 {
+		t.Errorf("process created time is wrong.")
+	}
+
+	gotElapsed := time.Since(time.Unix(int64(c/1000), 0))
+	maxElapsed := time.Duration(5 * time.Second)
+
+	if gotElapsed >= maxElapsed {
+		t.Errorf("this process has not been running for %v", gotElapsed)
+	}
+}
+
+func Test_Parent(t *testing.T) {
+	p := testGetProcess()
+
+	c, err := p.Parent()
+	if err != nil {
+		t.Fatalf("error %v", err)
+	}
+	if c == nil {
+		t.Fatalf("could not get parent")
+	}
+	if c.Pid == 0 {
+		t.Fatalf("wrong parent pid")
+	}
+}
+
+func Test_Connections(t *testing.T) {
+	p := testGetProcess()
+
+	c, err := p.Connections()
+	if err != nil {
+		t.Fatalf("error %v", err)
+	}
+	// TODO:
+	// Since go test open no conneciton, ret is empty.
+	// should invoke child process or other solutions.
+	if len(c) != 0 {
+		t.Fatalf("wrong connections")
+	}
+}
+
+func Test_Children(t *testing.T) {
+	p, err := NewProcess(1)
+	if err != nil {
+		t.Fatalf("new process error %v", err)
+	}
+
+	c, err := p.Children()
+	if err != nil {
+		t.Fatalf("error %v", err)
+	}
+	if len(c) == 0 {
+		t.Fatalf("children is empty")
+	}
+}
+
+func Test_Username(t *testing.T) {
+	myPid := os.Getpid()
+	currentUser, _ := user.Current()
+	myUsername := currentUser.Username
+
+	process, _ := NewProcess(int32(myPid))
+	pidUsername, _ := process.Username()
+	assert.Equal(t, myUsername, pidUsername)
+}
+
+func Test_CPUTimes(t *testing.T) {
+	pid := os.Getpid()
+	process, err := NewProcess(int32(pid))
+	assert.Nil(t, err)
+
+	spinSeconds := 0.2
+	cpuTimes0, err := process.Times()
+	assert.Nil(t, err)
+
+	// Spin for a duration of spinSeconds
+	t0 := time.Now()
+	tGoal := t0.Add(time.Duration(spinSeconds*1000) * time.Millisecond)
+	assert.Nil(t, err)
+	for time.Now().Before(tGoal) {
+		// This block intentionally left blank
+	}
+
+	cpuTimes1, err := process.Times()
+	assert.Nil(t, err)
+
+	if cpuTimes0 == nil || cpuTimes1 == nil {
+		t.FailNow()
+	}
+	measuredElapsed := cpuTimes1.Total() - cpuTimes0.Total()
+	message := fmt.Sprintf("Measured %fs != spun time of %fs\ncpuTimes0=%v\ncpuTimes1=%v",
+		measuredElapsed, spinSeconds, cpuTimes0, cpuTimes1)
+	assert.True(t, measuredElapsed > float64(spinSeconds)/5, message)
+	assert.True(t, measuredElapsed < float64(spinSeconds)*5, message)
+}
+
+func Test_OpenFiles(t *testing.T) {
+	pid := os.Getpid()
+	p, err := NewProcess(int32(pid))
+	assert.Nil(t, err)
+
+	v, err := p.OpenFiles()
+	assert.Nil(t, err)
+	assert.NotEmpty(t, v) // test always open files.
+
+	for _, vv := range v {
+		assert.NotEqual(t, "", vv.Path)
+	}
+
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/process_windows.go b/go/src/github.com/shirou/gopsutil/process/process_windows.go
new file mode 100644
index 0000000..3176cde
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/process_windows.go
@@ -0,0 +1,357 @@
+// +build windows
+
+package process
+
+import (
+	"errors"
+	"fmt"
+	"strings"
+	"syscall"
+	"time"
+	"unsafe"
+
+	"github.com/StackExchange/wmi"
+	"github.com/shirou/w32"
+
+	cpu "github.com/shirou/gopsutil/cpu"
+	"github.com/shirou/gopsutil/internal/common"
+	net "github.com/shirou/gopsutil/net"
+)
+
+const (
+	NoMoreFiles   = 0x12
+	MaxPathLength = 260
+)
+
+type SystemProcessInformation struct {
+	NextEntryOffset   uint64
+	NumberOfThreads   uint64
+	Reserved1         [48]byte
+	Reserved2         [3]byte
+	UniqueProcessID   uintptr
+	Reserved3         uintptr
+	HandleCount       uint64
+	Reserved4         [4]byte
+	Reserved5         [11]byte
+	PeakPagefileUsage uint64
+	PrivatePageCount  uint64
+	Reserved6         [6]uint64
+}
+
+// Memory_info_ex is different between OSes
+type MemoryInfoExStat struct {
+}
+
+type MemoryMapsStat struct {
+}
+
+type Win32_Process struct {
+	Name           string
+	ExecutablePath *string
+	CommandLine    *string
+	Priority       uint32
+	CreationDate   *time.Time
+	ProcessID      uint32
+	ThreadCount    uint32
+
+	/*
+		CSCreationClassName   string
+		CSName                string
+		Caption               *string
+		CreationClassName     string
+		Description           *string
+		ExecutionState        *uint16
+		HandleCount           uint32
+		KernelModeTime        uint64
+		MaximumWorkingSetSize *uint32
+		MinimumWorkingSetSize *uint32
+		OSCreationClassName   string
+		OSName                string
+		OtherOperationCount   uint64
+		OtherTransferCount    uint64
+		PageFaults            uint32
+		PageFileUsage         uint32
+		ParentProcessID       uint32
+		PeakPageFileUsage     uint32
+		PeakVirtualSize       uint64
+		PeakWorkingSetSize    uint32
+		PrivatePageCount      uint64
+		ReadOperationCount    uint64
+		ReadTransferCount     uint64
+		Status                *string
+		TerminationDate       *time.Time
+		UserModeTime          uint64
+		WorkingSetSize        uint64
+		WriteOperationCount   uint64
+		WriteTransferCount    uint64
+	*/
+}
+
+func Pids() ([]int32, error) {
+	var ret []int32
+
+	procs, err := processes()
+	if err != nil {
+		return ret, nil
+	}
+
+	for _, proc := range procs {
+		ret = append(ret, proc.Pid)
+	}
+
+	return ret, nil
+}
+
+func (p *Process) Ppid() (int32, error) {
+	ret, _, _, err := p.getFromSnapProcess(p.Pid)
+	if err != nil {
+		return 0, err
+	}
+	return ret, nil
+}
+
+func GetWin32Proc(pid int32) ([]Win32_Process, error) {
+	var dst []Win32_Process
+	query := fmt.Sprintf("WHERE ProcessId = %d", pid)
+	q := wmi.CreateQuery(&dst, query)
+	err := wmi.Query(q, &dst)
+	if err != nil {
+		return []Win32_Process{}, fmt.Errorf("could not get win32Proc: %s", err)
+	}
+	if len(dst) != 1 {
+		return []Win32_Process{}, fmt.Errorf("could not get win32Proc: empty")
+	}
+	return dst, nil
+}
+
+func (p *Process) Name() (string, error) {
+	dst, err := GetWin32Proc(p.Pid)
+	if err != nil {
+		return "", fmt.Errorf("could not get Name: %s", err)
+	}
+	return dst[0].Name, nil
+}
+func (p *Process) Exe() (string, error) {
+	dst, err := GetWin32Proc(p.Pid)
+	if err != nil {
+		return "", fmt.Errorf("could not get ExecutablePath: %s", err)
+	}
+	return *dst[0].ExecutablePath, nil
+}
+func (p *Process) Cmdline() (string, error) {
+	dst, err := GetWin32Proc(p.Pid)
+	if err != nil {
+		return "", fmt.Errorf("could not get CommandLine: %s", err)
+	}
+	return *dst[0].CommandLine, nil
+}
+
+// CmdlineSlice returns the command line arguments of the process as a slice with each
+// element being an argument. This merely returns the CommandLine informations passed
+// to the process split on the 0x20 ASCII character.
+func (p *Process) CmdlineSlice() ([]string, error) {
+	cmdline, err := p.Cmdline()
+	if err != nil {
+		return nil, err
+	}
+	return strings.Split(cmdline, " "), nil
+}
+
+func (p *Process) CreateTime() (int64, error) {
+	dst, err := GetWin32Proc(p.Pid)
+	if err != nil {
+		return 0, fmt.Errorf("could not get CreationDate: %s", err)
+	}
+	date := *dst[0].CreationDate
+	return date.Unix(), nil
+}
+
+func (p *Process) Cwd() (string, error) {
+	return "", common.ErrNotImplementedError
+}
+func (p *Process) Parent() (*Process, error) {
+	return p, common.ErrNotImplementedError
+}
+func (p *Process) Status() (string, error) {
+	return "", common.ErrNotImplementedError
+}
+func (p *Process) Username() (string, error) {
+	return "", common.ErrNotImplementedError
+}
+func (p *Process) Uids() ([]int32, error) {
+	var uids []int32
+
+	return uids, common.ErrNotImplementedError
+}
+func (p *Process) Gids() ([]int32, error) {
+	var gids []int32
+	return gids, common.ErrNotImplementedError
+}
+func (p *Process) Terminal() (string, error) {
+	return "", common.ErrNotImplementedError
+}
+
+// Nice returnes priority in Windows
+func (p *Process) Nice() (int32, error) {
+	dst, err := GetWin32Proc(p.Pid)
+	if err != nil {
+		return 0, fmt.Errorf("could not get Priority: %s", err)
+	}
+	return int32(dst[0].Priority), nil
+}
+func (p *Process) IOnice() (int32, error) {
+	return 0, common.ErrNotImplementedError
+}
+func (p *Process) Rlimit() ([]RlimitStat, error) {
+	var rlimit []RlimitStat
+
+	return rlimit, common.ErrNotImplementedError
+}
+func (p *Process) IOCounters() (*IOCountersStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+func (p *Process) NumFDs() (int32, error) {
+	return 0, common.ErrNotImplementedError
+}
+func (p *Process) NumThreads() (int32, error) {
+	dst, err := GetWin32Proc(p.Pid)
+	if err != nil {
+		return 0, fmt.Errorf("could not get ThreadCount: %s", err)
+	}
+	return int32(dst[0].ThreadCount), nil
+}
+func (p *Process) Threads() (map[string]string, error) {
+	ret := make(map[string]string, 0)
+	return ret, common.ErrNotImplementedError
+}
+func (p *Process) Times() (*cpu.TimesStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+func (p *Process) CPUAffinity() ([]int32, error) {
+	return nil, common.ErrNotImplementedError
+}
+func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) Children() ([]*Process, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) Connections() ([]net.ConnectionStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
+	return nil, common.ErrNotImplementedError
+}
+
+func (p *Process) IsRunning() (bool, error) {
+	return true, common.ErrNotImplementedError
+}
+
+func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
+	var ret []MemoryMapsStat
+	return &ret, common.ErrNotImplementedError
+}
+
+func NewProcess(pid int32) (*Process, error) {
+	p := &Process{Pid: pid}
+
+	return p, nil
+}
+
+func (p *Process) SendSignal(sig syscall.Signal) error {
+	return common.ErrNotImplementedError
+}
+
+func (p *Process) Suspend() error {
+	return common.ErrNotImplementedError
+}
+func (p *Process) Resume() error {
+	return common.ErrNotImplementedError
+}
+func (p *Process) Terminate() error {
+	return common.ErrNotImplementedError
+}
+func (p *Process) Kill() error {
+	return common.ErrNotImplementedError
+}
+
+func (p *Process) getFromSnapProcess(pid int32) (int32, int32, string, error) {
+	snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPPROCESS, uint32(pid))
+	if snap == 0 {
+		return 0, 0, "", syscall.GetLastError()
+	}
+	defer w32.CloseHandle(snap)
+	var pe32 w32.PROCESSENTRY32
+	pe32.DwSize = uint32(unsafe.Sizeof(pe32))
+	if w32.Process32First(snap, &pe32) == false {
+		return 0, 0, "", syscall.GetLastError()
+	}
+
+	if pe32.Th32ProcessID == uint32(pid) {
+		szexe := syscall.UTF16ToString(pe32.SzExeFile[:])
+		return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil
+	}
+
+	for w32.Process32Next(snap, &pe32) {
+		if pe32.Th32ProcessID == uint32(pid) {
+			szexe := syscall.UTF16ToString(pe32.SzExeFile[:])
+			return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil
+		}
+	}
+	return 0, 0, "", errors.New("Couldn't find pid:" + string(pid))
+}
+
+// Get processes
+func processes() ([]*Process, error) {
+
+	var dst []Win32_Process
+	q := wmi.CreateQuery(&dst, "")
+	err := wmi.Query(q, &dst)
+	if err != nil {
+		return []*Process{}, err
+	}
+	if len(dst) == 0 {
+		return []*Process{}, fmt.Errorf("could not get Process")
+	}
+	results := make([]*Process, 0, len(dst))
+	for _, proc := range dst {
+		p, err := NewProcess(int32(proc.ProcessID))
+		if err != nil {
+			continue
+		}
+		results = append(results, p)
+	}
+
+	return results, nil
+}
+
+func getProcInfo(pid int32) (*SystemProcessInformation, error) {
+	initialBufferSize := uint64(0x4000)
+	bufferSize := initialBufferSize
+	buffer := make([]byte, bufferSize)
+
+	var sysProcInfo SystemProcessInformation
+	ret, _, _ := common.ProcNtQuerySystemInformation.Call(
+		uintptr(unsafe.Pointer(&sysProcInfo)),
+		uintptr(unsafe.Pointer(&buffer[0])),
+		uintptr(unsafe.Pointer(&bufferSize)),
+		uintptr(unsafe.Pointer(&bufferSize)))
+	if ret != 0 {
+		return nil, syscall.GetLastError()
+	}
+
+	return &sysProcInfo, nil
+}
diff --git a/go/src/github.com/shirou/gopsutil/process/types_darwin.go b/go/src/github.com/shirou/gopsutil/process/types_darwin.go
new file mode 100644
index 0000000..21216cd
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/types_darwin.go
@@ -0,0 +1,160 @@
+// 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.
+
+// Hand Writing
+// - all pointer in ExternProc to uint64
+
+// +build ignore
+
+/*
+Input to cgo -godefs.
+*/
+
+// +godefs map struct_in_addr [4]byte /* in_addr */
+// +godefs map struct_in6_addr [16]byte /* in6_addr */
+// +godefs map struct_ [16]byte /* in6_addr */
+
+package process
+
+/*
+#define __DARWIN_UNIX03 0
+#define KERNEL
+#define _DARWIN_USE_64_BIT_INODE
+#include <dirent.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <termios.h>
+#include <unistd.h>
+#include <mach/mach.h>
+#include <mach/message.h>
+#include <sys/event.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/resource.h>
+#include <sys/select.h>
+#include <sys/signal.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <net/bpf.h>
+#include <net/if_dl.h>
+#include <net/if_var.h>
+#include <net/route.h>
+#include <netinet/in.h>
+
+#include <sys/sysctl.h>
+#include <sys/ucred.h>
+#include <sys/proc.h>
+#include <sys/time.h>
+#include <sys/_types/_timeval.h>
+#include <sys/appleapiopts.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <bsm/audit.h>
+#include <sys/queue.h>
+
+enum {
+	sizeofPtr = sizeof(void*),
+};
+
+union sockaddr_all {
+	struct sockaddr s1;	// this one gets used for fields
+	struct sockaddr_in s2;	// these pad it out
+	struct sockaddr_in6 s3;
+	struct sockaddr_un s4;
+	struct sockaddr_dl s5;
+};
+
+struct sockaddr_any {
+	struct sockaddr addr;
+	char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
+};
+
+struct ucred_queue {
+        struct ucred *tqe_next;
+        struct ucred **tqe_prev;
+        TRACEBUF
+};
+
+*/
+import "C"
+
+// Machine characteristics; for internal use.
+
+const (
+	sizeofPtr      = C.sizeofPtr
+	sizeofShort    = C.sizeof_short
+	sizeofInt      = C.sizeof_int
+	sizeofLong     = C.sizeof_long
+	sizeofLongLong = C.sizeof_longlong
+)
+
+// Basic types
+
+type (
+	_C_short     C.short
+	_C_int       C.int
+	_C_long      C.long
+	_C_long_long C.longlong
+)
+
+// Time
+
+type Timespec C.struct_timespec
+
+type Timeval C.struct_timeval
+
+// Processes
+
+type Rusage C.struct_rusage
+
+type Rlimit C.struct_rlimit
+
+type UGid_t C.gid_t
+
+type KinfoProc C.struct_kinfo_proc
+
+type Eproc C.struct_eproc
+
+type Proc C.struct_proc
+
+type Session C.struct_session
+
+type ucred C.struct_ucred
+
+type Uucred C.struct__ucred
+
+type Upcred C.struct__pcred
+
+type Vmspace C.struct_vmspace
+
+type Sigacts C.struct_sigacts
+
+type ExternProc C.struct_extern_proc
+
+type Itimerval C.struct_itimerval
+
+type Vnode C.struct_vnode
+
+type Pgrp C.struct_pgrp
+
+type UserStruct C.struct_user
+
+type Au_session C.struct_au_session
+
+type Posix_cred C.struct_posix_cred
+
+type Label C.struct_label
+
+type AuditinfoAddr C.struct_auditinfo_addr
+type AuMask C.struct_au_mask
+type AuTidAddr C.struct_au_tid_addr
+
+// TAILQ(ucred)
+type UcredQueue C.struct_ucred_queue
diff --git a/go/src/github.com/shirou/gopsutil/process/types_freebsd.go b/go/src/github.com/shirou/gopsutil/process/types_freebsd.go
new file mode 100644
index 0000000..aa7b346
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/process/types_freebsd.go
@@ -0,0 +1,95 @@
+// +build ignore
+
+// We still need editing by hands.
+// go tool cgo -godefs types_freebsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/'  > process_freebsd_amd64.go
+
+/*
+Input to cgo -godefs.
+*/
+
+// +godefs map struct_pargs int64 /* pargs */
+// +godefs map struct_proc int64 /* proc */
+// +godefs map struct_user int64 /* user */
+// +godefs map struct_vnode int64 /* vnode */
+// +godefs map struct_vnode int64 /* vnode */
+// +godefs map struct_filedesc int64 /* filedesc */
+// +godefs map struct_vmspace int64 /* vmspace */
+// +godefs map struct_pcb int64 /* pcb */
+// +godefs map struct_thread int64 /* thread */
+// +godefs map struct___sigset [16]byte /* sigset */
+
+package process
+
+/*
+#include <sys/types.h>
+#include <sys/user.h>
+
+enum {
+	sizeofPtr = sizeof(void*),
+};
+
+
+*/
+import "C"
+
+// Machine characteristics; for internal use.
+
+const (
+	CTLKern          = 1  // "high kernel": proc, limits
+	KernProc         = 14 // struct: process entries
+	KernProcPID      = 1  // by process id
+	KernProcProc     = 8  // only return procs
+	KernProcPathname = 12 // path to executable
+	KernProcArgs     = 7  // get/set arguments/proctitle
+)
+
+const (
+	sizeofPtr      = C.sizeofPtr
+	sizeofShort    = C.sizeof_short
+	sizeofInt      = C.sizeof_int
+	sizeofLong     = C.sizeof_long
+	sizeofLongLong = C.sizeof_longlong
+)
+
+const (
+	sizeOfKinfoVmentry = C.sizeof_struct_kinfo_vmentry
+	sizeOfKinfoProc    = C.sizeof_struct_kinfo_proc
+)
+
+// from sys/proc.h
+const (
+	SIDL   = 1 /* Process being created by fork. */
+	SRUN   = 2 /* Currently runnable. */
+	SSLEEP = 3 /* Sleeping on an address. */
+	SSTOP  = 4 /* Process debugging or suspension. */
+	SZOMB  = 5 /* Awaiting collection by parent. */
+	SWAIT  = 6 /* Waiting for interrupt. */
+	SLOCK  = 7 /* Blocked on a lock. */
+)
+
+// Basic types
+
+type (
+	_C_short     C.short
+	_C_int       C.int
+	_C_long      C.long
+	_C_long_long C.longlong
+)
+
+// Time
+
+type Timespec C.struct_timespec
+
+type Timeval C.struct_timeval
+
+// Processes
+
+type Rusage C.struct_rusage
+
+type Rlimit C.struct_rlimit
+
+type KinfoProc C.struct_kinfo_proc
+
+type Priority C.struct_priority
+
+type KinfoVmentry C.struct_kinfo_vmentry
diff --git a/go/src/github.com/shirou/gopsutil/v2migration.sh b/go/src/github.com/shirou/gopsutil/v2migration.sh
new file mode 100644
index 0000000..978cc44
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/v2migration.sh
@@ -0,0 +1,134 @@
+# This script is a helper of migration to gopsutil v2 using gorename
+# 
+# go get golang.org/x/tools/cmd/gorename
+
+IFS=$'\n'
+
+## Part 1. rename Functions to pass golint.  ex) cpu.CPUTimesStat -> cpu.TimesStat
+
+#
+# Note:
+#   process has IOCounters() for file IO, and also NetIOCounters() for Net IO.
+#   This scripts replace process.NetIOCounters() to IOCounters().
+#   So you need hand-fixing process.
+
+TARGETS=`cat <<EOF
+CPUTimesStat -> TimesStat
+CPUInfoStat -> InfoStat
+CPUTimes -> Times
+CPUInfo -> Info
+CPUCounts -> Counts
+CPUPercent -> Percent
+DiskUsageStat -> UsageStat
+DiskPartitionStat -> PartitionStat
+DiskIOCountersStat -> IOCountersStat
+DiskPartitions -> Partitions
+DiskIOCounters -> IOCounters
+DiskUsage -> Usage
+HostInfoStat -> InfoStat
+HostInfo -> Info
+GetVirtualization -> Virtualization
+GetPlatformInformation -> PlatformInformation
+LoadAvgStat -> AvgStat
+LoadAvg -> Avg
+NetIOCountersStat -> IOCountersStat
+NetConnectionStat -> ConnectionStat
+NetProtoCountersStat -> ProtoCountersStat
+NetInterfaceAddr -> InterfaceAddr
+NetInterfaceStat -> InterfaceStat
+NetFilterStat -> FilterStat
+NetInterfaces -> Interfaces
+getNetIOCountersAll -> getIOCountersAll
+NetIOCounters -> IOCounters
+NetIOCountersByFile -> IOCountersByFile
+NetProtoCounters -> ProtoCounters
+NetFilterCounters -> FilterCounters
+NetConnections -> Connections
+NetConnectionsPid -> ConnectionsPid
+Uid -> UID
+Id -> ID
+convertCpuTimes -> convertCPUTimes
+EOF`
+
+for T in $TARGETS
+do
+  echo $T
+  gofmt -w -r "$T" ./*.go
+done
+
+
+###### Part 2  rename JSON key name
+## Google JSOn style
+## https://google.github.io/styleguide/jsoncstyleguide.xml
+
+sed -i "" 's/guest_nice/guestNice/g' cpu/*.go
+sed -i "" 's/vendor_id/vendorId/g' cpu/*.go
+sed -i "" 's/physical_id/physicalId/g' cpu/*.go
+sed -i "" 's/model_name/modelName/g' cpu/*.go
+sed -i "" 's/cache_size/cacheSize/g' cpu/*.go
+sed -i "" 's/core_id/coreId/g' cpu/*.go
+
+sed -i "" 's/inodes_total/inodesTotal/g' disk/*.go
+sed -i "" 's/inodes_used/inodesUsed/g' disk/*.go
+sed -i "" 's/inodes_free/inodesFree/g' disk/*.go
+sed -i "" 's/inodes_used_percent/inodesUsedPercent/g' disk/*.go
+sed -i "" 's/read_count/readCount/g' disk/*.go
+sed -i "" 's/write_count/writeCount/g' disk/*.go
+sed -i "" 's/read_bytes/readBytes/g' disk/*.go
+sed -i "" 's/write_bytes/writeBytes/g' disk/*.go
+sed -i "" 's/read_time/readTime/g' disk/*.go
+sed -i "" 's/write_time/writeTime/g' disk/*.go
+sed -i "" 's/io_time/ioTime/g' disk/*.go
+sed -i "" 's/serial_number/serialNumber/g' disk/*.go
+sed -i "" 's/used_percent/usedPercent/g' disk/*.go
+sed -i "" 's/inodesUsed_percent/inodesUsedPercent/g' disk/*.go
+
+sed -i "" 's/total_cache/totalCache/g' docker/*.go
+sed -i "" 's/total_rss_huge/totalRssHuge/g' docker/*.go
+sed -i "" 's/total_rss/totalRss/g' docker/*.go
+sed -i "" 's/total_mapped_file/totalMappedFile/g' docker/*.go
+sed -i "" 's/total_pgpgin/totalPgpgin/g' docker/*.go
+sed -i "" 's/total_pgpgout/totalPgpgout/g' docker/*.go
+sed -i "" 's/total_pgfault/totalPgfault/g' docker/*.go
+sed -i "" 's/total_pgmajfault/totalPgmajfault/g' docker/*.go
+sed -i "" 's/total_inactive_anon/totalInactiveAnon/g' docker/*.go
+sed -i "" 's/total_active_anon/totalActiveAnon/g' docker/*.go
+sed -i "" 's/total_inactive_file/totalInactiveFile/g' docker/*.go
+sed -i "" 's/total_active_file/totalActiveFile/g' docker/*.go
+sed -i "" 's/total_unevictable/totalUnevictable/g' docker/*.go
+sed -i "" 's/mem_usage_in_bytes/memUsageInBytes/g' docker/*.go
+sed -i "" 's/mem_max_usage_in_bytes/memMaxUsageInBytes/g' docker/*.go
+sed -i "" 's/memory.limit_in_bytes/memoryLimitInBbytes/g' docker/*.go
+sed -i "" 's/memory.failcnt/memoryFailcnt/g' docker/*.go
+sed -i "" 's/mapped_file/mappedFile/g' docker/*.go
+sed -i "" 's/container_id/containerID/g' docker/*.go
+sed -i "" 's/rss_huge/rssHuge/g' docker/*.go
+sed -i "" 's/inactive_anon/inactiveAnon/g' docker/*.go
+sed -i "" 's/active_anon/activeAnon/g' docker/*.go
+sed -i "" 's/inactive_file/inactiveFile/g' docker/*.go
+sed -i "" 's/active_file/activeFile/g' docker/*.go
+sed -i "" 's/hierarchical_memory_limit/hierarchicalMemoryLimit/g' docker/*.go
+
+sed -i "" 's/boot_time/bootTime/g' host/*.go
+sed -i "" 's/platform_family/platformFamily/g' host/*.go
+sed -i "" 's/platform_version/platformVersion/g' host/*.go
+sed -i "" 's/virtualization_system/virtualizationSystem/g' host/*.go
+sed -i "" 's/virtualization_role/virtualizationRole/g' host/*.go
+
+sed -i "" 's/used_percent/usedPercent/g' mem/*.go
+
+sed -i "" 's/bytes_sent/bytesSent/g' net/*.go
+sed -i "" 's/bytes_recv/bytesRecv/g' net/*.go
+sed -i "" 's/packets_sent/packetsSent/g' net/*.go
+sed -i "" 's/packets_recv/packetsRecv/g' net/*.go
+sed -i "" 's/conntrack_count/conntrackCount/g' net/*.go
+sed -i "" 's/conntrack_max/conntrackMax/g' net/*.go
+
+sed -i "" 's/read_count/readCount/g' process/*.go
+sed -i "" 's/write_count/writeCount/g' process/*.go
+sed -i "" 's/read_bytes/readBytes/g' process/*.go
+sed -i "" 's/write_bytes/writeBytes/g' process/*.go
+sed -i "" 's/shared_clean/sharedClean/g' process/*.go
+sed -i "" 's/shared_dirty/sharedDirty/g' process/*.go
+sed -i "" 's/private_clean/privateClean/g' process/*.go
+sed -i "" 's/private_dirty/privateDirty/g' process/*.go
diff --git a/go/src/github.com/shirou/gopsutil/windows_memo.rst b/go/src/github.com/shirou/gopsutil/windows_memo.rst
new file mode 100644
index 0000000..38abed8
--- /dev/null
+++ b/go/src/github.com/shirou/gopsutil/windows_memo.rst
@@ -0,0 +1,36 @@
+Windows memo
+=====================
+
+Size
+----------
+
+DWORD
+  32-bit unsigned integer
+DWORDLONG
+  64-bit unsigned integer
+DWORD_PTR
+  unsigned long type for pointer precision
+DWORD32
+  32-bit unsigned integer
+DWORD64
+  64-bit unsigned integer
+HALF_PTR
+  _WIN64 = int, else short
+INT
+  32-bit signed integer
+INT_PTR
+  _WIN64 = __int64 else int
+LONG
+  32-bit signed integer
+LONGLONG
+  64-bit signed integer
+LONG_PTR
+  _WIN64 = __int64 else long
+SHORT
+  16-bit integer
+SIZE_T
+  maximum number of bytes to which a pointer can point. typedef ULONG_PTR SIZE_T;
+SSIZE_T
+  signed version of SIZE_T. typedef LONG_PTR SSIZE_T;
+WORD
+  16-bit unsigned integer
\ No newline at end of file
diff --git a/go/src/github.com/stretchr/objx/.gitignore b/go/src/github.com/stretchr/objx/.gitignore
new file mode 100644
index 0000000..0026861
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/.gitignore
@@ -0,0 +1,22 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
diff --git a/go/src/github.com/stretchr/objx/LICENSE.md b/go/src/github.com/stretchr/objx/LICENSE.md
new file mode 100644
index 0000000..2199945
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/LICENSE.md
@@ -0,0 +1,23 @@
+objx - by Mat Ryer and Tyler Bunnell
+
+The MIT License (MIT)
+
+Copyright (c) 2014 Stretchr, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/go/src/github.com/stretchr/objx/README.google b/go/src/github.com/stretchr/objx/README.google
new file mode 100644
index 0000000..4d38f10
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/README.google
@@ -0,0 +1,10 @@
+URL: https://github.com/stretchr/objx/archive/1a9d0bb9f541897e62256577b352fdbc1fb4fd94.zip
+Version: 1a9d0bb9f541897e62256577b352fdbc1fb4fd94
+License: MIT
+License File: LICENSE.md
+
+Description:
+Go package for dealing with maps, slices, JSON and other data.
+
+Local Modifications:
+None.
diff --git a/go/src/github.com/stretchr/objx/README.md b/go/src/github.com/stretchr/objx/README.md
new file mode 100644
index 0000000..4aa1806
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/README.md
@@ -0,0 +1,3 @@
+# objx
+
+  * Jump into the [API Documentation](http://godoc.org/github.com/stretchr/objx)
diff --git a/go/src/github.com/stretchr/objx/accessors.go b/go/src/github.com/stretchr/objx/accessors.go
new file mode 100644
index 0000000..721bcac
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/accessors.go
@@ -0,0 +1,179 @@
+package objx
+
+import (
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+// arrayAccesRegexString is the regex used to extract the array number
+// from the access path
+const arrayAccesRegexString = `^(.+)\[([0-9]+)\]$`
+
+// arrayAccesRegex is the compiled arrayAccesRegexString
+var arrayAccesRegex = regexp.MustCompile(arrayAccesRegexString)
+
+// Get gets the value using the specified selector and
+// returns it inside a new Obj object.
+//
+// If it cannot find the value, Get will return a nil
+// value inside an instance of Obj.
+//
+// Get can only operate directly on map[string]interface{} and []interface.
+//
+// Example
+//
+// To access the title of the third chapter of the second book, do:
+//
+//    o.Get("books[1].chapters[2].title")
+func (m Map) Get(selector string) *Value {
+	rawObj := access(m, selector, nil, false, false)
+	return &Value{data: rawObj}
+}
+
+// Set sets the value using the specified selector and
+// returns the object on which Set was called.
+//
+// Set can only operate directly on map[string]interface{} and []interface
+//
+// Example
+//
+// To set the title of the third chapter of the second book, do:
+//
+//    o.Set("books[1].chapters[2].title","Time to Go")
+func (m Map) Set(selector string, value interface{}) Map {
+	access(m, selector, value, true, false)
+	return m
+}
+
+// access accesses the object using the selector and performs the
+// appropriate action.
+func access(current, selector, value interface{}, isSet, panics bool) interface{} {
+
+	switch selector.(type) {
+	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
+
+		if array, ok := current.([]interface{}); ok {
+			index := intFromInterface(selector)
+
+			if index >= len(array) {
+				if panics {
+					panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array)))
+				}
+				return nil
+			}
+
+			return array[index]
+		}
+
+		return nil
+
+	case string:
+
+		selStr := selector.(string)
+		selSegs := strings.SplitN(selStr, PathSeparator, 2)
+		thisSel := selSegs[0]
+		index := -1
+		var err error
+
+		// https://github.com/stretchr/objx/issues/12
+		if strings.Contains(thisSel, "[") {
+
+			arrayMatches := arrayAccesRegex.FindStringSubmatch(thisSel)
+
+			if len(arrayMatches) > 0 {
+
+				// Get the key into the map
+				thisSel = arrayMatches[1]
+
+				// Get the index into the array at the key
+				index, err = strconv.Atoi(arrayMatches[2])
+
+				if err != nil {
+					// This should never happen. If it does, something has gone
+					// seriously wrong. Panic.
+					panic("objx: Array index is not an integer.  Must use array[int].")
+				}
+
+			}
+		}
+
+		if curMap, ok := current.(Map); ok {
+			current = map[string]interface{}(curMap)
+		}
+
+		// get the object in question
+		switch current.(type) {
+		case map[string]interface{}:
+			curMSI := current.(map[string]interface{})
+			if len(selSegs) <= 1 && isSet {
+				curMSI[thisSel] = value
+				return nil
+			} else {
+				current = curMSI[thisSel]
+			}
+		default:
+			current = nil
+		}
+
+		if current == nil && panics {
+			panic(fmt.Sprintf("objx: '%v' invalid on object.", selector))
+		}
+
+		// do we need to access the item of an array?
+		if index > -1 {
+			if array, ok := current.([]interface{}); ok {
+				if index < len(array) {
+					current = array[index]
+				} else {
+					if panics {
+						panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array)))
+					}
+					current = nil
+				}
+			}
+		}
+
+		if len(selSegs) > 1 {
+			current = access(current, selSegs[1], value, isSet, panics)
+		}
+
+	}
+
+	return current
+
+}
+
+// intFromInterface converts an interface object to the largest
+// representation of an unsigned integer using a type switch and
+// assertions
+func intFromInterface(selector interface{}) int {
+	var value int
+	switch selector.(type) {
+	case int:
+		value = selector.(int)
+	case int8:
+		value = int(selector.(int8))
+	case int16:
+		value = int(selector.(int16))
+	case int32:
+		value = int(selector.(int32))
+	case int64:
+		value = int(selector.(int64))
+	case uint:
+		value = int(selector.(uint))
+	case uint8:
+		value = int(selector.(uint8))
+	case uint16:
+		value = int(selector.(uint16))
+	case uint32:
+		value = int(selector.(uint32))
+	case uint64:
+		value = int(selector.(uint64))
+	default:
+		panic("objx: array access argument is not an integer type (this should never happen)")
+	}
+
+	return value
+}
diff --git a/go/src/github.com/stretchr/objx/accessors_test.go b/go/src/github.com/stretchr/objx/accessors_test.go
new file mode 100644
index 0000000..ce5d8e4
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/accessors_test.go
@@ -0,0 +1,145 @@
+package objx
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestAccessorsAccessGetSingleField(t *testing.T) {
+
+	current := map[string]interface{}{"name": "Tyler"}
+	assert.Equal(t, "Tyler", access(current, "name", nil, false, true))
+
+}
+func TestAccessorsAccessGetDeep(t *testing.T) {
+
+	current := map[string]interface{}{"name": map[string]interface{}{"first": "Tyler", "last": "Bunnell"}}
+	assert.Equal(t, "Tyler", access(current, "name.first", nil, false, true))
+	assert.Equal(t, "Bunnell", access(current, "name.last", nil, false, true))
+
+}
+func TestAccessorsAccessGetDeepDeep(t *testing.T) {
+
+	current := map[string]interface{}{"one": map[string]interface{}{"two": map[string]interface{}{"three": map[string]interface{}{"four": 4}}}}
+	assert.Equal(t, 4, access(current, "one.two.three.four", nil, false, true))
+
+}
+func TestAccessorsAccessGetInsideArray(t *testing.T) {
+
+	current := map[string]interface{}{"names": []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}}}
+	assert.Equal(t, "Tyler", access(current, "names[0].first", nil, false, true))
+	assert.Equal(t, "Bunnell", access(current, "names[0].last", nil, false, true))
+	assert.Equal(t, "Capitol", access(current, "names[1].first", nil, false, true))
+	assert.Equal(t, "Bollocks", access(current, "names[1].last", nil, false, true))
+
+	assert.Panics(t, func() {
+		access(current, "names[2]", nil, false, true)
+	})
+	assert.Nil(t, access(current, "names[2]", nil, false, false))
+
+}
+
+func TestAccessorsAccessGetFromArrayWithInt(t *testing.T) {
+
+	current := []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}}
+	one := access(current, 0, nil, false, false)
+	two := access(current, 1, nil, false, false)
+	three := access(current, 2, nil, false, false)
+
+	assert.Equal(t, "Tyler", one.(map[string]interface{})["first"])
+	assert.Equal(t, "Capitol", two.(map[string]interface{})["first"])
+	assert.Nil(t, three)
+
+}
+
+func TestAccessorsGet(t *testing.T) {
+
+	current := New(map[string]interface{}{"name": "Tyler"})
+	assert.Equal(t, "Tyler", current.Get("name").data)
+
+}
+
+func TestAccessorsAccessSetSingleField(t *testing.T) {
+
+	current := map[string]interface{}{"name": "Tyler"}
+	access(current, "name", "Mat", true, false)
+	assert.Equal(t, current["name"], "Mat")
+
+	access(current, "age", 29, true, true)
+	assert.Equal(t, current["age"], 29)
+
+}
+
+func TestAccessorsAccessSetSingleFieldNotExisting(t *testing.T) {
+
+	current := map[string]interface{}{}
+	access(current, "name", "Mat", true, false)
+	assert.Equal(t, current["name"], "Mat")
+
+}
+
+func TestAccessorsAccessSetDeep(t *testing.T) {
+
+	current := map[string]interface{}{"name": map[string]interface{}{"first": "Tyler", "last": "Bunnell"}}
+
+	access(current, "name.first", "Mat", true, true)
+	access(current, "name.last", "Ryer", true, true)
+
+	assert.Equal(t, "Mat", access(current, "name.first", nil, false, true))
+	assert.Equal(t, "Ryer", access(current, "name.last", nil, false, true))
+
+}
+func TestAccessorsAccessSetDeepDeep(t *testing.T) {
+
+	current := map[string]interface{}{"one": map[string]interface{}{"two": map[string]interface{}{"three": map[string]interface{}{"four": 4}}}}
+
+	access(current, "one.two.three.four", 5, true, true)
+
+	assert.Equal(t, 5, access(current, "one.two.three.four", nil, false, true))
+
+}
+func TestAccessorsAccessSetArray(t *testing.T) {
+
+	current := map[string]interface{}{"names": []interface{}{"Tyler"}}
+
+	access(current, "names[0]", "Mat", true, true)
+
+	assert.Equal(t, "Mat", access(current, "names[0]", nil, false, true))
+
+}
+func TestAccessorsAccessSetInsideArray(t *testing.T) {
+
+	current := map[string]interface{}{"names": []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}}}
+
+	access(current, "names[0].first", "Mat", true, true)
+	access(current, "names[0].last", "Ryer", true, true)
+	access(current, "names[1].first", "Captain", true, true)
+	access(current, "names[1].last", "Underpants", true, true)
+
+	assert.Equal(t, "Mat", access(current, "names[0].first", nil, false, true))
+	assert.Equal(t, "Ryer", access(current, "names[0].last", nil, false, true))
+	assert.Equal(t, "Captain", access(current, "names[1].first", nil, false, true))
+	assert.Equal(t, "Underpants", access(current, "names[1].last", nil, false, true))
+
+}
+
+func TestAccessorsAccessSetFromArrayWithInt(t *testing.T) {
+
+	current := []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}}
+	one := access(current, 0, nil, false, false)
+	two := access(current, 1, nil, false, false)
+	three := access(current, 2, nil, false, false)
+
+	assert.Equal(t, "Tyler", one.(map[string]interface{})["first"])
+	assert.Equal(t, "Capitol", two.(map[string]interface{})["first"])
+	assert.Nil(t, three)
+
+}
+
+func TestAccessorsSet(t *testing.T) {
+
+	current := New(map[string]interface{}{"name": "Tyler"})
+	current.Set("name", "Mat")
+	assert.Equal(t, "Mat", current.Get("name").data)
+
+}
diff --git a/go/src/github.com/stretchr/objx/codegen/array-access.txt b/go/src/github.com/stretchr/objx/codegen/array-access.txt
new file mode 100644
index 0000000..3060234
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/codegen/array-access.txt
@@ -0,0 +1,14 @@
+  case []{1}:
+    a := object.([]{1})
+    if isSet {
+      a[index] = value.({1})
+    } else {
+      if index >= len(a) {
+        if panics {
+          panic(fmt.Sprintf("objx: Index %d is out of range because the []{1} only contains %d items.", index, len(a)))
+        }
+        return nil
+      } else {
+        return a[index]
+      }
+    }
diff --git a/go/src/github.com/stretchr/objx/codegen/index.html b/go/src/github.com/stretchr/objx/codegen/index.html
new file mode 100644
index 0000000..379ffc3
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/codegen/index.html
@@ -0,0 +1,86 @@
+<html>
+	<head>
+	<title>
+		Codegen
+	</title>
+	<style>
+		body {
+			width: 800px;
+			margin: auto;
+		}
+		textarea {
+			width: 100%;
+			min-height: 100px;
+			font-family: Courier;
+		}
+	</style>
+	</head>
+	<body>
+
+		<h2>
+			Template
+		</h2>
+		<p>
+			Use <code>{x}</code> as a placeholder for each argument.
+		</p>
+		<textarea id="template"></textarea>
+
+		<h2>
+			Arguments (comma separated)
+		</h2>
+		<p>
+			One block per line
+		</p>
+		<textarea id="args"></textarea>
+
+		<h2>
+			Output
+		</h2>
+		<input id="go" type="button" value="Generate code" />
+
+		<textarea id="output"></textarea>
+
+		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
+		<script>
+
+			$(function(){
+
+				$("#go").click(function(){
+
+					var output = ""
+					var template = $("#template").val()
+					var args = $("#args").val()
+
+					// collect the args
+					var argLines = args.split("\n")
+					for (var line in argLines) {
+
+						var argLine = argLines[line];
+						var thisTemp = template
+
+						// get individual args
+						var args = argLine.split(",")
+
+						for (var argI in args) {
+							var argText = args[argI];
+							var argPlaceholder = "{" + argI + "}";
+
+							while (thisTemp.indexOf(argPlaceholder) > -1) {
+								thisTemp = thisTemp.replace(argPlaceholder, argText);
+							}
+
+						}
+
+						output += thisTemp
+
+					}
+
+					$("#output").val(output);
+
+				});
+
+			});
+
+		</script>
+	</body>
+</html>
diff --git a/go/src/github.com/stretchr/objx/codegen/template.txt b/go/src/github.com/stretchr/objx/codegen/template.txt
new file mode 100644
index 0000000..b396900
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/codegen/template.txt
@@ -0,0 +1,286 @@
+/*
+	{4} ({1} and []{1})
+	--------------------------------------------------
+*/
+
+// {4} gets the value as a {1}, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) {4}(optionalDefault ...{1}) {1} {
+	if s, ok := v.data.({1}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return {3}
+}
+
+// Must{4} gets the value as a {1}.
+//
+// Panics if the object is not a {1}.
+func (v *Value) Must{4}() {1} {
+	return v.data.({1})
+}
+
+// {4}Slice gets the value as a []{1}, returns the optionalDefault
+// value or nil if the value is not a []{1}.
+func (v *Value) {4}Slice(optionalDefault ...[]{1}) []{1} {
+	if s, ok := v.data.([]{1}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// Must{4}Slice gets the value as a []{1}.
+//
+// Panics if the object is not a []{1}.
+func (v *Value) Must{4}Slice() []{1} {
+	return v.data.([]{1})
+}
+
+// Is{4} gets whether the object contained is a {1} or not.
+func (v *Value) Is{4}() bool {
+  _, ok := v.data.({1})
+  return ok
+}
+
+// Is{4}Slice gets whether the object contained is a []{1} or not.
+func (v *Value) Is{4}Slice() bool {
+	_, ok := v.data.([]{1})
+	return ok
+}
+
+// Each{4} calls the specified callback for each object
+// in the []{1}.
+//
+// Panics if the object is the wrong type.
+func (v *Value) Each{4}(callback func(int, {1}) bool) *Value {
+
+	for index, val := range v.Must{4}Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// Where{4} uses the specified decider function to select items
+// from the []{1}.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) Where{4}(decider func(int, {1}) bool) *Value {
+
+	var selected []{1}
+
+	v.Each{4}(func(index int, val {1}) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data:selected}
+
+}
+
+// Group{4} uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]{1}.
+func (v *Value) Group{4}(grouper func(int, {1}) string) *Value {
+
+	groups := make(map[string][]{1})
+
+	v.Each{4}(func(index int, val {1}) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]{1}, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data:groups}
+
+}
+
+// Replace{4} uses the specified function to replace each {1}s
+// by iterating each item.  The data in the returned result will be a
+// []{1} containing the replaced items.
+func (v *Value) Replace{4}(replacer func(int, {1}) {1}) *Value {
+
+	arr := v.Must{4}Slice()
+	replaced := make([]{1}, len(arr))
+
+	v.Each{4}(func(index int, val {1}) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data:replaced}
+
+}
+
+// Collect{4} uses the specified collector function to collect a value
+// for each of the {1}s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) Collect{4}(collector func(int, {1}) interface{}) *Value {
+
+	arr := v.Must{4}Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.Each{4}(func(index int, val {1}) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data:collected}
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func Test{4}(t *testing.T) {
+
+  val := {1}( {2} )
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").{4}())
+	assert.Equal(t, val, New(m).Get("value").Must{4}())
+	assert.Equal(t, {1}({3}), New(m).Get("nothing").{4}())
+	assert.Equal(t, val, New(m).Get("nothing").{4}({2}))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").Must{4}()
+	})
+
+}
+
+func Test{4}Slice(t *testing.T) {
+
+  val := {1}( {2} )
+	m := map[string]interface{}{"value": []{1}{ val }, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").{4}Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").Must{4}Slice()[0])
+	assert.Equal(t, []{1}(nil), New(m).Get("nothing").{4}Slice())
+	assert.Equal(t, val, New(m).Get("nothing").{4}Slice( []{1}{ {1}({2}) } )[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").Must{4}Slice()
+	})
+
+}
+
+func TestIs{4}(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: {1}({2})}
+	assert.True(t, v.Is{4}())
+
+	v = &Value{data: []{1}{ {1}({2}) }}
+	assert.True(t, v.Is{4}Slice())
+
+}
+
+func TestEach{4}(t *testing.T) {
+
+	v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
+	count := 0
+	replacedVals := make([]{1}, 0)
+	assert.Equal(t, v, v.Each{4}(func(i int, val {1}) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.Must{4}Slice()[0])
+	assert.Equal(t, replacedVals[1], v.Must{4}Slice()[1])
+	assert.Equal(t, replacedVals[2], v.Must{4}Slice()[2])
+
+}
+
+func TestWhere{4}(t *testing.T) {
+
+	v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
+
+	selected := v.Where{4}(func(i int, val {1}) bool {
+		return i%2==0
+	}).Must{4}Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroup{4}(t *testing.T) {
+
+	v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
+
+	grouped := v.Group{4}(func(i int, val {1}) string {
+		return fmt.Sprintf("%v", i%2==0)
+	}).data.(map[string][]{1})
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplace{4}(t *testing.T) {
+
+	v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
+
+	rawArr := v.Must{4}Slice()
+
+	replaced := v.Replace{4}(func(index int, val {1}) {1} {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.Must{4}Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollect{4}(t *testing.T) {
+
+	v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
+
+	collected := v.Collect{4}(func(index int, val {1}) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
diff --git a/go/src/github.com/stretchr/objx/codegen/types_list.txt b/go/src/github.com/stretchr/objx/codegen/types_list.txt
new file mode 100644
index 0000000..069d43d
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/codegen/types_list.txt
@@ -0,0 +1,20 @@
+Interface,interface{},"something",nil,Inter
+Map,map[string]interface{},map[string]interface{}{"name":"Tyler"},nil,MSI
+ObjxMap,(Map),New(1),New(nil),ObjxMap
+Bool,bool,true,false,Bool
+String,string,"hello","",Str
+Int,int,1,0,Int
+Int8,int8,1,0,Int8
+Int16,int16,1,0,Int16
+Int32,int32,1,0,Int32
+Int64,int64,1,0,Int64
+Uint,uint,1,0,Uint
+Uint8,uint8,1,0,Uint8
+Uint16,uint16,1,0,Uint16
+Uint32,uint32,1,0,Uint32
+Uint64,uint64,1,0,Uint64
+Uintptr,uintptr,1,0,Uintptr
+Float32,float32,1,0,Float32
+Float64,float64,1,0,Float64
+Complex64,complex64,1,0,Complex64
+Complex128,complex128,1,0,Complex128
diff --git a/go/src/github.com/stretchr/objx/constants.go b/go/src/github.com/stretchr/objx/constants.go
new file mode 100644
index 0000000..f9eb42a
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/constants.go
@@ -0,0 +1,13 @@
+package objx
+
+const (
+	// PathSeparator is the character used to separate the elements
+	// of the keypath.
+	//
+	// For example, `location.address.city`
+	PathSeparator string = "."
+
+	// SignatureSeparator is the character that is used to
+	// separate the Base64 string from the security signature.
+	SignatureSeparator = "_"
+)
diff --git a/go/src/github.com/stretchr/objx/conversions.go b/go/src/github.com/stretchr/objx/conversions.go
new file mode 100644
index 0000000..9cdfa9f
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/conversions.go
@@ -0,0 +1,117 @@
+package objx
+
+import (
+	"bytes"
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"net/url"
+)
+
+// JSON converts the contained object to a JSON string
+// representation
+func (m Map) JSON() (string, error) {
+
+	result, err := json.Marshal(m)
+
+	if err != nil {
+		err = errors.New("objx: JSON encode failed with: " + err.Error())
+	}
+
+	return string(result), err
+
+}
+
+// MustJSON converts the contained object to a JSON string
+// representation and panics if there is an error
+func (m Map) MustJSON() string {
+	result, err := m.JSON()
+	if err != nil {
+		panic(err.Error())
+	}
+	return result
+}
+
+// Base64 converts the contained object to a Base64 string
+// representation of the JSON string representation
+func (m Map) Base64() (string, error) {
+
+	var buf bytes.Buffer
+
+	jsonData, err := m.JSON()
+	if err != nil {
+		return "", err
+	}
+
+	encoder := base64.NewEncoder(base64.StdEncoding, &buf)
+	encoder.Write([]byte(jsonData))
+	encoder.Close()
+
+	return buf.String(), nil
+
+}
+
+// MustBase64 converts the contained object to a Base64 string
+// representation of the JSON string representation and panics
+// if there is an error
+func (m Map) MustBase64() string {
+	result, err := m.Base64()
+	if err != nil {
+		panic(err.Error())
+	}
+	return result
+}
+
+// SignedBase64 converts the contained object to a Base64 string
+// representation of the JSON string representation and signs it
+// using the provided key.
+func (m Map) SignedBase64(key string) (string, error) {
+
+	base64, err := m.Base64()
+	if err != nil {
+		return "", err
+	}
+
+	sig := HashWithKey(base64, key)
+
+	return base64 + SignatureSeparator + sig, nil
+
+}
+
+// MustSignedBase64 converts the contained object to a Base64 string
+// representation of the JSON string representation and signs it
+// using the provided key and panics if there is an error
+func (m Map) MustSignedBase64(key string) string {
+	result, err := m.SignedBase64(key)
+	if err != nil {
+		panic(err.Error())
+	}
+	return result
+}
+
+/*
+	URL Query
+	------------------------------------------------
+*/
+
+// URLValues creates a url.Values object from an Obj. This
+// function requires that the wrapped object be a map[string]interface{}
+func (m Map) URLValues() url.Values {
+
+	vals := make(url.Values)
+
+	for k, v := range m {
+		//TODO: can this be done without sprintf?
+		vals.Set(k, fmt.Sprintf("%v", v))
+	}
+
+	return vals
+}
+
+// URLQuery gets an encoded URL query representing the given
+// Obj. This function requires that the wrapped object be a
+// map[string]interface{}
+func (m Map) URLQuery() (string, error) {
+	return m.URLValues().Encode(), nil
+}
diff --git a/go/src/github.com/stretchr/objx/conversions_test.go b/go/src/github.com/stretchr/objx/conversions_test.go
new file mode 100644
index 0000000..e9ccd29
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/conversions_test.go
@@ -0,0 +1,94 @@
+package objx
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestConversionJSON(t *testing.T) {
+
+	jsonString := `{"name":"Mat"}`
+	o := MustFromJSON(jsonString)
+
+	result, err := o.JSON()
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, jsonString, result)
+	}
+
+	assert.Equal(t, jsonString, o.MustJSON())
+
+}
+
+func TestConversionJSONWithError(t *testing.T) {
+
+	o := MSI()
+	o["test"] = func() {}
+
+	assert.Panics(t, func() {
+		o.MustJSON()
+	})
+
+	_, err := o.JSON()
+
+	assert.Error(t, err)
+
+}
+
+func TestConversionBase64(t *testing.T) {
+
+	o := New(map[string]interface{}{"name": "Mat"})
+
+	result, err := o.Base64()
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, "eyJuYW1lIjoiTWF0In0=", result)
+	}
+
+	assert.Equal(t, "eyJuYW1lIjoiTWF0In0=", o.MustBase64())
+
+}
+
+func TestConversionBase64WithError(t *testing.T) {
+
+	o := MSI()
+	o["test"] = func() {}
+
+	assert.Panics(t, func() {
+		o.MustBase64()
+	})
+
+	_, err := o.Base64()
+
+	assert.Error(t, err)
+
+}
+
+func TestConversionSignedBase64(t *testing.T) {
+
+	o := New(map[string]interface{}{"name": "Mat"})
+
+	result, err := o.SignedBase64("key")
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, "eyJuYW1lIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6", result)
+	}
+
+	assert.Equal(t, "eyJuYW1lIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6", o.MustSignedBase64("key"))
+
+}
+
+func TestConversionSignedBase64WithError(t *testing.T) {
+
+	o := MSI()
+	o["test"] = func() {}
+
+	assert.Panics(t, func() {
+		o.MustSignedBase64("key")
+	})
+
+	_, err := o.SignedBase64("key")
+
+	assert.Error(t, err)
+
+}
diff --git a/go/src/github.com/stretchr/objx/doc.go b/go/src/github.com/stretchr/objx/doc.go
new file mode 100644
index 0000000..47bf85e
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/doc.go
@@ -0,0 +1,72 @@
+// objx - Go package for dealing with maps, slices, JSON and other data.
+//
+// Overview
+//
+// Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes
+// a powerful `Get` method (among others) that allows you to easily and quickly get
+// access to data within the map, without having to worry too much about type assertions,
+// missing data, default values etc.
+//
+// Pattern
+//
+// Objx uses a preditable pattern to make access data from within `map[string]interface{}'s
+// easy.
+//
+// Call one of the `objx.` functions to create your `objx.Map` to get going:
+//
+//     m, err := objx.FromJSON(json)
+//
+// NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong,
+// the rest will be optimistic and try to figure things out without panicking.
+//
+// Use `Get` to access the value you're interested in.  You can use dot and array
+// notation too:
+//
+//     m.Get("places[0].latlng")
+//
+// Once you have saught the `Value` you're interested in, you can use the `Is*` methods
+// to determine its type.
+//
+//     if m.Get("code").IsStr() { /* ... */ }
+//
+// Or you can just assume the type, and use one of the strong type methods to
+// extract the real value:
+//
+//     m.Get("code").Int()
+//
+// If there's no value there (or if it's the wrong type) then a default value
+// will be returned, or you can be explicit about the default value.
+//
+//     Get("code").Int(-1)
+//
+// If you're dealing with a slice of data as a value, Objx provides many useful
+// methods for iterating, manipulating and selecting that data.  You can find out more
+// by exploring the index below.
+//
+// Reading data
+//
+// A simple example of how to use Objx:
+//
+//     // use MustFromJSON to make an objx.Map from some JSON
+//     m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`)
+//
+//     // get the details
+//     name := m.Get("name").Str()
+//     age := m.Get("age").Int()
+//
+//     // get their nickname (or use their name if they
+//     // don't have one)
+//     nickname := m.Get("nickname").Str(name)
+//
+// Ranging
+//
+// Since `objx.Map` is a `map[string]interface{}` you can treat it as such.  For
+// example, to `range` the data, do what you would expect:
+//
+//     m := objx.MustFromJSON(json)
+//     for key, value := range m {
+//
+//       /* ... do your magic ... */
+//
+//     }
+package objx
diff --git a/go/src/github.com/stretchr/objx/fixture_test.go b/go/src/github.com/stretchr/objx/fixture_test.go
new file mode 100644
index 0000000..27f7d90
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/fixture_test.go
@@ -0,0 +1,98 @@
+package objx
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+var fixtures = []struct {
+	// name is the name of the fixture (used for reporting
+	// failures)
+	name string
+	// data is the JSON data to be worked on
+	data string
+	// get is the argument(s) to pass to Get
+	get interface{}
+	// output is the expected output
+	output interface{}
+}{
+	{
+		name:   "Simple get",
+		data:   `{"name": "Mat"}`,
+		get:    "name",
+		output: "Mat",
+	},
+	{
+		name:   "Get with dot notation",
+		data:   `{"address": {"city": "Boulder"}}`,
+		get:    "address.city",
+		output: "Boulder",
+	},
+	{
+		name:   "Deep get with dot notation",
+		data:   `{"one": {"two": {"three": {"four": "hello"}}}}`,
+		get:    "one.two.three.four",
+		output: "hello",
+	},
+	{
+		name:   "Get missing with dot notation",
+		data:   `{"one": {"two": {"three": {"four": "hello"}}}}`,
+		get:    "one.ten",
+		output: nil,
+	},
+	{
+		name:   "Get with array notation",
+		data:   `{"tags": ["one", "two", "three"]}`,
+		get:    "tags[1]",
+		output: "two",
+	},
+	{
+		name:   "Get with array and dot notation",
+		data:   `{"types": { "tags": ["one", "two", "three"]}}`,
+		get:    "types.tags[1]",
+		output: "two",
+	},
+	{
+		name:   "Get with array and dot notation - field after array",
+		data:   `{"tags": [{"name":"one"}, {"name":"two"}, {"name":"three"}]}`,
+		get:    "tags[1].name",
+		output: "two",
+	},
+	{
+		name:   "Complex get with array and dot notation",
+		data:   `{"tags": [{"list": [{"one":"pizza"}]}]}`,
+		get:    "tags[0].list[0].one",
+		output: "pizza",
+	},
+	{
+		name:   "Get field from within string should be nil",
+		data:   `{"name":"Tyler"}`,
+		get:    "name.something",
+		output: nil,
+	},
+	{
+		name:   "Get field from within string (using array accessor) should be nil",
+		data:   `{"numbers":["one", "two", "three"]}`,
+		get:    "numbers[0].nope",
+		output: nil,
+	},
+}
+
+func TestFixtures(t *testing.T) {
+
+	for _, fixture := range fixtures {
+
+		m := MustFromJSON(fixture.data)
+
+		// get the value
+		t.Logf("Running get fixture: \"%s\" (%v)", fixture.name, fixture)
+		value := m.Get(fixture.get.(string))
+
+		// make sure it matches
+		assert.Equal(t, fixture.output, value.data,
+			"Get fixture \"%s\" failed: %v", fixture.name, fixture,
+		)
+
+	}
+
+}
diff --git a/go/src/github.com/stretchr/objx/map.go b/go/src/github.com/stretchr/objx/map.go
new file mode 100644
index 0000000..eb6ed8e
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/map.go
@@ -0,0 +1,222 @@
+package objx
+
+import (
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"io/ioutil"
+	"net/url"
+	"strings"
+)
+
+// MSIConvertable is an interface that defines methods for converting your
+// custom types to a map[string]interface{} representation.
+type MSIConvertable interface {
+	// MSI gets a map[string]interface{} (msi) representing the
+	// object.
+	MSI() map[string]interface{}
+}
+
+// Map provides extended functionality for working with
+// untyped data, in particular map[string]interface (msi).
+type Map map[string]interface{}
+
+// Value returns the internal value instance
+func (m Map) Value() *Value {
+	return &Value{data: m}
+}
+
+// Nil represents a nil Map.
+var Nil Map = New(nil)
+
+// New creates a new Map containing the map[string]interface{} in the data argument.
+// If the data argument is not a map[string]interface, New attempts to call the
+// MSI() method on the MSIConvertable interface to create one.
+func New(data interface{}) Map {
+	if _, ok := data.(map[string]interface{}); !ok {
+		if converter, ok := data.(MSIConvertable); ok {
+			data = converter.MSI()
+		} else {
+			return nil
+		}
+	}
+	return Map(data.(map[string]interface{}))
+}
+
+// MSI creates a map[string]interface{} and puts it inside a new Map.
+//
+// The arguments follow a key, value pattern.
+//
+// Panics
+//
+// Panics if any key arugment is non-string or if there are an odd number of arguments.
+//
+// Example
+//
+// To easily create Maps:
+//
+//     m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true))
+//
+//     // creates an Map equivalent to
+//     m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}})
+func MSI(keyAndValuePairs ...interface{}) Map {
+
+	newMap := make(map[string]interface{})
+	keyAndValuePairsLen := len(keyAndValuePairs)
+
+	if keyAndValuePairsLen%2 != 0 {
+		panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.")
+	}
+
+	for i := 0; i < keyAndValuePairsLen; i = i + 2 {
+
+		key := keyAndValuePairs[i]
+		value := keyAndValuePairs[i+1]
+
+		// make sure the key is a string
+		keyString, keyStringOK := key.(string)
+		if !keyStringOK {
+			panic("objx: MSI must follow 'string, interface{}' pattern.  " + keyString + " is not a valid key.")
+		}
+
+		newMap[keyString] = value
+
+	}
+
+	return New(newMap)
+}
+
+// ****** Conversion Constructors
+
+// MustFromJSON creates a new Map containing the data specified in the
+// jsonString.
+//
+// Panics if the JSON is invalid.
+func MustFromJSON(jsonString string) Map {
+	o, err := FromJSON(jsonString)
+
+	if err != nil {
+		panic("objx: MustFromJSON failed with error: " + err.Error())
+	}
+
+	return o
+}
+
+// FromJSON creates a new Map containing the data specified in the
+// jsonString.
+//
+// Returns an error if the JSON is invalid.
+func FromJSON(jsonString string) (Map, error) {
+
+	var data interface{}
+	err := json.Unmarshal([]byte(jsonString), &data)
+
+	if err != nil {
+		return Nil, err
+	}
+
+	return New(data), nil
+
+}
+
+// FromBase64 creates a new Obj containing the data specified
+// in the Base64 string.
+//
+// The string is an encoded JSON string returned by Base64
+func FromBase64(base64String string) (Map, error) {
+
+	decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String))
+
+	decoded, err := ioutil.ReadAll(decoder)
+	if err != nil {
+		return nil, err
+	}
+
+	return FromJSON(string(decoded))
+}
+
+// MustFromBase64 creates a new Obj containing the data specified
+// in the Base64 string and panics if there is an error.
+//
+// The string is an encoded JSON string returned by Base64
+func MustFromBase64(base64String string) Map {
+
+	result, err := FromBase64(base64String)
+
+	if err != nil {
+		panic("objx: MustFromBase64 failed with error: " + err.Error())
+	}
+
+	return result
+}
+
+// FromSignedBase64 creates a new Obj containing the data specified
+// in the Base64 string.
+//
+// The string is an encoded JSON string returned by SignedBase64
+func FromSignedBase64(base64String, key string) (Map, error) {
+	parts := strings.Split(base64String, SignatureSeparator)
+	if len(parts) != 2 {
+		return nil, errors.New("objx: Signed base64 string is malformed.")
+	}
+
+	sig := HashWithKey(parts[0], key)
+	if parts[1] != sig {
+		return nil, errors.New("objx: Signature for base64 data does not match.")
+	}
+
+	return FromBase64(parts[0])
+}
+
+// MustFromSignedBase64 creates a new Obj containing the data specified
+// in the Base64 string and panics if there is an error.
+//
+// The string is an encoded JSON string returned by Base64
+func MustFromSignedBase64(base64String, key string) Map {
+
+	result, err := FromSignedBase64(base64String, key)
+
+	if err != nil {
+		panic("objx: MustFromSignedBase64 failed with error: " + err.Error())
+	}
+
+	return result
+}
+
+// FromURLQuery generates a new Obj by parsing the specified
+// query.
+//
+// For queries with multiple values, the first value is selected.
+func FromURLQuery(query string) (Map, error) {
+
+	vals, err := url.ParseQuery(query)
+
+	if err != nil {
+		return nil, err
+	}
+
+	m := make(map[string]interface{})
+	for k, vals := range vals {
+		m[k] = vals[0]
+	}
+
+	return New(m), nil
+}
+
+// MustFromURLQuery generates a new Obj by parsing the specified
+// query.
+//
+// For queries with multiple values, the first value is selected.
+//
+// Panics if it encounters an error
+func MustFromURLQuery(query string) Map {
+
+	o, err := FromURLQuery(query)
+
+	if err != nil {
+		panic("objx: MustFromURLQuery failed with error: " + err.Error())
+	}
+
+	return o
+
+}
diff --git a/go/src/github.com/stretchr/objx/map_for_test.go b/go/src/github.com/stretchr/objx/map_for_test.go
new file mode 100644
index 0000000..6beb506
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/map_for_test.go
@@ -0,0 +1,10 @@
+package objx
+
+var TestMap map[string]interface{} = map[string]interface{}{
+	"name": "Tyler",
+	"address": map[string]interface{}{
+		"city":  "Salt Lake City",
+		"state": "UT",
+	},
+	"numbers": []interface{}{"one", "two", "three", "four", "five"},
+}
diff --git a/go/src/github.com/stretchr/objx/map_test.go b/go/src/github.com/stretchr/objx/map_test.go
new file mode 100644
index 0000000..1f8b45c
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/map_test.go
@@ -0,0 +1,147 @@
+package objx
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+type Convertable struct {
+	name string
+}
+
+func (c *Convertable) MSI() map[string]interface{} {
+	return map[string]interface{}{"name": c.name}
+}
+
+type Unconvertable struct {
+	name string
+}
+
+func TestMapCreation(t *testing.T) {
+
+	o := New(nil)
+	assert.Nil(t, o)
+
+	o = New("Tyler")
+	assert.Nil(t, o)
+
+	unconvertable := &Unconvertable{name: "Tyler"}
+	o = New(unconvertable)
+	assert.Nil(t, o)
+
+	convertable := &Convertable{name: "Tyler"}
+	o = New(convertable)
+	if assert.NotNil(t, convertable) {
+		assert.Equal(t, "Tyler", o["name"], "Tyler")
+	}
+
+	o = MSI()
+	if assert.NotNil(t, o) {
+		assert.NotNil(t, o)
+	}
+
+	o = MSI("name", "Tyler")
+	if assert.NotNil(t, o) {
+		if assert.NotNil(t, o) {
+			assert.Equal(t, o["name"], "Tyler")
+		}
+	}
+
+}
+
+func TestMapMustFromJSONWithError(t *testing.T) {
+
+	_, err := FromJSON(`"name":"Mat"}`)
+	assert.Error(t, err)
+
+}
+
+func TestMapFromJSON(t *testing.T) {
+
+	o := MustFromJSON(`{"name":"Mat"}`)
+
+	if assert.NotNil(t, o) {
+		if assert.NotNil(t, o) {
+			assert.Equal(t, "Mat", o["name"])
+		}
+	}
+
+}
+
+func TestMapFromJSONWithError(t *testing.T) {
+
+	var m Map
+
+	assert.Panics(t, func() {
+		m = MustFromJSON(`"name":"Mat"}`)
+	})
+
+	assert.Nil(t, m)
+
+}
+
+func TestMapFromBase64String(t *testing.T) {
+
+	base64String := "eyJuYW1lIjoiTWF0In0="
+
+	o, err := FromBase64(base64String)
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, o.Get("name").Str(), "Mat")
+	}
+
+	assert.Equal(t, MustFromBase64(base64String).Get("name").Str(), "Mat")
+
+}
+
+func TestMapFromBase64StringWithError(t *testing.T) {
+
+	base64String := "eyJuYW1lIjoiTWFasd0In0="
+
+	_, err := FromBase64(base64String)
+
+	assert.Error(t, err)
+
+	assert.Panics(t, func() {
+		MustFromBase64(base64String)
+	})
+
+}
+
+func TestMapFromSignedBase64String(t *testing.T) {
+
+	base64String := "eyJuYW1lIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6"
+
+	o, err := FromSignedBase64(base64String, "key")
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, o.Get("name").Str(), "Mat")
+	}
+
+	assert.Equal(t, MustFromSignedBase64(base64String, "key").Get("name").Str(), "Mat")
+
+}
+
+func TestMapFromSignedBase64StringWithError(t *testing.T) {
+
+	base64String := "eyJuYW1lasdIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6"
+
+	_, err := FromSignedBase64(base64String, "key")
+
+	assert.Error(t, err)
+
+	assert.Panics(t, func() {
+		MustFromSignedBase64(base64String, "key")
+	})
+
+}
+
+func TestMapFromURLQuery(t *testing.T) {
+
+	m, err := FromURLQuery("name=tyler&state=UT")
+	if assert.NoError(t, err) && assert.NotNil(t, m) {
+		assert.Equal(t, "tyler", m.Get("name").Str())
+		assert.Equal(t, "UT", m.Get("state").Str())
+	}
+
+}
diff --git a/go/src/github.com/stretchr/objx/mutations.go b/go/src/github.com/stretchr/objx/mutations.go
new file mode 100644
index 0000000..b35c863
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/mutations.go
@@ -0,0 +1,81 @@
+package objx
+
+// Exclude returns a new Map with the keys in the specified []string
+// excluded.
+func (d Map) Exclude(exclude []string) Map {
+
+	excluded := make(Map)
+	for k, v := range d {
+		var shouldInclude bool = true
+		for _, toExclude := range exclude {
+			if k == toExclude {
+				shouldInclude = false
+				break
+			}
+		}
+		if shouldInclude {
+			excluded[k] = v
+		}
+	}
+
+	return excluded
+}
+
+// Copy creates a shallow copy of the Obj.
+func (m Map) Copy() Map {
+	copied := make(map[string]interface{})
+	for k, v := range m {
+		copied[k] = v
+	}
+	return New(copied)
+}
+
+// Merge blends the specified map with a copy of this map and returns the result.
+//
+// Keys that appear in both will be selected from the specified map.
+// This method requires that the wrapped object be a map[string]interface{}
+func (m Map) Merge(merge Map) Map {
+	return m.Copy().MergeHere(merge)
+}
+
+// Merge blends the specified map with this map and returns the current map.
+//
+// Keys that appear in both will be selected from the specified map.  The original map
+// will be modified. This method requires that
+// the wrapped object be a map[string]interface{}
+func (m Map) MergeHere(merge Map) Map {
+
+	for k, v := range merge {
+		m[k] = v
+	}
+
+	return m
+
+}
+
+// Transform builds a new Obj giving the transformer a chance
+// to change the keys and values as it goes. This method requires that
+// the wrapped object be a map[string]interface{}
+func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map {
+	newMap := make(map[string]interface{})
+	for k, v := range m {
+		modifiedKey, modifiedVal := transformer(k, v)
+		newMap[modifiedKey] = modifiedVal
+	}
+	return New(newMap)
+}
+
+// TransformKeys builds a new map using the specified key mapping.
+//
+// Unspecified keys will be unaltered.
+// This method requires that the wrapped object be a map[string]interface{}
+func (m Map) TransformKeys(mapping map[string]string) Map {
+	return m.Transform(func(key string, value interface{}) (string, interface{}) {
+
+		if newKey, ok := mapping[key]; ok {
+			return newKey, value
+		}
+
+		return key, value
+	})
+}
diff --git a/go/src/github.com/stretchr/objx/mutations_test.go b/go/src/github.com/stretchr/objx/mutations_test.go
new file mode 100644
index 0000000..e20ee23
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/mutations_test.go
@@ -0,0 +1,77 @@
+package objx
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestExclude(t *testing.T) {
+
+	d := make(Map)
+	d["name"] = "Mat"
+	d["age"] = 29
+	d["secret"] = "ABC"
+
+	excluded := d.Exclude([]string{"secret"})
+
+	assert.Equal(t, d["name"], excluded["name"])
+	assert.Equal(t, d["age"], excluded["age"])
+	assert.False(t, excluded.Has("secret"), "secret should be excluded")
+
+}
+
+func TestCopy(t *testing.T) {
+
+	d1 := make(map[string]interface{})
+	d1["name"] = "Tyler"
+	d1["location"] = "UT"
+
+	d1Obj := New(d1)
+	d2Obj := d1Obj.Copy()
+
+	d2Obj["name"] = "Mat"
+
+	assert.Equal(t, d1Obj.Get("name").Str(), "Tyler")
+	assert.Equal(t, d2Obj.Get("name").Str(), "Mat")
+
+}
+
+func TestMerge(t *testing.T) {
+
+	d := make(map[string]interface{})
+	d["name"] = "Mat"
+
+	d1 := make(map[string]interface{})
+	d1["name"] = "Tyler"
+	d1["location"] = "UT"
+
+	dObj := New(d)
+	d1Obj := New(d1)
+
+	merged := dObj.Merge(d1Obj)
+
+	assert.Equal(t, merged.Get("name").Str(), d1Obj.Get("name").Str())
+	assert.Equal(t, merged.Get("location").Str(), d1Obj.Get("location").Str())
+	assert.Empty(t, dObj.Get("location").Str())
+
+}
+
+func TestMergeHere(t *testing.T) {
+
+	d := make(map[string]interface{})
+	d["name"] = "Mat"
+
+	d1 := make(map[string]interface{})
+	d1["name"] = "Tyler"
+	d1["location"] = "UT"
+
+	dObj := New(d)
+	d1Obj := New(d1)
+
+	merged := dObj.MergeHere(d1Obj)
+
+	assert.Equal(t, dObj, merged, "With MergeHere, it should return the first modified map")
+	assert.Equal(t, merged.Get("name").Str(), d1Obj.Get("name").Str())
+	assert.Equal(t, merged.Get("location").Str(), d1Obj.Get("location").Str())
+	assert.Equal(t, merged.Get("location").Str(), dObj.Get("location").Str())
+}
diff --git a/go/src/github.com/stretchr/objx/security.go b/go/src/github.com/stretchr/objx/security.go
new file mode 100644
index 0000000..fdd6be9
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/security.go
@@ -0,0 +1,14 @@
+package objx
+
+import (
+	"crypto/sha1"
+	"encoding/hex"
+)
+
+// HashWithKey hashes the specified string using the security
+// key.
+func HashWithKey(data, key string) string {
+	hash := sha1.New()
+	hash.Write([]byte(data + ":" + key))
+	return hex.EncodeToString(hash.Sum(nil))
+}
diff --git a/go/src/github.com/stretchr/objx/security_test.go b/go/src/github.com/stretchr/objx/security_test.go
new file mode 100644
index 0000000..8f0898f
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/security_test.go
@@ -0,0 +1,12 @@
+package objx
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestHashWithKey(t *testing.T) {
+
+	assert.Equal(t, "0ce84d8d01f2c7b6e0882b784429c54d280ea2d9", HashWithKey("abc", "def"))
+
+}
diff --git a/go/src/github.com/stretchr/objx/simple_example_test.go b/go/src/github.com/stretchr/objx/simple_example_test.go
new file mode 100644
index 0000000..5408c7f
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/simple_example_test.go
@@ -0,0 +1,41 @@
+package objx
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestSimpleExample(t *testing.T) {
+
+	// build a map from a JSON object
+	o := MustFromJSON(`{"name":"Mat","foods":["indian","chinese"], "location":{"county":"hobbiton","city":"the shire"}}`)
+
+	// Map can be used as a straight map[string]interface{}
+	assert.Equal(t, o["name"], "Mat")
+
+	// Get an Value object
+	v := o.Get("name")
+	assert.Equal(t, v, &Value{data: "Mat"})
+
+	// Test the contained value
+	assert.False(t, v.IsInt())
+	assert.False(t, v.IsBool())
+	assert.True(t, v.IsStr())
+
+	// Get the contained value
+	assert.Equal(t, v.Str(), "Mat")
+
+	// Get a default value if the contained value is not of the expected type or does not exist
+	assert.Equal(t, 1, v.Int(1))
+
+	// Get a value by using array notation
+	assert.Equal(t, "indian", o.Get("foods[0]").Data())
+
+	// Set a value by using array notation
+	o.Set("foods[0]", "italian")
+	assert.Equal(t, "italian", o.Get("foods[0]").Str())
+
+	// Get a value by using dot notation
+	assert.Equal(t, "hobbiton", o.Get("location.county").Str())
+
+}
diff --git a/go/src/github.com/stretchr/objx/tests.go b/go/src/github.com/stretchr/objx/tests.go
new file mode 100644
index 0000000..d9e0b47
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/tests.go
@@ -0,0 +1,17 @@
+package objx
+
+// Has gets whether there is something at the specified selector
+// or not.
+//
+// If m is nil, Has will always return false.
+func (m Map) Has(selector string) bool {
+	if m == nil {
+		return false
+	}
+	return !m.Get(selector).IsNil()
+}
+
+// IsNil gets whether the data is nil or not.
+func (v *Value) IsNil() bool {
+	return v == nil || v.data == nil
+}
diff --git a/go/src/github.com/stretchr/objx/tests_test.go b/go/src/github.com/stretchr/objx/tests_test.go
new file mode 100644
index 0000000..bcc1eb0
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/tests_test.go
@@ -0,0 +1,24 @@
+package objx
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestHas(t *testing.T) {
+
+	m := New(TestMap)
+
+	assert.True(t, m.Has("name"))
+	assert.True(t, m.Has("address.state"))
+	assert.True(t, m.Has("numbers[4]"))
+
+	assert.False(t, m.Has("address.state.nope"))
+	assert.False(t, m.Has("address.nope"))
+	assert.False(t, m.Has("nope"))
+	assert.False(t, m.Has("numbers[5]"))
+
+	m = nil
+	assert.False(t, m.Has("nothing"))
+
+}
diff --git a/go/src/github.com/stretchr/objx/type_specific_codegen.go b/go/src/github.com/stretchr/objx/type_specific_codegen.go
new file mode 100644
index 0000000..f3ecb29
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/type_specific_codegen.go
@@ -0,0 +1,2881 @@
+package objx
+
+/*
+	Inter (interface{} and []interface{})
+	--------------------------------------------------
+*/
+
+// Inter gets the value as a interface{}, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Inter(optionalDefault ...interface{}) interface{} {
+	if s, ok := v.data.(interface{}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInter gets the value as a interface{}.
+//
+// Panics if the object is not a interface{}.
+func (v *Value) MustInter() interface{} {
+	return v.data.(interface{})
+}
+
+// InterSlice gets the value as a []interface{}, returns the optionalDefault
+// value or nil if the value is not a []interface{}.
+func (v *Value) InterSlice(optionalDefault ...[]interface{}) []interface{} {
+	if s, ok := v.data.([]interface{}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInterSlice gets the value as a []interface{}.
+//
+// Panics if the object is not a []interface{}.
+func (v *Value) MustInterSlice() []interface{} {
+	return v.data.([]interface{})
+}
+
+// IsInter gets whether the object contained is a interface{} or not.
+func (v *Value) IsInter() bool {
+	_, ok := v.data.(interface{})
+	return ok
+}
+
+// IsInterSlice gets whether the object contained is a []interface{} or not.
+func (v *Value) IsInterSlice() bool {
+	_, ok := v.data.([]interface{})
+	return ok
+}
+
+// EachInter calls the specified callback for each object
+// in the []interface{}.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInter(callback func(int, interface{}) bool) *Value {
+
+	for index, val := range v.MustInterSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInter uses the specified decider function to select items
+// from the []interface{}.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInter(decider func(int, interface{}) bool) *Value {
+
+	var selected []interface{}
+
+	v.EachInter(func(index int, val interface{}) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInter uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]interface{}.
+func (v *Value) GroupInter(grouper func(int, interface{}) string) *Value {
+
+	groups := make(map[string][]interface{})
+
+	v.EachInter(func(index int, val interface{}) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]interface{}, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInter uses the specified function to replace each interface{}s
+// by iterating each item.  The data in the returned result will be a
+// []interface{} containing the replaced items.
+func (v *Value) ReplaceInter(replacer func(int, interface{}) interface{}) *Value {
+
+	arr := v.MustInterSlice()
+	replaced := make([]interface{}, len(arr))
+
+	v.EachInter(func(index int, val interface{}) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInter uses the specified collector function to collect a value
+// for each of the interface{}s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInter(collector func(int, interface{}) interface{}) *Value {
+
+	arr := v.MustInterSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInter(func(index int, val interface{}) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	MSI (map[string]interface{} and []map[string]interface{})
+	--------------------------------------------------
+*/
+
+// MSI gets the value as a map[string]interface{}, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) MSI(optionalDefault ...map[string]interface{}) map[string]interface{} {
+	if s, ok := v.data.(map[string]interface{}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustMSI gets the value as a map[string]interface{}.
+//
+// Panics if the object is not a map[string]interface{}.
+func (v *Value) MustMSI() map[string]interface{} {
+	return v.data.(map[string]interface{})
+}
+
+// MSISlice gets the value as a []map[string]interface{}, returns the optionalDefault
+// value or nil if the value is not a []map[string]interface{}.
+func (v *Value) MSISlice(optionalDefault ...[]map[string]interface{}) []map[string]interface{} {
+	if s, ok := v.data.([]map[string]interface{}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustMSISlice gets the value as a []map[string]interface{}.
+//
+// Panics if the object is not a []map[string]interface{}.
+func (v *Value) MustMSISlice() []map[string]interface{} {
+	return v.data.([]map[string]interface{})
+}
+
+// IsMSI gets whether the object contained is a map[string]interface{} or not.
+func (v *Value) IsMSI() bool {
+	_, ok := v.data.(map[string]interface{})
+	return ok
+}
+
+// IsMSISlice gets whether the object contained is a []map[string]interface{} or not.
+func (v *Value) IsMSISlice() bool {
+	_, ok := v.data.([]map[string]interface{})
+	return ok
+}
+
+// EachMSI calls the specified callback for each object
+// in the []map[string]interface{}.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachMSI(callback func(int, map[string]interface{}) bool) *Value {
+
+	for index, val := range v.MustMSISlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereMSI uses the specified decider function to select items
+// from the []map[string]interface{}.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereMSI(decider func(int, map[string]interface{}) bool) *Value {
+
+	var selected []map[string]interface{}
+
+	v.EachMSI(func(index int, val map[string]interface{}) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupMSI uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]map[string]interface{}.
+func (v *Value) GroupMSI(grouper func(int, map[string]interface{}) string) *Value {
+
+	groups := make(map[string][]map[string]interface{})
+
+	v.EachMSI(func(index int, val map[string]interface{}) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]map[string]interface{}, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceMSI uses the specified function to replace each map[string]interface{}s
+// by iterating each item.  The data in the returned result will be a
+// []map[string]interface{} containing the replaced items.
+func (v *Value) ReplaceMSI(replacer func(int, map[string]interface{}) map[string]interface{}) *Value {
+
+	arr := v.MustMSISlice()
+	replaced := make([]map[string]interface{}, len(arr))
+
+	v.EachMSI(func(index int, val map[string]interface{}) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectMSI uses the specified collector function to collect a value
+// for each of the map[string]interface{}s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectMSI(collector func(int, map[string]interface{}) interface{}) *Value {
+
+	arr := v.MustMSISlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachMSI(func(index int, val map[string]interface{}) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	ObjxMap ((Map) and [](Map))
+	--------------------------------------------------
+*/
+
+// ObjxMap gets the value as a (Map), returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) ObjxMap(optionalDefault ...(Map)) Map {
+	if s, ok := v.data.((Map)); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return New(nil)
+}
+
+// MustObjxMap gets the value as a (Map).
+//
+// Panics if the object is not a (Map).
+func (v *Value) MustObjxMap() Map {
+	return v.data.((Map))
+}
+
+// ObjxMapSlice gets the value as a [](Map), returns the optionalDefault
+// value or nil if the value is not a [](Map).
+func (v *Value) ObjxMapSlice(optionalDefault ...[](Map)) [](Map) {
+	if s, ok := v.data.([](Map)); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustObjxMapSlice gets the value as a [](Map).
+//
+// Panics if the object is not a [](Map).
+func (v *Value) MustObjxMapSlice() [](Map) {
+	return v.data.([](Map))
+}
+
+// IsObjxMap gets whether the object contained is a (Map) or not.
+func (v *Value) IsObjxMap() bool {
+	_, ok := v.data.((Map))
+	return ok
+}
+
+// IsObjxMapSlice gets whether the object contained is a [](Map) or not.
+func (v *Value) IsObjxMapSlice() bool {
+	_, ok := v.data.([](Map))
+	return ok
+}
+
+// EachObjxMap calls the specified callback for each object
+// in the [](Map).
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachObjxMap(callback func(int, Map) bool) *Value {
+
+	for index, val := range v.MustObjxMapSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereObjxMap uses the specified decider function to select items
+// from the [](Map).  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereObjxMap(decider func(int, Map) bool) *Value {
+
+	var selected [](Map)
+
+	v.EachObjxMap(func(index int, val Map) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupObjxMap uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][](Map).
+func (v *Value) GroupObjxMap(grouper func(int, Map) string) *Value {
+
+	groups := make(map[string][](Map))
+
+	v.EachObjxMap(func(index int, val Map) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([](Map), 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceObjxMap uses the specified function to replace each (Map)s
+// by iterating each item.  The data in the returned result will be a
+// [](Map) containing the replaced items.
+func (v *Value) ReplaceObjxMap(replacer func(int, Map) Map) *Value {
+
+	arr := v.MustObjxMapSlice()
+	replaced := make([](Map), len(arr))
+
+	v.EachObjxMap(func(index int, val Map) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectObjxMap uses the specified collector function to collect a value
+// for each of the (Map)s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectObjxMap(collector func(int, Map) interface{}) *Value {
+
+	arr := v.MustObjxMapSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachObjxMap(func(index int, val Map) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Bool (bool and []bool)
+	--------------------------------------------------
+*/
+
+// Bool gets the value as a bool, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Bool(optionalDefault ...bool) bool {
+	if s, ok := v.data.(bool); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return false
+}
+
+// MustBool gets the value as a bool.
+//
+// Panics if the object is not a bool.
+func (v *Value) MustBool() bool {
+	return v.data.(bool)
+}
+
+// BoolSlice gets the value as a []bool, returns the optionalDefault
+// value or nil if the value is not a []bool.
+func (v *Value) BoolSlice(optionalDefault ...[]bool) []bool {
+	if s, ok := v.data.([]bool); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustBoolSlice gets the value as a []bool.
+//
+// Panics if the object is not a []bool.
+func (v *Value) MustBoolSlice() []bool {
+	return v.data.([]bool)
+}
+
+// IsBool gets whether the object contained is a bool or not.
+func (v *Value) IsBool() bool {
+	_, ok := v.data.(bool)
+	return ok
+}
+
+// IsBoolSlice gets whether the object contained is a []bool or not.
+func (v *Value) IsBoolSlice() bool {
+	_, ok := v.data.([]bool)
+	return ok
+}
+
+// EachBool calls the specified callback for each object
+// in the []bool.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachBool(callback func(int, bool) bool) *Value {
+
+	for index, val := range v.MustBoolSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereBool uses the specified decider function to select items
+// from the []bool.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereBool(decider func(int, bool) bool) *Value {
+
+	var selected []bool
+
+	v.EachBool(func(index int, val bool) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupBool uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]bool.
+func (v *Value) GroupBool(grouper func(int, bool) string) *Value {
+
+	groups := make(map[string][]bool)
+
+	v.EachBool(func(index int, val bool) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]bool, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceBool uses the specified function to replace each bools
+// by iterating each item.  The data in the returned result will be a
+// []bool containing the replaced items.
+func (v *Value) ReplaceBool(replacer func(int, bool) bool) *Value {
+
+	arr := v.MustBoolSlice()
+	replaced := make([]bool, len(arr))
+
+	v.EachBool(func(index int, val bool) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectBool uses the specified collector function to collect a value
+// for each of the bools in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectBool(collector func(int, bool) interface{}) *Value {
+
+	arr := v.MustBoolSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachBool(func(index int, val bool) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Str (string and []string)
+	--------------------------------------------------
+*/
+
+// Str gets the value as a string, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Str(optionalDefault ...string) string {
+	if s, ok := v.data.(string); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return ""
+}
+
+// MustStr gets the value as a string.
+//
+// Panics if the object is not a string.
+func (v *Value) MustStr() string {
+	return v.data.(string)
+}
+
+// StrSlice gets the value as a []string, returns the optionalDefault
+// value or nil if the value is not a []string.
+func (v *Value) StrSlice(optionalDefault ...[]string) []string {
+	if s, ok := v.data.([]string); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustStrSlice gets the value as a []string.
+//
+// Panics if the object is not a []string.
+func (v *Value) MustStrSlice() []string {
+	return v.data.([]string)
+}
+
+// IsStr gets whether the object contained is a string or not.
+func (v *Value) IsStr() bool {
+	_, ok := v.data.(string)
+	return ok
+}
+
+// IsStrSlice gets whether the object contained is a []string or not.
+func (v *Value) IsStrSlice() bool {
+	_, ok := v.data.([]string)
+	return ok
+}
+
+// EachStr calls the specified callback for each object
+// in the []string.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachStr(callback func(int, string) bool) *Value {
+
+	for index, val := range v.MustStrSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereStr uses the specified decider function to select items
+// from the []string.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereStr(decider func(int, string) bool) *Value {
+
+	var selected []string
+
+	v.EachStr(func(index int, val string) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupStr uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]string.
+func (v *Value) GroupStr(grouper func(int, string) string) *Value {
+
+	groups := make(map[string][]string)
+
+	v.EachStr(func(index int, val string) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]string, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceStr uses the specified function to replace each strings
+// by iterating each item.  The data in the returned result will be a
+// []string containing the replaced items.
+func (v *Value) ReplaceStr(replacer func(int, string) string) *Value {
+
+	arr := v.MustStrSlice()
+	replaced := make([]string, len(arr))
+
+	v.EachStr(func(index int, val string) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectStr uses the specified collector function to collect a value
+// for each of the strings in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectStr(collector func(int, string) interface{}) *Value {
+
+	arr := v.MustStrSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachStr(func(index int, val string) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Int (int and []int)
+	--------------------------------------------------
+*/
+
+// Int gets the value as a int, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Int(optionalDefault ...int) int {
+	if s, ok := v.data.(int); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustInt gets the value as a int.
+//
+// Panics if the object is not a int.
+func (v *Value) MustInt() int {
+	return v.data.(int)
+}
+
+// IntSlice gets the value as a []int, returns the optionalDefault
+// value or nil if the value is not a []int.
+func (v *Value) IntSlice(optionalDefault ...[]int) []int {
+	if s, ok := v.data.([]int); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustIntSlice gets the value as a []int.
+//
+// Panics if the object is not a []int.
+func (v *Value) MustIntSlice() []int {
+	return v.data.([]int)
+}
+
+// IsInt gets whether the object contained is a int or not.
+func (v *Value) IsInt() bool {
+	_, ok := v.data.(int)
+	return ok
+}
+
+// IsIntSlice gets whether the object contained is a []int or not.
+func (v *Value) IsIntSlice() bool {
+	_, ok := v.data.([]int)
+	return ok
+}
+
+// EachInt calls the specified callback for each object
+// in the []int.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInt(callback func(int, int) bool) *Value {
+
+	for index, val := range v.MustIntSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInt uses the specified decider function to select items
+// from the []int.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInt(decider func(int, int) bool) *Value {
+
+	var selected []int
+
+	v.EachInt(func(index int, val int) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInt uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]int.
+func (v *Value) GroupInt(grouper func(int, int) string) *Value {
+
+	groups := make(map[string][]int)
+
+	v.EachInt(func(index int, val int) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]int, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInt uses the specified function to replace each ints
+// by iterating each item.  The data in the returned result will be a
+// []int containing the replaced items.
+func (v *Value) ReplaceInt(replacer func(int, int) int) *Value {
+
+	arr := v.MustIntSlice()
+	replaced := make([]int, len(arr))
+
+	v.EachInt(func(index int, val int) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInt uses the specified collector function to collect a value
+// for each of the ints in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInt(collector func(int, int) interface{}) *Value {
+
+	arr := v.MustIntSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInt(func(index int, val int) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Int8 (int8 and []int8)
+	--------------------------------------------------
+*/
+
+// Int8 gets the value as a int8, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Int8(optionalDefault ...int8) int8 {
+	if s, ok := v.data.(int8); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustInt8 gets the value as a int8.
+//
+// Panics if the object is not a int8.
+func (v *Value) MustInt8() int8 {
+	return v.data.(int8)
+}
+
+// Int8Slice gets the value as a []int8, returns the optionalDefault
+// value or nil if the value is not a []int8.
+func (v *Value) Int8Slice(optionalDefault ...[]int8) []int8 {
+	if s, ok := v.data.([]int8); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInt8Slice gets the value as a []int8.
+//
+// Panics if the object is not a []int8.
+func (v *Value) MustInt8Slice() []int8 {
+	return v.data.([]int8)
+}
+
+// IsInt8 gets whether the object contained is a int8 or not.
+func (v *Value) IsInt8() bool {
+	_, ok := v.data.(int8)
+	return ok
+}
+
+// IsInt8Slice gets whether the object contained is a []int8 or not.
+func (v *Value) IsInt8Slice() bool {
+	_, ok := v.data.([]int8)
+	return ok
+}
+
+// EachInt8 calls the specified callback for each object
+// in the []int8.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInt8(callback func(int, int8) bool) *Value {
+
+	for index, val := range v.MustInt8Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInt8 uses the specified decider function to select items
+// from the []int8.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInt8(decider func(int, int8) bool) *Value {
+
+	var selected []int8
+
+	v.EachInt8(func(index int, val int8) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInt8 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]int8.
+func (v *Value) GroupInt8(grouper func(int, int8) string) *Value {
+
+	groups := make(map[string][]int8)
+
+	v.EachInt8(func(index int, val int8) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]int8, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInt8 uses the specified function to replace each int8s
+// by iterating each item.  The data in the returned result will be a
+// []int8 containing the replaced items.
+func (v *Value) ReplaceInt8(replacer func(int, int8) int8) *Value {
+
+	arr := v.MustInt8Slice()
+	replaced := make([]int8, len(arr))
+
+	v.EachInt8(func(index int, val int8) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInt8 uses the specified collector function to collect a value
+// for each of the int8s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInt8(collector func(int, int8) interface{}) *Value {
+
+	arr := v.MustInt8Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInt8(func(index int, val int8) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Int16 (int16 and []int16)
+	--------------------------------------------------
+*/
+
+// Int16 gets the value as a int16, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Int16(optionalDefault ...int16) int16 {
+	if s, ok := v.data.(int16); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustInt16 gets the value as a int16.
+//
+// Panics if the object is not a int16.
+func (v *Value) MustInt16() int16 {
+	return v.data.(int16)
+}
+
+// Int16Slice gets the value as a []int16, returns the optionalDefault
+// value or nil if the value is not a []int16.
+func (v *Value) Int16Slice(optionalDefault ...[]int16) []int16 {
+	if s, ok := v.data.([]int16); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInt16Slice gets the value as a []int16.
+//
+// Panics if the object is not a []int16.
+func (v *Value) MustInt16Slice() []int16 {
+	return v.data.([]int16)
+}
+
+// IsInt16 gets whether the object contained is a int16 or not.
+func (v *Value) IsInt16() bool {
+	_, ok := v.data.(int16)
+	return ok
+}
+
+// IsInt16Slice gets whether the object contained is a []int16 or not.
+func (v *Value) IsInt16Slice() bool {
+	_, ok := v.data.([]int16)
+	return ok
+}
+
+// EachInt16 calls the specified callback for each object
+// in the []int16.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInt16(callback func(int, int16) bool) *Value {
+
+	for index, val := range v.MustInt16Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInt16 uses the specified decider function to select items
+// from the []int16.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInt16(decider func(int, int16) bool) *Value {
+
+	var selected []int16
+
+	v.EachInt16(func(index int, val int16) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInt16 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]int16.
+func (v *Value) GroupInt16(grouper func(int, int16) string) *Value {
+
+	groups := make(map[string][]int16)
+
+	v.EachInt16(func(index int, val int16) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]int16, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInt16 uses the specified function to replace each int16s
+// by iterating each item.  The data in the returned result will be a
+// []int16 containing the replaced items.
+func (v *Value) ReplaceInt16(replacer func(int, int16) int16) *Value {
+
+	arr := v.MustInt16Slice()
+	replaced := make([]int16, len(arr))
+
+	v.EachInt16(func(index int, val int16) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInt16 uses the specified collector function to collect a value
+// for each of the int16s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInt16(collector func(int, int16) interface{}) *Value {
+
+	arr := v.MustInt16Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInt16(func(index int, val int16) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Int32 (int32 and []int32)
+	--------------------------------------------------
+*/
+
+// Int32 gets the value as a int32, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Int32(optionalDefault ...int32) int32 {
+	if s, ok := v.data.(int32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustInt32 gets the value as a int32.
+//
+// Panics if the object is not a int32.
+func (v *Value) MustInt32() int32 {
+	return v.data.(int32)
+}
+
+// Int32Slice gets the value as a []int32, returns the optionalDefault
+// value or nil if the value is not a []int32.
+func (v *Value) Int32Slice(optionalDefault ...[]int32) []int32 {
+	if s, ok := v.data.([]int32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInt32Slice gets the value as a []int32.
+//
+// Panics if the object is not a []int32.
+func (v *Value) MustInt32Slice() []int32 {
+	return v.data.([]int32)
+}
+
+// IsInt32 gets whether the object contained is a int32 or not.
+func (v *Value) IsInt32() bool {
+	_, ok := v.data.(int32)
+	return ok
+}
+
+// IsInt32Slice gets whether the object contained is a []int32 or not.
+func (v *Value) IsInt32Slice() bool {
+	_, ok := v.data.([]int32)
+	return ok
+}
+
+// EachInt32 calls the specified callback for each object
+// in the []int32.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInt32(callback func(int, int32) bool) *Value {
+
+	for index, val := range v.MustInt32Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInt32 uses the specified decider function to select items
+// from the []int32.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInt32(decider func(int, int32) bool) *Value {
+
+	var selected []int32
+
+	v.EachInt32(func(index int, val int32) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInt32 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]int32.
+func (v *Value) GroupInt32(grouper func(int, int32) string) *Value {
+
+	groups := make(map[string][]int32)
+
+	v.EachInt32(func(index int, val int32) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]int32, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInt32 uses the specified function to replace each int32s
+// by iterating each item.  The data in the returned result will be a
+// []int32 containing the replaced items.
+func (v *Value) ReplaceInt32(replacer func(int, int32) int32) *Value {
+
+	arr := v.MustInt32Slice()
+	replaced := make([]int32, len(arr))
+
+	v.EachInt32(func(index int, val int32) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInt32 uses the specified collector function to collect a value
+// for each of the int32s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInt32(collector func(int, int32) interface{}) *Value {
+
+	arr := v.MustInt32Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInt32(func(index int, val int32) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Int64 (int64 and []int64)
+	--------------------------------------------------
+*/
+
+// Int64 gets the value as a int64, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Int64(optionalDefault ...int64) int64 {
+	if s, ok := v.data.(int64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustInt64 gets the value as a int64.
+//
+// Panics if the object is not a int64.
+func (v *Value) MustInt64() int64 {
+	return v.data.(int64)
+}
+
+// Int64Slice gets the value as a []int64, returns the optionalDefault
+// value or nil if the value is not a []int64.
+func (v *Value) Int64Slice(optionalDefault ...[]int64) []int64 {
+	if s, ok := v.data.([]int64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInt64Slice gets the value as a []int64.
+//
+// Panics if the object is not a []int64.
+func (v *Value) MustInt64Slice() []int64 {
+	return v.data.([]int64)
+}
+
+// IsInt64 gets whether the object contained is a int64 or not.
+func (v *Value) IsInt64() bool {
+	_, ok := v.data.(int64)
+	return ok
+}
+
+// IsInt64Slice gets whether the object contained is a []int64 or not.
+func (v *Value) IsInt64Slice() bool {
+	_, ok := v.data.([]int64)
+	return ok
+}
+
+// EachInt64 calls the specified callback for each object
+// in the []int64.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInt64(callback func(int, int64) bool) *Value {
+
+	for index, val := range v.MustInt64Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInt64 uses the specified decider function to select items
+// from the []int64.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInt64(decider func(int, int64) bool) *Value {
+
+	var selected []int64
+
+	v.EachInt64(func(index int, val int64) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInt64 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]int64.
+func (v *Value) GroupInt64(grouper func(int, int64) string) *Value {
+
+	groups := make(map[string][]int64)
+
+	v.EachInt64(func(index int, val int64) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]int64, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInt64 uses the specified function to replace each int64s
+// by iterating each item.  The data in the returned result will be a
+// []int64 containing the replaced items.
+func (v *Value) ReplaceInt64(replacer func(int, int64) int64) *Value {
+
+	arr := v.MustInt64Slice()
+	replaced := make([]int64, len(arr))
+
+	v.EachInt64(func(index int, val int64) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInt64 uses the specified collector function to collect a value
+// for each of the int64s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInt64(collector func(int, int64) interface{}) *Value {
+
+	arr := v.MustInt64Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInt64(func(index int, val int64) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uint (uint and []uint)
+	--------------------------------------------------
+*/
+
+// Uint gets the value as a uint, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uint(optionalDefault ...uint) uint {
+	if s, ok := v.data.(uint); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUint gets the value as a uint.
+//
+// Panics if the object is not a uint.
+func (v *Value) MustUint() uint {
+	return v.data.(uint)
+}
+
+// UintSlice gets the value as a []uint, returns the optionalDefault
+// value or nil if the value is not a []uint.
+func (v *Value) UintSlice(optionalDefault ...[]uint) []uint {
+	if s, ok := v.data.([]uint); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUintSlice gets the value as a []uint.
+//
+// Panics if the object is not a []uint.
+func (v *Value) MustUintSlice() []uint {
+	return v.data.([]uint)
+}
+
+// IsUint gets whether the object contained is a uint or not.
+func (v *Value) IsUint() bool {
+	_, ok := v.data.(uint)
+	return ok
+}
+
+// IsUintSlice gets whether the object contained is a []uint or not.
+func (v *Value) IsUintSlice() bool {
+	_, ok := v.data.([]uint)
+	return ok
+}
+
+// EachUint calls the specified callback for each object
+// in the []uint.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUint(callback func(int, uint) bool) *Value {
+
+	for index, val := range v.MustUintSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUint uses the specified decider function to select items
+// from the []uint.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUint(decider func(int, uint) bool) *Value {
+
+	var selected []uint
+
+	v.EachUint(func(index int, val uint) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUint uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uint.
+func (v *Value) GroupUint(grouper func(int, uint) string) *Value {
+
+	groups := make(map[string][]uint)
+
+	v.EachUint(func(index int, val uint) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uint, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUint uses the specified function to replace each uints
+// by iterating each item.  The data in the returned result will be a
+// []uint containing the replaced items.
+func (v *Value) ReplaceUint(replacer func(int, uint) uint) *Value {
+
+	arr := v.MustUintSlice()
+	replaced := make([]uint, len(arr))
+
+	v.EachUint(func(index int, val uint) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUint uses the specified collector function to collect a value
+// for each of the uints in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUint(collector func(int, uint) interface{}) *Value {
+
+	arr := v.MustUintSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUint(func(index int, val uint) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uint8 (uint8 and []uint8)
+	--------------------------------------------------
+*/
+
+// Uint8 gets the value as a uint8, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uint8(optionalDefault ...uint8) uint8 {
+	if s, ok := v.data.(uint8); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUint8 gets the value as a uint8.
+//
+// Panics if the object is not a uint8.
+func (v *Value) MustUint8() uint8 {
+	return v.data.(uint8)
+}
+
+// Uint8Slice gets the value as a []uint8, returns the optionalDefault
+// value or nil if the value is not a []uint8.
+func (v *Value) Uint8Slice(optionalDefault ...[]uint8) []uint8 {
+	if s, ok := v.data.([]uint8); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUint8Slice gets the value as a []uint8.
+//
+// Panics if the object is not a []uint8.
+func (v *Value) MustUint8Slice() []uint8 {
+	return v.data.([]uint8)
+}
+
+// IsUint8 gets whether the object contained is a uint8 or not.
+func (v *Value) IsUint8() bool {
+	_, ok := v.data.(uint8)
+	return ok
+}
+
+// IsUint8Slice gets whether the object contained is a []uint8 or not.
+func (v *Value) IsUint8Slice() bool {
+	_, ok := v.data.([]uint8)
+	return ok
+}
+
+// EachUint8 calls the specified callback for each object
+// in the []uint8.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUint8(callback func(int, uint8) bool) *Value {
+
+	for index, val := range v.MustUint8Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUint8 uses the specified decider function to select items
+// from the []uint8.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUint8(decider func(int, uint8) bool) *Value {
+
+	var selected []uint8
+
+	v.EachUint8(func(index int, val uint8) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUint8 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uint8.
+func (v *Value) GroupUint8(grouper func(int, uint8) string) *Value {
+
+	groups := make(map[string][]uint8)
+
+	v.EachUint8(func(index int, val uint8) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uint8, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUint8 uses the specified function to replace each uint8s
+// by iterating each item.  The data in the returned result will be a
+// []uint8 containing the replaced items.
+func (v *Value) ReplaceUint8(replacer func(int, uint8) uint8) *Value {
+
+	arr := v.MustUint8Slice()
+	replaced := make([]uint8, len(arr))
+
+	v.EachUint8(func(index int, val uint8) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUint8 uses the specified collector function to collect a value
+// for each of the uint8s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUint8(collector func(int, uint8) interface{}) *Value {
+
+	arr := v.MustUint8Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUint8(func(index int, val uint8) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uint16 (uint16 and []uint16)
+	--------------------------------------------------
+*/
+
+// Uint16 gets the value as a uint16, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uint16(optionalDefault ...uint16) uint16 {
+	if s, ok := v.data.(uint16); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUint16 gets the value as a uint16.
+//
+// Panics if the object is not a uint16.
+func (v *Value) MustUint16() uint16 {
+	return v.data.(uint16)
+}
+
+// Uint16Slice gets the value as a []uint16, returns the optionalDefault
+// value or nil if the value is not a []uint16.
+func (v *Value) Uint16Slice(optionalDefault ...[]uint16) []uint16 {
+	if s, ok := v.data.([]uint16); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUint16Slice gets the value as a []uint16.
+//
+// Panics if the object is not a []uint16.
+func (v *Value) MustUint16Slice() []uint16 {
+	return v.data.([]uint16)
+}
+
+// IsUint16 gets whether the object contained is a uint16 or not.
+func (v *Value) IsUint16() bool {
+	_, ok := v.data.(uint16)
+	return ok
+}
+
+// IsUint16Slice gets whether the object contained is a []uint16 or not.
+func (v *Value) IsUint16Slice() bool {
+	_, ok := v.data.([]uint16)
+	return ok
+}
+
+// EachUint16 calls the specified callback for each object
+// in the []uint16.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUint16(callback func(int, uint16) bool) *Value {
+
+	for index, val := range v.MustUint16Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUint16 uses the specified decider function to select items
+// from the []uint16.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUint16(decider func(int, uint16) bool) *Value {
+
+	var selected []uint16
+
+	v.EachUint16(func(index int, val uint16) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUint16 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uint16.
+func (v *Value) GroupUint16(grouper func(int, uint16) string) *Value {
+
+	groups := make(map[string][]uint16)
+
+	v.EachUint16(func(index int, val uint16) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uint16, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUint16 uses the specified function to replace each uint16s
+// by iterating each item.  The data in the returned result will be a
+// []uint16 containing the replaced items.
+func (v *Value) ReplaceUint16(replacer func(int, uint16) uint16) *Value {
+
+	arr := v.MustUint16Slice()
+	replaced := make([]uint16, len(arr))
+
+	v.EachUint16(func(index int, val uint16) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUint16 uses the specified collector function to collect a value
+// for each of the uint16s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUint16(collector func(int, uint16) interface{}) *Value {
+
+	arr := v.MustUint16Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUint16(func(index int, val uint16) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uint32 (uint32 and []uint32)
+	--------------------------------------------------
+*/
+
+// Uint32 gets the value as a uint32, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uint32(optionalDefault ...uint32) uint32 {
+	if s, ok := v.data.(uint32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUint32 gets the value as a uint32.
+//
+// Panics if the object is not a uint32.
+func (v *Value) MustUint32() uint32 {
+	return v.data.(uint32)
+}
+
+// Uint32Slice gets the value as a []uint32, returns the optionalDefault
+// value or nil if the value is not a []uint32.
+func (v *Value) Uint32Slice(optionalDefault ...[]uint32) []uint32 {
+	if s, ok := v.data.([]uint32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUint32Slice gets the value as a []uint32.
+//
+// Panics if the object is not a []uint32.
+func (v *Value) MustUint32Slice() []uint32 {
+	return v.data.([]uint32)
+}
+
+// IsUint32 gets whether the object contained is a uint32 or not.
+func (v *Value) IsUint32() bool {
+	_, ok := v.data.(uint32)
+	return ok
+}
+
+// IsUint32Slice gets whether the object contained is a []uint32 or not.
+func (v *Value) IsUint32Slice() bool {
+	_, ok := v.data.([]uint32)
+	return ok
+}
+
+// EachUint32 calls the specified callback for each object
+// in the []uint32.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUint32(callback func(int, uint32) bool) *Value {
+
+	for index, val := range v.MustUint32Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUint32 uses the specified decider function to select items
+// from the []uint32.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUint32(decider func(int, uint32) bool) *Value {
+
+	var selected []uint32
+
+	v.EachUint32(func(index int, val uint32) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUint32 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uint32.
+func (v *Value) GroupUint32(grouper func(int, uint32) string) *Value {
+
+	groups := make(map[string][]uint32)
+
+	v.EachUint32(func(index int, val uint32) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uint32, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUint32 uses the specified function to replace each uint32s
+// by iterating each item.  The data in the returned result will be a
+// []uint32 containing the replaced items.
+func (v *Value) ReplaceUint32(replacer func(int, uint32) uint32) *Value {
+
+	arr := v.MustUint32Slice()
+	replaced := make([]uint32, len(arr))
+
+	v.EachUint32(func(index int, val uint32) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUint32 uses the specified collector function to collect a value
+// for each of the uint32s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUint32(collector func(int, uint32) interface{}) *Value {
+
+	arr := v.MustUint32Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUint32(func(index int, val uint32) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uint64 (uint64 and []uint64)
+	--------------------------------------------------
+*/
+
+// Uint64 gets the value as a uint64, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uint64(optionalDefault ...uint64) uint64 {
+	if s, ok := v.data.(uint64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUint64 gets the value as a uint64.
+//
+// Panics if the object is not a uint64.
+func (v *Value) MustUint64() uint64 {
+	return v.data.(uint64)
+}
+
+// Uint64Slice gets the value as a []uint64, returns the optionalDefault
+// value or nil if the value is not a []uint64.
+func (v *Value) Uint64Slice(optionalDefault ...[]uint64) []uint64 {
+	if s, ok := v.data.([]uint64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUint64Slice gets the value as a []uint64.
+//
+// Panics if the object is not a []uint64.
+func (v *Value) MustUint64Slice() []uint64 {
+	return v.data.([]uint64)
+}
+
+// IsUint64 gets whether the object contained is a uint64 or not.
+func (v *Value) IsUint64() bool {
+	_, ok := v.data.(uint64)
+	return ok
+}
+
+// IsUint64Slice gets whether the object contained is a []uint64 or not.
+func (v *Value) IsUint64Slice() bool {
+	_, ok := v.data.([]uint64)
+	return ok
+}
+
+// EachUint64 calls the specified callback for each object
+// in the []uint64.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUint64(callback func(int, uint64) bool) *Value {
+
+	for index, val := range v.MustUint64Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUint64 uses the specified decider function to select items
+// from the []uint64.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUint64(decider func(int, uint64) bool) *Value {
+
+	var selected []uint64
+
+	v.EachUint64(func(index int, val uint64) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUint64 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uint64.
+func (v *Value) GroupUint64(grouper func(int, uint64) string) *Value {
+
+	groups := make(map[string][]uint64)
+
+	v.EachUint64(func(index int, val uint64) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uint64, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUint64 uses the specified function to replace each uint64s
+// by iterating each item.  The data in the returned result will be a
+// []uint64 containing the replaced items.
+func (v *Value) ReplaceUint64(replacer func(int, uint64) uint64) *Value {
+
+	arr := v.MustUint64Slice()
+	replaced := make([]uint64, len(arr))
+
+	v.EachUint64(func(index int, val uint64) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUint64 uses the specified collector function to collect a value
+// for each of the uint64s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUint64(collector func(int, uint64) interface{}) *Value {
+
+	arr := v.MustUint64Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUint64(func(index int, val uint64) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uintptr (uintptr and []uintptr)
+	--------------------------------------------------
+*/
+
+// Uintptr gets the value as a uintptr, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uintptr(optionalDefault ...uintptr) uintptr {
+	if s, ok := v.data.(uintptr); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUintptr gets the value as a uintptr.
+//
+// Panics if the object is not a uintptr.
+func (v *Value) MustUintptr() uintptr {
+	return v.data.(uintptr)
+}
+
+// UintptrSlice gets the value as a []uintptr, returns the optionalDefault
+// value or nil if the value is not a []uintptr.
+func (v *Value) UintptrSlice(optionalDefault ...[]uintptr) []uintptr {
+	if s, ok := v.data.([]uintptr); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUintptrSlice gets the value as a []uintptr.
+//
+// Panics if the object is not a []uintptr.
+func (v *Value) MustUintptrSlice() []uintptr {
+	return v.data.([]uintptr)
+}
+
+// IsUintptr gets whether the object contained is a uintptr or not.
+func (v *Value) IsUintptr() bool {
+	_, ok := v.data.(uintptr)
+	return ok
+}
+
+// IsUintptrSlice gets whether the object contained is a []uintptr or not.
+func (v *Value) IsUintptrSlice() bool {
+	_, ok := v.data.([]uintptr)
+	return ok
+}
+
+// EachUintptr calls the specified callback for each object
+// in the []uintptr.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUintptr(callback func(int, uintptr) bool) *Value {
+
+	for index, val := range v.MustUintptrSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUintptr uses the specified decider function to select items
+// from the []uintptr.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUintptr(decider func(int, uintptr) bool) *Value {
+
+	var selected []uintptr
+
+	v.EachUintptr(func(index int, val uintptr) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUintptr uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uintptr.
+func (v *Value) GroupUintptr(grouper func(int, uintptr) string) *Value {
+
+	groups := make(map[string][]uintptr)
+
+	v.EachUintptr(func(index int, val uintptr) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uintptr, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUintptr uses the specified function to replace each uintptrs
+// by iterating each item.  The data in the returned result will be a
+// []uintptr containing the replaced items.
+func (v *Value) ReplaceUintptr(replacer func(int, uintptr) uintptr) *Value {
+
+	arr := v.MustUintptrSlice()
+	replaced := make([]uintptr, len(arr))
+
+	v.EachUintptr(func(index int, val uintptr) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUintptr uses the specified collector function to collect a value
+// for each of the uintptrs in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUintptr(collector func(int, uintptr) interface{}) *Value {
+
+	arr := v.MustUintptrSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUintptr(func(index int, val uintptr) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Float32 (float32 and []float32)
+	--------------------------------------------------
+*/
+
+// Float32 gets the value as a float32, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Float32(optionalDefault ...float32) float32 {
+	if s, ok := v.data.(float32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustFloat32 gets the value as a float32.
+//
+// Panics if the object is not a float32.
+func (v *Value) MustFloat32() float32 {
+	return v.data.(float32)
+}
+
+// Float32Slice gets the value as a []float32, returns the optionalDefault
+// value or nil if the value is not a []float32.
+func (v *Value) Float32Slice(optionalDefault ...[]float32) []float32 {
+	if s, ok := v.data.([]float32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustFloat32Slice gets the value as a []float32.
+//
+// Panics if the object is not a []float32.
+func (v *Value) MustFloat32Slice() []float32 {
+	return v.data.([]float32)
+}
+
+// IsFloat32 gets whether the object contained is a float32 or not.
+func (v *Value) IsFloat32() bool {
+	_, ok := v.data.(float32)
+	return ok
+}
+
+// IsFloat32Slice gets whether the object contained is a []float32 or not.
+func (v *Value) IsFloat32Slice() bool {
+	_, ok := v.data.([]float32)
+	return ok
+}
+
+// EachFloat32 calls the specified callback for each object
+// in the []float32.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachFloat32(callback func(int, float32) bool) *Value {
+
+	for index, val := range v.MustFloat32Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereFloat32 uses the specified decider function to select items
+// from the []float32.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereFloat32(decider func(int, float32) bool) *Value {
+
+	var selected []float32
+
+	v.EachFloat32(func(index int, val float32) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupFloat32 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]float32.
+func (v *Value) GroupFloat32(grouper func(int, float32) string) *Value {
+
+	groups := make(map[string][]float32)
+
+	v.EachFloat32(func(index int, val float32) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]float32, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceFloat32 uses the specified function to replace each float32s
+// by iterating each item.  The data in the returned result will be a
+// []float32 containing the replaced items.
+func (v *Value) ReplaceFloat32(replacer func(int, float32) float32) *Value {
+
+	arr := v.MustFloat32Slice()
+	replaced := make([]float32, len(arr))
+
+	v.EachFloat32(func(index int, val float32) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectFloat32 uses the specified collector function to collect a value
+// for each of the float32s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectFloat32(collector func(int, float32) interface{}) *Value {
+
+	arr := v.MustFloat32Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachFloat32(func(index int, val float32) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Float64 (float64 and []float64)
+	--------------------------------------------------
+*/
+
+// Float64 gets the value as a float64, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Float64(optionalDefault ...float64) float64 {
+	if s, ok := v.data.(float64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustFloat64 gets the value as a float64.
+//
+// Panics if the object is not a float64.
+func (v *Value) MustFloat64() float64 {
+	return v.data.(float64)
+}
+
+// Float64Slice gets the value as a []float64, returns the optionalDefault
+// value or nil if the value is not a []float64.
+func (v *Value) Float64Slice(optionalDefault ...[]float64) []float64 {
+	if s, ok := v.data.([]float64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustFloat64Slice gets the value as a []float64.
+//
+// Panics if the object is not a []float64.
+func (v *Value) MustFloat64Slice() []float64 {
+	return v.data.([]float64)
+}
+
+// IsFloat64 gets whether the object contained is a float64 or not.
+func (v *Value) IsFloat64() bool {
+	_, ok := v.data.(float64)
+	return ok
+}
+
+// IsFloat64Slice gets whether the object contained is a []float64 or not.
+func (v *Value) IsFloat64Slice() bool {
+	_, ok := v.data.([]float64)
+	return ok
+}
+
+// EachFloat64 calls the specified callback for each object
+// in the []float64.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachFloat64(callback func(int, float64) bool) *Value {
+
+	for index, val := range v.MustFloat64Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereFloat64 uses the specified decider function to select items
+// from the []float64.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereFloat64(decider func(int, float64) bool) *Value {
+
+	var selected []float64
+
+	v.EachFloat64(func(index int, val float64) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupFloat64 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]float64.
+func (v *Value) GroupFloat64(grouper func(int, float64) string) *Value {
+
+	groups := make(map[string][]float64)
+
+	v.EachFloat64(func(index int, val float64) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]float64, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceFloat64 uses the specified function to replace each float64s
+// by iterating each item.  The data in the returned result will be a
+// []float64 containing the replaced items.
+func (v *Value) ReplaceFloat64(replacer func(int, float64) float64) *Value {
+
+	arr := v.MustFloat64Slice()
+	replaced := make([]float64, len(arr))
+
+	v.EachFloat64(func(index int, val float64) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectFloat64 uses the specified collector function to collect a value
+// for each of the float64s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectFloat64(collector func(int, float64) interface{}) *Value {
+
+	arr := v.MustFloat64Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachFloat64(func(index int, val float64) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Complex64 (complex64 and []complex64)
+	--------------------------------------------------
+*/
+
+// Complex64 gets the value as a complex64, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Complex64(optionalDefault ...complex64) complex64 {
+	if s, ok := v.data.(complex64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustComplex64 gets the value as a complex64.
+//
+// Panics if the object is not a complex64.
+func (v *Value) MustComplex64() complex64 {
+	return v.data.(complex64)
+}
+
+// Complex64Slice gets the value as a []complex64, returns the optionalDefault
+// value or nil if the value is not a []complex64.
+func (v *Value) Complex64Slice(optionalDefault ...[]complex64) []complex64 {
+	if s, ok := v.data.([]complex64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustComplex64Slice gets the value as a []complex64.
+//
+// Panics if the object is not a []complex64.
+func (v *Value) MustComplex64Slice() []complex64 {
+	return v.data.([]complex64)
+}
+
+// IsComplex64 gets whether the object contained is a complex64 or not.
+func (v *Value) IsComplex64() bool {
+	_, ok := v.data.(complex64)
+	return ok
+}
+
+// IsComplex64Slice gets whether the object contained is a []complex64 or not.
+func (v *Value) IsComplex64Slice() bool {
+	_, ok := v.data.([]complex64)
+	return ok
+}
+
+// EachComplex64 calls the specified callback for each object
+// in the []complex64.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachComplex64(callback func(int, complex64) bool) *Value {
+
+	for index, val := range v.MustComplex64Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereComplex64 uses the specified decider function to select items
+// from the []complex64.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereComplex64(decider func(int, complex64) bool) *Value {
+
+	var selected []complex64
+
+	v.EachComplex64(func(index int, val complex64) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupComplex64 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]complex64.
+func (v *Value) GroupComplex64(grouper func(int, complex64) string) *Value {
+
+	groups := make(map[string][]complex64)
+
+	v.EachComplex64(func(index int, val complex64) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]complex64, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceComplex64 uses the specified function to replace each complex64s
+// by iterating each item.  The data in the returned result will be a
+// []complex64 containing the replaced items.
+func (v *Value) ReplaceComplex64(replacer func(int, complex64) complex64) *Value {
+
+	arr := v.MustComplex64Slice()
+	replaced := make([]complex64, len(arr))
+
+	v.EachComplex64(func(index int, val complex64) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectComplex64 uses the specified collector function to collect a value
+// for each of the complex64s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectComplex64(collector func(int, complex64) interface{}) *Value {
+
+	arr := v.MustComplex64Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachComplex64(func(index int, val complex64) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Complex128 (complex128 and []complex128)
+	--------------------------------------------------
+*/
+
+// Complex128 gets the value as a complex128, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Complex128(optionalDefault ...complex128) complex128 {
+	if s, ok := v.data.(complex128); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustComplex128 gets the value as a complex128.
+//
+// Panics if the object is not a complex128.
+func (v *Value) MustComplex128() complex128 {
+	return v.data.(complex128)
+}
+
+// Complex128Slice gets the value as a []complex128, returns the optionalDefault
+// value or nil if the value is not a []complex128.
+func (v *Value) Complex128Slice(optionalDefault ...[]complex128) []complex128 {
+	if s, ok := v.data.([]complex128); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustComplex128Slice gets the value as a []complex128.
+//
+// Panics if the object is not a []complex128.
+func (v *Value) MustComplex128Slice() []complex128 {
+	return v.data.([]complex128)
+}
+
+// IsComplex128 gets whether the object contained is a complex128 or not.
+func (v *Value) IsComplex128() bool {
+	_, ok := v.data.(complex128)
+	return ok
+}
+
+// IsComplex128Slice gets whether the object contained is a []complex128 or not.
+func (v *Value) IsComplex128Slice() bool {
+	_, ok := v.data.([]complex128)
+	return ok
+}
+
+// EachComplex128 calls the specified callback for each object
+// in the []complex128.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachComplex128(callback func(int, complex128) bool) *Value {
+
+	for index, val := range v.MustComplex128Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereComplex128 uses the specified decider function to select items
+// from the []complex128.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereComplex128(decider func(int, complex128) bool) *Value {
+
+	var selected []complex128
+
+	v.EachComplex128(func(index int, val complex128) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupComplex128 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]complex128.
+func (v *Value) GroupComplex128(grouper func(int, complex128) string) *Value {
+
+	groups := make(map[string][]complex128)
+
+	v.EachComplex128(func(index int, val complex128) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]complex128, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceComplex128 uses the specified function to replace each complex128s
+// by iterating each item.  The data in the returned result will be a
+// []complex128 containing the replaced items.
+func (v *Value) ReplaceComplex128(replacer func(int, complex128) complex128) *Value {
+
+	arr := v.MustComplex128Slice()
+	replaced := make([]complex128, len(arr))
+
+	v.EachComplex128(func(index int, val complex128) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectComplex128 uses the specified collector function to collect a value
+// for each of the complex128s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectComplex128(collector func(int, complex128) interface{}) *Value {
+
+	arr := v.MustComplex128Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachComplex128(func(index int, val complex128) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
diff --git a/go/src/github.com/stretchr/objx/type_specific_codegen_test.go b/go/src/github.com/stretchr/objx/type_specific_codegen_test.go
new file mode 100644
index 0000000..f7a4fce
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/type_specific_codegen_test.go
@@ -0,0 +1,2867 @@
+package objx
+
+import (
+	"fmt"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestInter(t *testing.T) {
+
+	val := interface{}("something")
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Inter())
+	assert.Equal(t, val, New(m).Get("value").MustInter())
+	assert.Equal(t, interface{}(nil), New(m).Get("nothing").Inter())
+	assert.Equal(t, val, New(m).Get("nothing").Inter("something"))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustInter()
+	})
+
+}
+
+func TestInterSlice(t *testing.T) {
+
+	val := interface{}("something")
+	m := map[string]interface{}{"value": []interface{}{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").InterSlice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustInterSlice()[0])
+	assert.Equal(t, []interface{}(nil), New(m).Get("nothing").InterSlice())
+	assert.Equal(t, val, New(m).Get("nothing").InterSlice([]interface{}{interface{}("something")})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustInterSlice()
+	})
+
+}
+
+func TestIsInter(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: interface{}("something")}
+	assert.True(t, v.IsInter())
+
+	v = &Value{data: []interface{}{interface{}("something")}}
+	assert.True(t, v.IsInterSlice())
+
+}
+
+func TestEachInter(t *testing.T) {
+
+	v := &Value{data: []interface{}{interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something")}}
+	count := 0
+	replacedVals := make([]interface{}, 0)
+	assert.Equal(t, v, v.EachInter(func(i int, val interface{}) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustInterSlice()[0])
+	assert.Equal(t, replacedVals[1], v.MustInterSlice()[1])
+	assert.Equal(t, replacedVals[2], v.MustInterSlice()[2])
+
+}
+
+func TestWhereInter(t *testing.T) {
+
+	v := &Value{data: []interface{}{interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something")}}
+
+	selected := v.WhereInter(func(i int, val interface{}) bool {
+		return i%2 == 0
+	}).MustInterSlice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupInter(t *testing.T) {
+
+	v := &Value{data: []interface{}{interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something")}}
+
+	grouped := v.GroupInter(func(i int, val interface{}) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]interface{})
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceInter(t *testing.T) {
+
+	v := &Value{data: []interface{}{interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something")}}
+
+	rawArr := v.MustInterSlice()
+
+	replaced := v.ReplaceInter(func(index int, val interface{}) interface{} {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustInterSlice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectInter(t *testing.T) {
+
+	v := &Value{data: []interface{}{interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something"), interface{}("something")}}
+
+	collected := v.CollectInter(func(index int, val interface{}) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestMSI(t *testing.T) {
+
+	val := map[string]interface{}(map[string]interface{}{"name": "Tyler"})
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").MSI())
+	assert.Equal(t, val, New(m).Get("value").MustMSI())
+	assert.Equal(t, map[string]interface{}(nil), New(m).Get("nothing").MSI())
+	assert.Equal(t, val, New(m).Get("nothing").MSI(map[string]interface{}{"name": "Tyler"}))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustMSI()
+	})
+
+}
+
+func TestMSISlice(t *testing.T) {
+
+	val := map[string]interface{}(map[string]interface{}{"name": "Tyler"})
+	m := map[string]interface{}{"value": []map[string]interface{}{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").MSISlice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustMSISlice()[0])
+	assert.Equal(t, []map[string]interface{}(nil), New(m).Get("nothing").MSISlice())
+	assert.Equal(t, val, New(m).Get("nothing").MSISlice([]map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"})})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustMSISlice()
+	})
+
+}
+
+func TestIsMSI(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: map[string]interface{}(map[string]interface{}{"name": "Tyler"})}
+	assert.True(t, v.IsMSI())
+
+	v = &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"})}}
+	assert.True(t, v.IsMSISlice())
+
+}
+
+func TestEachMSI(t *testing.T) {
+
+	v := &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"})}}
+	count := 0
+	replacedVals := make([]map[string]interface{}, 0)
+	assert.Equal(t, v, v.EachMSI(func(i int, val map[string]interface{}) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustMSISlice()[0])
+	assert.Equal(t, replacedVals[1], v.MustMSISlice()[1])
+	assert.Equal(t, replacedVals[2], v.MustMSISlice()[2])
+
+}
+
+func TestWhereMSI(t *testing.T) {
+
+	v := &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"})}}
+
+	selected := v.WhereMSI(func(i int, val map[string]interface{}) bool {
+		return i%2 == 0
+	}).MustMSISlice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupMSI(t *testing.T) {
+
+	v := &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"})}}
+
+	grouped := v.GroupMSI(func(i int, val map[string]interface{}) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]map[string]interface{})
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceMSI(t *testing.T) {
+
+	v := &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"})}}
+
+	rawArr := v.MustMSISlice()
+
+	replaced := v.ReplaceMSI(func(index int, val map[string]interface{}) map[string]interface{} {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustMSISlice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectMSI(t *testing.T) {
+
+	v := &Value{data: []map[string]interface{}{map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"}), map[string]interface{}(map[string]interface{}{"name": "Tyler"})}}
+
+	collected := v.CollectMSI(func(index int, val map[string]interface{}) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestObjxMap(t *testing.T) {
+
+	val := (Map)(New(1))
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").ObjxMap())
+	assert.Equal(t, val, New(m).Get("value").MustObjxMap())
+	assert.Equal(t, (Map)(New(nil)), New(m).Get("nothing").ObjxMap())
+	assert.Equal(t, val, New(m).Get("nothing").ObjxMap(New(1)))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustObjxMap()
+	})
+
+}
+
+func TestObjxMapSlice(t *testing.T) {
+
+	val := (Map)(New(1))
+	m := map[string]interface{}{"value": [](Map){val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").ObjxMapSlice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustObjxMapSlice()[0])
+	assert.Equal(t, [](Map)(nil), New(m).Get("nothing").ObjxMapSlice())
+	assert.Equal(t, val, New(m).Get("nothing").ObjxMapSlice([](Map){(Map)(New(1))})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustObjxMapSlice()
+	})
+
+}
+
+func TestIsObjxMap(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: (Map)(New(1))}
+	assert.True(t, v.IsObjxMap())
+
+	v = &Value{data: [](Map){(Map)(New(1))}}
+	assert.True(t, v.IsObjxMapSlice())
+
+}
+
+func TestEachObjxMap(t *testing.T) {
+
+	v := &Value{data: [](Map){(Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1))}}
+	count := 0
+	replacedVals := make([](Map), 0)
+	assert.Equal(t, v, v.EachObjxMap(func(i int, val Map) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustObjxMapSlice()[0])
+	assert.Equal(t, replacedVals[1], v.MustObjxMapSlice()[1])
+	assert.Equal(t, replacedVals[2], v.MustObjxMapSlice()[2])
+
+}
+
+func TestWhereObjxMap(t *testing.T) {
+
+	v := &Value{data: [](Map){(Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1))}}
+
+	selected := v.WhereObjxMap(func(i int, val Map) bool {
+		return i%2 == 0
+	}).MustObjxMapSlice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupObjxMap(t *testing.T) {
+
+	v := &Value{data: [](Map){(Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1))}}
+
+	grouped := v.GroupObjxMap(func(i int, val Map) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][](Map))
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceObjxMap(t *testing.T) {
+
+	v := &Value{data: [](Map){(Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1))}}
+
+	rawArr := v.MustObjxMapSlice()
+
+	replaced := v.ReplaceObjxMap(func(index int, val Map) Map {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustObjxMapSlice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectObjxMap(t *testing.T) {
+
+	v := &Value{data: [](Map){(Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1)), (Map)(New(1))}}
+
+	collected := v.CollectObjxMap(func(index int, val Map) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestBool(t *testing.T) {
+
+	val := bool(true)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Bool())
+	assert.Equal(t, val, New(m).Get("value").MustBool())
+	assert.Equal(t, bool(false), New(m).Get("nothing").Bool())
+	assert.Equal(t, val, New(m).Get("nothing").Bool(true))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustBool()
+	})
+
+}
+
+func TestBoolSlice(t *testing.T) {
+
+	val := bool(true)
+	m := map[string]interface{}{"value": []bool{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").BoolSlice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustBoolSlice()[0])
+	assert.Equal(t, []bool(nil), New(m).Get("nothing").BoolSlice())
+	assert.Equal(t, val, New(m).Get("nothing").BoolSlice([]bool{bool(true)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustBoolSlice()
+	})
+
+}
+
+func TestIsBool(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: bool(true)}
+	assert.True(t, v.IsBool())
+
+	v = &Value{data: []bool{bool(true)}}
+	assert.True(t, v.IsBoolSlice())
+
+}
+
+func TestEachBool(t *testing.T) {
+
+	v := &Value{data: []bool{bool(true), bool(true), bool(true), bool(true), bool(true)}}
+	count := 0
+	replacedVals := make([]bool, 0)
+	assert.Equal(t, v, v.EachBool(func(i int, val bool) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustBoolSlice()[0])
+	assert.Equal(t, replacedVals[1], v.MustBoolSlice()[1])
+	assert.Equal(t, replacedVals[2], v.MustBoolSlice()[2])
+
+}
+
+func TestWhereBool(t *testing.T) {
+
+	v := &Value{data: []bool{bool(true), bool(true), bool(true), bool(true), bool(true), bool(true)}}
+
+	selected := v.WhereBool(func(i int, val bool) bool {
+		return i%2 == 0
+	}).MustBoolSlice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupBool(t *testing.T) {
+
+	v := &Value{data: []bool{bool(true), bool(true), bool(true), bool(true), bool(true), bool(true)}}
+
+	grouped := v.GroupBool(func(i int, val bool) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]bool)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceBool(t *testing.T) {
+
+	v := &Value{data: []bool{bool(true), bool(true), bool(true), bool(true), bool(true), bool(true)}}
+
+	rawArr := v.MustBoolSlice()
+
+	replaced := v.ReplaceBool(func(index int, val bool) bool {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustBoolSlice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectBool(t *testing.T) {
+
+	v := &Value{data: []bool{bool(true), bool(true), bool(true), bool(true), bool(true), bool(true)}}
+
+	collected := v.CollectBool(func(index int, val bool) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestStr(t *testing.T) {
+
+	val := string("hello")
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Str())
+	assert.Equal(t, val, New(m).Get("value").MustStr())
+	assert.Equal(t, string(""), New(m).Get("nothing").Str())
+	assert.Equal(t, val, New(m).Get("nothing").Str("hello"))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustStr()
+	})
+
+}
+
+func TestStrSlice(t *testing.T) {
+
+	val := string("hello")
+	m := map[string]interface{}{"value": []string{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").StrSlice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustStrSlice()[0])
+	assert.Equal(t, []string(nil), New(m).Get("nothing").StrSlice())
+	assert.Equal(t, val, New(m).Get("nothing").StrSlice([]string{string("hello")})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustStrSlice()
+	})
+
+}
+
+func TestIsStr(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: string("hello")}
+	assert.True(t, v.IsStr())
+
+	v = &Value{data: []string{string("hello")}}
+	assert.True(t, v.IsStrSlice())
+
+}
+
+func TestEachStr(t *testing.T) {
+
+	v := &Value{data: []string{string("hello"), string("hello"), string("hello"), string("hello"), string("hello")}}
+	count := 0
+	replacedVals := make([]string, 0)
+	assert.Equal(t, v, v.EachStr(func(i int, val string) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustStrSlice()[0])
+	assert.Equal(t, replacedVals[1], v.MustStrSlice()[1])
+	assert.Equal(t, replacedVals[2], v.MustStrSlice()[2])
+
+}
+
+func TestWhereStr(t *testing.T) {
+
+	v := &Value{data: []string{string("hello"), string("hello"), string("hello"), string("hello"), string("hello"), string("hello")}}
+
+	selected := v.WhereStr(func(i int, val string) bool {
+		return i%2 == 0
+	}).MustStrSlice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupStr(t *testing.T) {
+
+	v := &Value{data: []string{string("hello"), string("hello"), string("hello"), string("hello"), string("hello"), string("hello")}}
+
+	grouped := v.GroupStr(func(i int, val string) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]string)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceStr(t *testing.T) {
+
+	v := &Value{data: []string{string("hello"), string("hello"), string("hello"), string("hello"), string("hello"), string("hello")}}
+
+	rawArr := v.MustStrSlice()
+
+	replaced := v.ReplaceStr(func(index int, val string) string {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustStrSlice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectStr(t *testing.T) {
+
+	v := &Value{data: []string{string("hello"), string("hello"), string("hello"), string("hello"), string("hello"), string("hello")}}
+
+	collected := v.CollectStr(func(index int, val string) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestInt(t *testing.T) {
+
+	val := int(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Int())
+	assert.Equal(t, val, New(m).Get("value").MustInt())
+	assert.Equal(t, int(0), New(m).Get("nothing").Int())
+	assert.Equal(t, val, New(m).Get("nothing").Int(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustInt()
+	})
+
+}
+
+func TestIntSlice(t *testing.T) {
+
+	val := int(1)
+	m := map[string]interface{}{"value": []int{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").IntSlice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustIntSlice()[0])
+	assert.Equal(t, []int(nil), New(m).Get("nothing").IntSlice())
+	assert.Equal(t, val, New(m).Get("nothing").IntSlice([]int{int(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustIntSlice()
+	})
+
+}
+
+func TestIsInt(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: int(1)}
+	assert.True(t, v.IsInt())
+
+	v = &Value{data: []int{int(1)}}
+	assert.True(t, v.IsIntSlice())
+
+}
+
+func TestEachInt(t *testing.T) {
+
+	v := &Value{data: []int{int(1), int(1), int(1), int(1), int(1)}}
+	count := 0
+	replacedVals := make([]int, 0)
+	assert.Equal(t, v, v.EachInt(func(i int, val int) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustIntSlice()[0])
+	assert.Equal(t, replacedVals[1], v.MustIntSlice()[1])
+	assert.Equal(t, replacedVals[2], v.MustIntSlice()[2])
+
+}
+
+func TestWhereInt(t *testing.T) {
+
+	v := &Value{data: []int{int(1), int(1), int(1), int(1), int(1), int(1)}}
+
+	selected := v.WhereInt(func(i int, val int) bool {
+		return i%2 == 0
+	}).MustIntSlice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupInt(t *testing.T) {
+
+	v := &Value{data: []int{int(1), int(1), int(1), int(1), int(1), int(1)}}
+
+	grouped := v.GroupInt(func(i int, val int) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]int)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceInt(t *testing.T) {
+
+	v := &Value{data: []int{int(1), int(1), int(1), int(1), int(1), int(1)}}
+
+	rawArr := v.MustIntSlice()
+
+	replaced := v.ReplaceInt(func(index int, val int) int {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustIntSlice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectInt(t *testing.T) {
+
+	v := &Value{data: []int{int(1), int(1), int(1), int(1), int(1), int(1)}}
+
+	collected := v.CollectInt(func(index int, val int) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestInt8(t *testing.T) {
+
+	val := int8(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Int8())
+	assert.Equal(t, val, New(m).Get("value").MustInt8())
+	assert.Equal(t, int8(0), New(m).Get("nothing").Int8())
+	assert.Equal(t, val, New(m).Get("nothing").Int8(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustInt8()
+	})
+
+}
+
+func TestInt8Slice(t *testing.T) {
+
+	val := int8(1)
+	m := map[string]interface{}{"value": []int8{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Int8Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustInt8Slice()[0])
+	assert.Equal(t, []int8(nil), New(m).Get("nothing").Int8Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Int8Slice([]int8{int8(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustInt8Slice()
+	})
+
+}
+
+func TestIsInt8(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: int8(1)}
+	assert.True(t, v.IsInt8())
+
+	v = &Value{data: []int8{int8(1)}}
+	assert.True(t, v.IsInt8Slice())
+
+}
+
+func TestEachInt8(t *testing.T) {
+
+	v := &Value{data: []int8{int8(1), int8(1), int8(1), int8(1), int8(1)}}
+	count := 0
+	replacedVals := make([]int8, 0)
+	assert.Equal(t, v, v.EachInt8(func(i int, val int8) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustInt8Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustInt8Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustInt8Slice()[2])
+
+}
+
+func TestWhereInt8(t *testing.T) {
+
+	v := &Value{data: []int8{int8(1), int8(1), int8(1), int8(1), int8(1), int8(1)}}
+
+	selected := v.WhereInt8(func(i int, val int8) bool {
+		return i%2 == 0
+	}).MustInt8Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupInt8(t *testing.T) {
+
+	v := &Value{data: []int8{int8(1), int8(1), int8(1), int8(1), int8(1), int8(1)}}
+
+	grouped := v.GroupInt8(func(i int, val int8) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]int8)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceInt8(t *testing.T) {
+
+	v := &Value{data: []int8{int8(1), int8(1), int8(1), int8(1), int8(1), int8(1)}}
+
+	rawArr := v.MustInt8Slice()
+
+	replaced := v.ReplaceInt8(func(index int, val int8) int8 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustInt8Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectInt8(t *testing.T) {
+
+	v := &Value{data: []int8{int8(1), int8(1), int8(1), int8(1), int8(1), int8(1)}}
+
+	collected := v.CollectInt8(func(index int, val int8) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestInt16(t *testing.T) {
+
+	val := int16(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Int16())
+	assert.Equal(t, val, New(m).Get("value").MustInt16())
+	assert.Equal(t, int16(0), New(m).Get("nothing").Int16())
+	assert.Equal(t, val, New(m).Get("nothing").Int16(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustInt16()
+	})
+
+}
+
+func TestInt16Slice(t *testing.T) {
+
+	val := int16(1)
+	m := map[string]interface{}{"value": []int16{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Int16Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustInt16Slice()[0])
+	assert.Equal(t, []int16(nil), New(m).Get("nothing").Int16Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Int16Slice([]int16{int16(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustInt16Slice()
+	})
+
+}
+
+func TestIsInt16(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: int16(1)}
+	assert.True(t, v.IsInt16())
+
+	v = &Value{data: []int16{int16(1)}}
+	assert.True(t, v.IsInt16Slice())
+
+}
+
+func TestEachInt16(t *testing.T) {
+
+	v := &Value{data: []int16{int16(1), int16(1), int16(1), int16(1), int16(1)}}
+	count := 0
+	replacedVals := make([]int16, 0)
+	assert.Equal(t, v, v.EachInt16(func(i int, val int16) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustInt16Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustInt16Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustInt16Slice()[2])
+
+}
+
+func TestWhereInt16(t *testing.T) {
+
+	v := &Value{data: []int16{int16(1), int16(1), int16(1), int16(1), int16(1), int16(1)}}
+
+	selected := v.WhereInt16(func(i int, val int16) bool {
+		return i%2 == 0
+	}).MustInt16Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupInt16(t *testing.T) {
+
+	v := &Value{data: []int16{int16(1), int16(1), int16(1), int16(1), int16(1), int16(1)}}
+
+	grouped := v.GroupInt16(func(i int, val int16) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]int16)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceInt16(t *testing.T) {
+
+	v := &Value{data: []int16{int16(1), int16(1), int16(1), int16(1), int16(1), int16(1)}}
+
+	rawArr := v.MustInt16Slice()
+
+	replaced := v.ReplaceInt16(func(index int, val int16) int16 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustInt16Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectInt16(t *testing.T) {
+
+	v := &Value{data: []int16{int16(1), int16(1), int16(1), int16(1), int16(1), int16(1)}}
+
+	collected := v.CollectInt16(func(index int, val int16) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestInt32(t *testing.T) {
+
+	val := int32(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Int32())
+	assert.Equal(t, val, New(m).Get("value").MustInt32())
+	assert.Equal(t, int32(0), New(m).Get("nothing").Int32())
+	assert.Equal(t, val, New(m).Get("nothing").Int32(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustInt32()
+	})
+
+}
+
+func TestInt32Slice(t *testing.T) {
+
+	val := int32(1)
+	m := map[string]interface{}{"value": []int32{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Int32Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustInt32Slice()[0])
+	assert.Equal(t, []int32(nil), New(m).Get("nothing").Int32Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Int32Slice([]int32{int32(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustInt32Slice()
+	})
+
+}
+
+func TestIsInt32(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: int32(1)}
+	assert.True(t, v.IsInt32())
+
+	v = &Value{data: []int32{int32(1)}}
+	assert.True(t, v.IsInt32Slice())
+
+}
+
+func TestEachInt32(t *testing.T) {
+
+	v := &Value{data: []int32{int32(1), int32(1), int32(1), int32(1), int32(1)}}
+	count := 0
+	replacedVals := make([]int32, 0)
+	assert.Equal(t, v, v.EachInt32(func(i int, val int32) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustInt32Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustInt32Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustInt32Slice()[2])
+
+}
+
+func TestWhereInt32(t *testing.T) {
+
+	v := &Value{data: []int32{int32(1), int32(1), int32(1), int32(1), int32(1), int32(1)}}
+
+	selected := v.WhereInt32(func(i int, val int32) bool {
+		return i%2 == 0
+	}).MustInt32Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupInt32(t *testing.T) {
+
+	v := &Value{data: []int32{int32(1), int32(1), int32(1), int32(1), int32(1), int32(1)}}
+
+	grouped := v.GroupInt32(func(i int, val int32) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]int32)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceInt32(t *testing.T) {
+
+	v := &Value{data: []int32{int32(1), int32(1), int32(1), int32(1), int32(1), int32(1)}}
+
+	rawArr := v.MustInt32Slice()
+
+	replaced := v.ReplaceInt32(func(index int, val int32) int32 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustInt32Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectInt32(t *testing.T) {
+
+	v := &Value{data: []int32{int32(1), int32(1), int32(1), int32(1), int32(1), int32(1)}}
+
+	collected := v.CollectInt32(func(index int, val int32) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestInt64(t *testing.T) {
+
+	val := int64(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Int64())
+	assert.Equal(t, val, New(m).Get("value").MustInt64())
+	assert.Equal(t, int64(0), New(m).Get("nothing").Int64())
+	assert.Equal(t, val, New(m).Get("nothing").Int64(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustInt64()
+	})
+
+}
+
+func TestInt64Slice(t *testing.T) {
+
+	val := int64(1)
+	m := map[string]interface{}{"value": []int64{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Int64Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustInt64Slice()[0])
+	assert.Equal(t, []int64(nil), New(m).Get("nothing").Int64Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Int64Slice([]int64{int64(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustInt64Slice()
+	})
+
+}
+
+func TestIsInt64(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: int64(1)}
+	assert.True(t, v.IsInt64())
+
+	v = &Value{data: []int64{int64(1)}}
+	assert.True(t, v.IsInt64Slice())
+
+}
+
+func TestEachInt64(t *testing.T) {
+
+	v := &Value{data: []int64{int64(1), int64(1), int64(1), int64(1), int64(1)}}
+	count := 0
+	replacedVals := make([]int64, 0)
+	assert.Equal(t, v, v.EachInt64(func(i int, val int64) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustInt64Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustInt64Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustInt64Slice()[2])
+
+}
+
+func TestWhereInt64(t *testing.T) {
+
+	v := &Value{data: []int64{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}}
+
+	selected := v.WhereInt64(func(i int, val int64) bool {
+		return i%2 == 0
+	}).MustInt64Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupInt64(t *testing.T) {
+
+	v := &Value{data: []int64{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}}
+
+	grouped := v.GroupInt64(func(i int, val int64) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]int64)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceInt64(t *testing.T) {
+
+	v := &Value{data: []int64{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}}
+
+	rawArr := v.MustInt64Slice()
+
+	replaced := v.ReplaceInt64(func(index int, val int64) int64 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustInt64Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectInt64(t *testing.T) {
+
+	v := &Value{data: []int64{int64(1), int64(1), int64(1), int64(1), int64(1), int64(1)}}
+
+	collected := v.CollectInt64(func(index int, val int64) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestUint(t *testing.T) {
+
+	val := uint(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Uint())
+	assert.Equal(t, val, New(m).Get("value").MustUint())
+	assert.Equal(t, uint(0), New(m).Get("nothing").Uint())
+	assert.Equal(t, val, New(m).Get("nothing").Uint(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustUint()
+	})
+
+}
+
+func TestUintSlice(t *testing.T) {
+
+	val := uint(1)
+	m := map[string]interface{}{"value": []uint{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").UintSlice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustUintSlice()[0])
+	assert.Equal(t, []uint(nil), New(m).Get("nothing").UintSlice())
+	assert.Equal(t, val, New(m).Get("nothing").UintSlice([]uint{uint(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustUintSlice()
+	})
+
+}
+
+func TestIsUint(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: uint(1)}
+	assert.True(t, v.IsUint())
+
+	v = &Value{data: []uint{uint(1)}}
+	assert.True(t, v.IsUintSlice())
+
+}
+
+func TestEachUint(t *testing.T) {
+
+	v := &Value{data: []uint{uint(1), uint(1), uint(1), uint(1), uint(1)}}
+	count := 0
+	replacedVals := make([]uint, 0)
+	assert.Equal(t, v, v.EachUint(func(i int, val uint) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustUintSlice()[0])
+	assert.Equal(t, replacedVals[1], v.MustUintSlice()[1])
+	assert.Equal(t, replacedVals[2], v.MustUintSlice()[2])
+
+}
+
+func TestWhereUint(t *testing.T) {
+
+	v := &Value{data: []uint{uint(1), uint(1), uint(1), uint(1), uint(1), uint(1)}}
+
+	selected := v.WhereUint(func(i int, val uint) bool {
+		return i%2 == 0
+	}).MustUintSlice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupUint(t *testing.T) {
+
+	v := &Value{data: []uint{uint(1), uint(1), uint(1), uint(1), uint(1), uint(1)}}
+
+	grouped := v.GroupUint(func(i int, val uint) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]uint)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceUint(t *testing.T) {
+
+	v := &Value{data: []uint{uint(1), uint(1), uint(1), uint(1), uint(1), uint(1)}}
+
+	rawArr := v.MustUintSlice()
+
+	replaced := v.ReplaceUint(func(index int, val uint) uint {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustUintSlice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectUint(t *testing.T) {
+
+	v := &Value{data: []uint{uint(1), uint(1), uint(1), uint(1), uint(1), uint(1)}}
+
+	collected := v.CollectUint(func(index int, val uint) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestUint8(t *testing.T) {
+
+	val := uint8(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Uint8())
+	assert.Equal(t, val, New(m).Get("value").MustUint8())
+	assert.Equal(t, uint8(0), New(m).Get("nothing").Uint8())
+	assert.Equal(t, val, New(m).Get("nothing").Uint8(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustUint8()
+	})
+
+}
+
+func TestUint8Slice(t *testing.T) {
+
+	val := uint8(1)
+	m := map[string]interface{}{"value": []uint8{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Uint8Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustUint8Slice()[0])
+	assert.Equal(t, []uint8(nil), New(m).Get("nothing").Uint8Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Uint8Slice([]uint8{uint8(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustUint8Slice()
+	})
+
+}
+
+func TestIsUint8(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: uint8(1)}
+	assert.True(t, v.IsUint8())
+
+	v = &Value{data: []uint8{uint8(1)}}
+	assert.True(t, v.IsUint8Slice())
+
+}
+
+func TestEachUint8(t *testing.T) {
+
+	v := &Value{data: []uint8{uint8(1), uint8(1), uint8(1), uint8(1), uint8(1)}}
+	count := 0
+	replacedVals := make([]uint8, 0)
+	assert.Equal(t, v, v.EachUint8(func(i int, val uint8) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustUint8Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustUint8Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustUint8Slice()[2])
+
+}
+
+func TestWhereUint8(t *testing.T) {
+
+	v := &Value{data: []uint8{uint8(1), uint8(1), uint8(1), uint8(1), uint8(1), uint8(1)}}
+
+	selected := v.WhereUint8(func(i int, val uint8) bool {
+		return i%2 == 0
+	}).MustUint8Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupUint8(t *testing.T) {
+
+	v := &Value{data: []uint8{uint8(1), uint8(1), uint8(1), uint8(1), uint8(1), uint8(1)}}
+
+	grouped := v.GroupUint8(func(i int, val uint8) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]uint8)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceUint8(t *testing.T) {
+
+	v := &Value{data: []uint8{uint8(1), uint8(1), uint8(1), uint8(1), uint8(1), uint8(1)}}
+
+	rawArr := v.MustUint8Slice()
+
+	replaced := v.ReplaceUint8(func(index int, val uint8) uint8 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustUint8Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectUint8(t *testing.T) {
+
+	v := &Value{data: []uint8{uint8(1), uint8(1), uint8(1), uint8(1), uint8(1), uint8(1)}}
+
+	collected := v.CollectUint8(func(index int, val uint8) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestUint16(t *testing.T) {
+
+	val := uint16(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Uint16())
+	assert.Equal(t, val, New(m).Get("value").MustUint16())
+	assert.Equal(t, uint16(0), New(m).Get("nothing").Uint16())
+	assert.Equal(t, val, New(m).Get("nothing").Uint16(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustUint16()
+	})
+
+}
+
+func TestUint16Slice(t *testing.T) {
+
+	val := uint16(1)
+	m := map[string]interface{}{"value": []uint16{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Uint16Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustUint16Slice()[0])
+	assert.Equal(t, []uint16(nil), New(m).Get("nothing").Uint16Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Uint16Slice([]uint16{uint16(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustUint16Slice()
+	})
+
+}
+
+func TestIsUint16(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: uint16(1)}
+	assert.True(t, v.IsUint16())
+
+	v = &Value{data: []uint16{uint16(1)}}
+	assert.True(t, v.IsUint16Slice())
+
+}
+
+func TestEachUint16(t *testing.T) {
+
+	v := &Value{data: []uint16{uint16(1), uint16(1), uint16(1), uint16(1), uint16(1)}}
+	count := 0
+	replacedVals := make([]uint16, 0)
+	assert.Equal(t, v, v.EachUint16(func(i int, val uint16) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustUint16Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustUint16Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustUint16Slice()[2])
+
+}
+
+func TestWhereUint16(t *testing.T) {
+
+	v := &Value{data: []uint16{uint16(1), uint16(1), uint16(1), uint16(1), uint16(1), uint16(1)}}
+
+	selected := v.WhereUint16(func(i int, val uint16) bool {
+		return i%2 == 0
+	}).MustUint16Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupUint16(t *testing.T) {
+
+	v := &Value{data: []uint16{uint16(1), uint16(1), uint16(1), uint16(1), uint16(1), uint16(1)}}
+
+	grouped := v.GroupUint16(func(i int, val uint16) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]uint16)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceUint16(t *testing.T) {
+
+	v := &Value{data: []uint16{uint16(1), uint16(1), uint16(1), uint16(1), uint16(1), uint16(1)}}
+
+	rawArr := v.MustUint16Slice()
+
+	replaced := v.ReplaceUint16(func(index int, val uint16) uint16 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustUint16Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectUint16(t *testing.T) {
+
+	v := &Value{data: []uint16{uint16(1), uint16(1), uint16(1), uint16(1), uint16(1), uint16(1)}}
+
+	collected := v.CollectUint16(func(index int, val uint16) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestUint32(t *testing.T) {
+
+	val := uint32(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Uint32())
+	assert.Equal(t, val, New(m).Get("value").MustUint32())
+	assert.Equal(t, uint32(0), New(m).Get("nothing").Uint32())
+	assert.Equal(t, val, New(m).Get("nothing").Uint32(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustUint32()
+	})
+
+}
+
+func TestUint32Slice(t *testing.T) {
+
+	val := uint32(1)
+	m := map[string]interface{}{"value": []uint32{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Uint32Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustUint32Slice()[0])
+	assert.Equal(t, []uint32(nil), New(m).Get("nothing").Uint32Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Uint32Slice([]uint32{uint32(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustUint32Slice()
+	})
+
+}
+
+func TestIsUint32(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: uint32(1)}
+	assert.True(t, v.IsUint32())
+
+	v = &Value{data: []uint32{uint32(1)}}
+	assert.True(t, v.IsUint32Slice())
+
+}
+
+func TestEachUint32(t *testing.T) {
+
+	v := &Value{data: []uint32{uint32(1), uint32(1), uint32(1), uint32(1), uint32(1)}}
+	count := 0
+	replacedVals := make([]uint32, 0)
+	assert.Equal(t, v, v.EachUint32(func(i int, val uint32) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustUint32Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustUint32Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustUint32Slice()[2])
+
+}
+
+func TestWhereUint32(t *testing.T) {
+
+	v := &Value{data: []uint32{uint32(1), uint32(1), uint32(1), uint32(1), uint32(1), uint32(1)}}
+
+	selected := v.WhereUint32(func(i int, val uint32) bool {
+		return i%2 == 0
+	}).MustUint32Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupUint32(t *testing.T) {
+
+	v := &Value{data: []uint32{uint32(1), uint32(1), uint32(1), uint32(1), uint32(1), uint32(1)}}
+
+	grouped := v.GroupUint32(func(i int, val uint32) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]uint32)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceUint32(t *testing.T) {
+
+	v := &Value{data: []uint32{uint32(1), uint32(1), uint32(1), uint32(1), uint32(1), uint32(1)}}
+
+	rawArr := v.MustUint32Slice()
+
+	replaced := v.ReplaceUint32(func(index int, val uint32) uint32 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustUint32Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectUint32(t *testing.T) {
+
+	v := &Value{data: []uint32{uint32(1), uint32(1), uint32(1), uint32(1), uint32(1), uint32(1)}}
+
+	collected := v.CollectUint32(func(index int, val uint32) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestUint64(t *testing.T) {
+
+	val := uint64(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Uint64())
+	assert.Equal(t, val, New(m).Get("value").MustUint64())
+	assert.Equal(t, uint64(0), New(m).Get("nothing").Uint64())
+	assert.Equal(t, val, New(m).Get("nothing").Uint64(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustUint64()
+	})
+
+}
+
+func TestUint64Slice(t *testing.T) {
+
+	val := uint64(1)
+	m := map[string]interface{}{"value": []uint64{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Uint64Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustUint64Slice()[0])
+	assert.Equal(t, []uint64(nil), New(m).Get("nothing").Uint64Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Uint64Slice([]uint64{uint64(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustUint64Slice()
+	})
+
+}
+
+func TestIsUint64(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: uint64(1)}
+	assert.True(t, v.IsUint64())
+
+	v = &Value{data: []uint64{uint64(1)}}
+	assert.True(t, v.IsUint64Slice())
+
+}
+
+func TestEachUint64(t *testing.T) {
+
+	v := &Value{data: []uint64{uint64(1), uint64(1), uint64(1), uint64(1), uint64(1)}}
+	count := 0
+	replacedVals := make([]uint64, 0)
+	assert.Equal(t, v, v.EachUint64(func(i int, val uint64) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustUint64Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustUint64Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustUint64Slice()[2])
+
+}
+
+func TestWhereUint64(t *testing.T) {
+
+	v := &Value{data: []uint64{uint64(1), uint64(1), uint64(1), uint64(1), uint64(1), uint64(1)}}
+
+	selected := v.WhereUint64(func(i int, val uint64) bool {
+		return i%2 == 0
+	}).MustUint64Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupUint64(t *testing.T) {
+
+	v := &Value{data: []uint64{uint64(1), uint64(1), uint64(1), uint64(1), uint64(1), uint64(1)}}
+
+	grouped := v.GroupUint64(func(i int, val uint64) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]uint64)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceUint64(t *testing.T) {
+
+	v := &Value{data: []uint64{uint64(1), uint64(1), uint64(1), uint64(1), uint64(1), uint64(1)}}
+
+	rawArr := v.MustUint64Slice()
+
+	replaced := v.ReplaceUint64(func(index int, val uint64) uint64 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustUint64Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectUint64(t *testing.T) {
+
+	v := &Value{data: []uint64{uint64(1), uint64(1), uint64(1), uint64(1), uint64(1), uint64(1)}}
+
+	collected := v.CollectUint64(func(index int, val uint64) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestUintptr(t *testing.T) {
+
+	val := uintptr(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Uintptr())
+	assert.Equal(t, val, New(m).Get("value").MustUintptr())
+	assert.Equal(t, uintptr(0), New(m).Get("nothing").Uintptr())
+	assert.Equal(t, val, New(m).Get("nothing").Uintptr(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustUintptr()
+	})
+
+}
+
+func TestUintptrSlice(t *testing.T) {
+
+	val := uintptr(1)
+	m := map[string]interface{}{"value": []uintptr{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").UintptrSlice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustUintptrSlice()[0])
+	assert.Equal(t, []uintptr(nil), New(m).Get("nothing").UintptrSlice())
+	assert.Equal(t, val, New(m).Get("nothing").UintptrSlice([]uintptr{uintptr(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustUintptrSlice()
+	})
+
+}
+
+func TestIsUintptr(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: uintptr(1)}
+	assert.True(t, v.IsUintptr())
+
+	v = &Value{data: []uintptr{uintptr(1)}}
+	assert.True(t, v.IsUintptrSlice())
+
+}
+
+func TestEachUintptr(t *testing.T) {
+
+	v := &Value{data: []uintptr{uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1)}}
+	count := 0
+	replacedVals := make([]uintptr, 0)
+	assert.Equal(t, v, v.EachUintptr(func(i int, val uintptr) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustUintptrSlice()[0])
+	assert.Equal(t, replacedVals[1], v.MustUintptrSlice()[1])
+	assert.Equal(t, replacedVals[2], v.MustUintptrSlice()[2])
+
+}
+
+func TestWhereUintptr(t *testing.T) {
+
+	v := &Value{data: []uintptr{uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1)}}
+
+	selected := v.WhereUintptr(func(i int, val uintptr) bool {
+		return i%2 == 0
+	}).MustUintptrSlice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupUintptr(t *testing.T) {
+
+	v := &Value{data: []uintptr{uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1)}}
+
+	grouped := v.GroupUintptr(func(i int, val uintptr) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]uintptr)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceUintptr(t *testing.T) {
+
+	v := &Value{data: []uintptr{uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1)}}
+
+	rawArr := v.MustUintptrSlice()
+
+	replaced := v.ReplaceUintptr(func(index int, val uintptr) uintptr {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustUintptrSlice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectUintptr(t *testing.T) {
+
+	v := &Value{data: []uintptr{uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1), uintptr(1)}}
+
+	collected := v.CollectUintptr(func(index int, val uintptr) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestFloat32(t *testing.T) {
+
+	val := float32(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Float32())
+	assert.Equal(t, val, New(m).Get("value").MustFloat32())
+	assert.Equal(t, float32(0), New(m).Get("nothing").Float32())
+	assert.Equal(t, val, New(m).Get("nothing").Float32(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustFloat32()
+	})
+
+}
+
+func TestFloat32Slice(t *testing.T) {
+
+	val := float32(1)
+	m := map[string]interface{}{"value": []float32{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Float32Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustFloat32Slice()[0])
+	assert.Equal(t, []float32(nil), New(m).Get("nothing").Float32Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Float32Slice([]float32{float32(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustFloat32Slice()
+	})
+
+}
+
+func TestIsFloat32(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: float32(1)}
+	assert.True(t, v.IsFloat32())
+
+	v = &Value{data: []float32{float32(1)}}
+	assert.True(t, v.IsFloat32Slice())
+
+}
+
+func TestEachFloat32(t *testing.T) {
+
+	v := &Value{data: []float32{float32(1), float32(1), float32(1), float32(1), float32(1)}}
+	count := 0
+	replacedVals := make([]float32, 0)
+	assert.Equal(t, v, v.EachFloat32(func(i int, val float32) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustFloat32Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustFloat32Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustFloat32Slice()[2])
+
+}
+
+func TestWhereFloat32(t *testing.T) {
+
+	v := &Value{data: []float32{float32(1), float32(1), float32(1), float32(1), float32(1), float32(1)}}
+
+	selected := v.WhereFloat32(func(i int, val float32) bool {
+		return i%2 == 0
+	}).MustFloat32Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupFloat32(t *testing.T) {
+
+	v := &Value{data: []float32{float32(1), float32(1), float32(1), float32(1), float32(1), float32(1)}}
+
+	grouped := v.GroupFloat32(func(i int, val float32) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]float32)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceFloat32(t *testing.T) {
+
+	v := &Value{data: []float32{float32(1), float32(1), float32(1), float32(1), float32(1), float32(1)}}
+
+	rawArr := v.MustFloat32Slice()
+
+	replaced := v.ReplaceFloat32(func(index int, val float32) float32 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustFloat32Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectFloat32(t *testing.T) {
+
+	v := &Value{data: []float32{float32(1), float32(1), float32(1), float32(1), float32(1), float32(1)}}
+
+	collected := v.CollectFloat32(func(index int, val float32) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestFloat64(t *testing.T) {
+
+	val := float64(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Float64())
+	assert.Equal(t, val, New(m).Get("value").MustFloat64())
+	assert.Equal(t, float64(0), New(m).Get("nothing").Float64())
+	assert.Equal(t, val, New(m).Get("nothing").Float64(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustFloat64()
+	})
+
+}
+
+func TestFloat64Slice(t *testing.T) {
+
+	val := float64(1)
+	m := map[string]interface{}{"value": []float64{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Float64Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustFloat64Slice()[0])
+	assert.Equal(t, []float64(nil), New(m).Get("nothing").Float64Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Float64Slice([]float64{float64(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustFloat64Slice()
+	})
+
+}
+
+func TestIsFloat64(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: float64(1)}
+	assert.True(t, v.IsFloat64())
+
+	v = &Value{data: []float64{float64(1)}}
+	assert.True(t, v.IsFloat64Slice())
+
+}
+
+func TestEachFloat64(t *testing.T) {
+
+	v := &Value{data: []float64{float64(1), float64(1), float64(1), float64(1), float64(1)}}
+	count := 0
+	replacedVals := make([]float64, 0)
+	assert.Equal(t, v, v.EachFloat64(func(i int, val float64) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustFloat64Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustFloat64Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustFloat64Slice()[2])
+
+}
+
+func TestWhereFloat64(t *testing.T) {
+
+	v := &Value{data: []float64{float64(1), float64(1), float64(1), float64(1), float64(1), float64(1)}}
+
+	selected := v.WhereFloat64(func(i int, val float64) bool {
+		return i%2 == 0
+	}).MustFloat64Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupFloat64(t *testing.T) {
+
+	v := &Value{data: []float64{float64(1), float64(1), float64(1), float64(1), float64(1), float64(1)}}
+
+	grouped := v.GroupFloat64(func(i int, val float64) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]float64)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceFloat64(t *testing.T) {
+
+	v := &Value{data: []float64{float64(1), float64(1), float64(1), float64(1), float64(1), float64(1)}}
+
+	rawArr := v.MustFloat64Slice()
+
+	replaced := v.ReplaceFloat64(func(index int, val float64) float64 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustFloat64Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectFloat64(t *testing.T) {
+
+	v := &Value{data: []float64{float64(1), float64(1), float64(1), float64(1), float64(1), float64(1)}}
+
+	collected := v.CollectFloat64(func(index int, val float64) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestComplex64(t *testing.T) {
+
+	val := complex64(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Complex64())
+	assert.Equal(t, val, New(m).Get("value").MustComplex64())
+	assert.Equal(t, complex64(0), New(m).Get("nothing").Complex64())
+	assert.Equal(t, val, New(m).Get("nothing").Complex64(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustComplex64()
+	})
+
+}
+
+func TestComplex64Slice(t *testing.T) {
+
+	val := complex64(1)
+	m := map[string]interface{}{"value": []complex64{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Complex64Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustComplex64Slice()[0])
+	assert.Equal(t, []complex64(nil), New(m).Get("nothing").Complex64Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Complex64Slice([]complex64{complex64(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustComplex64Slice()
+	})
+
+}
+
+func TestIsComplex64(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: complex64(1)}
+	assert.True(t, v.IsComplex64())
+
+	v = &Value{data: []complex64{complex64(1)}}
+	assert.True(t, v.IsComplex64Slice())
+
+}
+
+func TestEachComplex64(t *testing.T) {
+
+	v := &Value{data: []complex64{complex64(1), complex64(1), complex64(1), complex64(1), complex64(1)}}
+	count := 0
+	replacedVals := make([]complex64, 0)
+	assert.Equal(t, v, v.EachComplex64(func(i int, val complex64) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustComplex64Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustComplex64Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustComplex64Slice()[2])
+
+}
+
+func TestWhereComplex64(t *testing.T) {
+
+	v := &Value{data: []complex64{complex64(1), complex64(1), complex64(1), complex64(1), complex64(1), complex64(1)}}
+
+	selected := v.WhereComplex64(func(i int, val complex64) bool {
+		return i%2 == 0
+	}).MustComplex64Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupComplex64(t *testing.T) {
+
+	v := &Value{data: []complex64{complex64(1), complex64(1), complex64(1), complex64(1), complex64(1), complex64(1)}}
+
+	grouped := v.GroupComplex64(func(i int, val complex64) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]complex64)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceComplex64(t *testing.T) {
+
+	v := &Value{data: []complex64{complex64(1), complex64(1), complex64(1), complex64(1), complex64(1), complex64(1)}}
+
+	rawArr := v.MustComplex64Slice()
+
+	replaced := v.ReplaceComplex64(func(index int, val complex64) complex64 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustComplex64Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectComplex64(t *testing.T) {
+
+	v := &Value{data: []complex64{complex64(1), complex64(1), complex64(1), complex64(1), complex64(1), complex64(1)}}
+
+	collected := v.CollectComplex64(func(index int, val complex64) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func TestComplex128(t *testing.T) {
+
+	val := complex128(1)
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Complex128())
+	assert.Equal(t, val, New(m).Get("value").MustComplex128())
+	assert.Equal(t, complex128(0), New(m).Get("nothing").Complex128())
+	assert.Equal(t, val, New(m).Get("nothing").Complex128(1))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").MustComplex128()
+	})
+
+}
+
+func TestComplex128Slice(t *testing.T) {
+
+	val := complex128(1)
+	m := map[string]interface{}{"value": []complex128{val}, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").Complex128Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").MustComplex128Slice()[0])
+	assert.Equal(t, []complex128(nil), New(m).Get("nothing").Complex128Slice())
+	assert.Equal(t, val, New(m).Get("nothing").Complex128Slice([]complex128{complex128(1)})[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").MustComplex128Slice()
+	})
+
+}
+
+func TestIsComplex128(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: complex128(1)}
+	assert.True(t, v.IsComplex128())
+
+	v = &Value{data: []complex128{complex128(1)}}
+	assert.True(t, v.IsComplex128Slice())
+
+}
+
+func TestEachComplex128(t *testing.T) {
+
+	v := &Value{data: []complex128{complex128(1), complex128(1), complex128(1), complex128(1), complex128(1)}}
+	count := 0
+	replacedVals := make([]complex128, 0)
+	assert.Equal(t, v, v.EachComplex128(func(i int, val complex128) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.MustComplex128Slice()[0])
+	assert.Equal(t, replacedVals[1], v.MustComplex128Slice()[1])
+	assert.Equal(t, replacedVals[2], v.MustComplex128Slice()[2])
+
+}
+
+func TestWhereComplex128(t *testing.T) {
+
+	v := &Value{data: []complex128{complex128(1), complex128(1), complex128(1), complex128(1), complex128(1), complex128(1)}}
+
+	selected := v.WhereComplex128(func(i int, val complex128) bool {
+		return i%2 == 0
+	}).MustComplex128Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroupComplex128(t *testing.T) {
+
+	v := &Value{data: []complex128{complex128(1), complex128(1), complex128(1), complex128(1), complex128(1), complex128(1)}}
+
+	grouped := v.GroupComplex128(func(i int, val complex128) string {
+		return fmt.Sprintf("%v", i%2 == 0)
+	}).data.(map[string][]complex128)
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplaceComplex128(t *testing.T) {
+
+	v := &Value{data: []complex128{complex128(1), complex128(1), complex128(1), complex128(1), complex128(1), complex128(1)}}
+
+	rawArr := v.MustComplex128Slice()
+
+	replaced := v.ReplaceComplex128(func(index int, val complex128) complex128 {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.MustComplex128Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollectComplex128(t *testing.T) {
+
+	v := &Value{data: []complex128{complex128(1), complex128(1), complex128(1), complex128(1), complex128(1), complex128(1)}}
+
+	collected := v.CollectComplex128(func(index int, val complex128) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
diff --git a/go/src/github.com/stretchr/objx/value.go b/go/src/github.com/stretchr/objx/value.go
new file mode 100644
index 0000000..956a221
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/value.go
@@ -0,0 +1,56 @@
+package objx
+
+import (
+	"fmt"
+	"strconv"
+)
+
+// Value provides methods for extracting interface{} data in various
+// types.
+type Value struct {
+	// data contains the raw data being managed by this Value
+	data interface{}
+}
+
+// Data returns the raw data contained by this Value
+func (v *Value) Data() interface{} {
+	return v.data
+}
+
+// String returns the value always as a string
+func (v *Value) String() string {
+	switch {
+	case v.IsStr():
+		return v.Str()
+	case v.IsBool():
+		return strconv.FormatBool(v.Bool())
+	case v.IsFloat32():
+		return strconv.FormatFloat(float64(v.Float32()), 'f', -1, 32)
+	case v.IsFloat64():
+		return strconv.FormatFloat(v.Float64(), 'f', -1, 64)
+	case v.IsInt():
+		return strconv.FormatInt(int64(v.Int()), 10)
+	case v.IsInt():
+		return strconv.FormatInt(int64(v.Int()), 10)
+	case v.IsInt8():
+		return strconv.FormatInt(int64(v.Int8()), 10)
+	case v.IsInt16():
+		return strconv.FormatInt(int64(v.Int16()), 10)
+	case v.IsInt32():
+		return strconv.FormatInt(int64(v.Int32()), 10)
+	case v.IsInt64():
+		return strconv.FormatInt(v.Int64(), 10)
+	case v.IsUint():
+		return strconv.FormatUint(uint64(v.Uint()), 10)
+	case v.IsUint8():
+		return strconv.FormatUint(uint64(v.Uint8()), 10)
+	case v.IsUint16():
+		return strconv.FormatUint(uint64(v.Uint16()), 10)
+	case v.IsUint32():
+		return strconv.FormatUint(uint64(v.Uint32()), 10)
+	case v.IsUint64():
+		return strconv.FormatUint(v.Uint64(), 10)
+	}
+
+	return fmt.Sprintf("%#v", v.Data())
+}
diff --git a/go/src/github.com/stretchr/objx/value_test.go b/go/src/github.com/stretchr/objx/value_test.go
new file mode 100644
index 0000000..5214058
--- /dev/null
+++ b/go/src/github.com/stretchr/objx/value_test.go
@@ -0,0 +1,66 @@
+package objx
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestStringTypeString(t *testing.T) {
+	m := New(map[string]interface{}{"string": "foo"})
+	assert.Equal(t, "foo", m.Get("string").String())
+}
+
+func TestStringTypeBool(t *testing.T) {
+	m := New(map[string]interface{}{"bool": true})
+	assert.Equal(t, "true", m.Get("bool").String())
+}
+
+func TestStringTypeInt(t *testing.T) {
+	m := New(map[string]interface{}{
+		"int":   int(1),
+		"int8":  int8(8),
+		"int16": int16(16),
+		"int32": int32(32),
+		"int64": int64(64),
+	})
+
+	assert.Equal(t, "1", m.Get("int").String())
+	assert.Equal(t, "8", m.Get("int8").String())
+	assert.Equal(t, "16", m.Get("int16").String())
+	assert.Equal(t, "32", m.Get("int32").String())
+	assert.Equal(t, "64", m.Get("int64").String())
+}
+
+func TestStringTypeUint(t *testing.T) {
+	m := New(map[string]interface{}{
+		"uint":   uint(1),
+		"uint8":  uint8(8),
+		"uint16": uint16(16),
+		"uint32": uint32(32),
+		"uint64": uint64(64),
+	})
+
+	assert.Equal(t, "1", m.Get("uint").String())
+	assert.Equal(t, "8", m.Get("uint8").String())
+	assert.Equal(t, "16", m.Get("uint16").String())
+	assert.Equal(t, "32", m.Get("uint32").String())
+	assert.Equal(t, "64", m.Get("uint64").String())
+}
+
+func TestStringTypeFloat(t *testing.T) {
+	m := New(map[string]interface{}{
+		"float32": float32(32.32),
+		"float64": float64(64.64),
+	})
+
+	assert.Equal(t, "32.32", m.Get("float32").String())
+	assert.Equal(t, "64.64", m.Get("float64").String())
+}
+
+func TestStringTypeOther(t *testing.T) {
+	m := New(map[string]interface{}{
+		"other": []string{"foo", "bar"},
+	})
+
+	assert.Equal(t, "[]string{\"foo\", \"bar\"}", m.Get("other").String())
+}
diff --git a/go/src/github.com/stretchr/testify/.gitignore b/go/src/github.com/stretchr/testify/.gitignore
new file mode 100644
index 0000000..5aacdb7
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/.gitignore
@@ -0,0 +1,24 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+
+.DS_Store
diff --git a/go/src/github.com/stretchr/testify/.travis.yml b/go/src/github.com/stretchr/testify/.travis.yml
new file mode 100644
index 0000000..455923e
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/.travis.yml
@@ -0,0 +1,15 @@
+language: go
+
+sudo: false
+
+go:
+  - 1.1
+  - 1.2
+  - 1.3
+  - 1.4
+  - 1.5
+  - 1.6
+  - tip
+
+script:
+  - go test -v ./...
diff --git a/go/src/github.com/stretchr/testify/Godeps/Godeps.json b/go/src/github.com/stretchr/testify/Godeps/Godeps.json
new file mode 100644
index 0000000..5069ce0
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/Godeps/Godeps.json
@@ -0,0 +1,21 @@
+{
+	"ImportPath": "github.com/stretchr/testify",
+	"GoVersion": "go1.5",
+	"Packages": [
+		"./..."
+	],
+	"Deps": [
+		{
+			"ImportPath": "github.com/davecgh/go-spew/spew",
+			"Rev": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d"
+		},
+		{
+			"ImportPath": "github.com/pmezard/go-difflib/difflib",
+			"Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d"
+		},
+		{
+			"ImportPath": "github.com/stretchr/objx",
+			"Rev": "cbeaeb16a013161a98496fad62933b1d21786672"
+		}
+	]
+}
diff --git a/go/src/github.com/stretchr/testify/Godeps/Readme b/go/src/github.com/stretchr/testify/Godeps/Readme
new file mode 100644
index 0000000..4cdaa53
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/Godeps/Readme
@@ -0,0 +1,5 @@
+This directory tree is generated automatically by godep.
+
+Please do not edit.
+
+See https://github.com/tools/godep for more information.
diff --git a/go/src/github.com/stretchr/testify/LICENCE.txt b/go/src/github.com/stretchr/testify/LICENCE.txt
new file mode 100644
index 0000000..473b670
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/LICENCE.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
+
+Please consider promoting this project if you find it useful.
+
+Permission is hereby granted, free of charge, to any person 
+obtaining a copy of this software and associated documentation 
+files (the "Software"), to deal in the Software without restriction, 
+including without limitation the rights to use, copy, modify, merge, 
+publish, distribute, sublicense, and/or sell copies of the Software, 
+and to permit persons to whom the Software is furnished to do so, 
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 
+OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/go/src/github.com/stretchr/testify/LICENSE b/go/src/github.com/stretchr/testify/LICENSE
new file mode 100644
index 0000000..473b670
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
+
+Please consider promoting this project if you find it useful.
+
+Permission is hereby granted, free of charge, to any person 
+obtaining a copy of this software and associated documentation 
+files (the "Software"), to deal in the Software without restriction, 
+including without limitation the rights to use, copy, modify, merge, 
+publish, distribute, sublicense, and/or sell copies of the Software, 
+and to permit persons to whom the Software is furnished to do so, 
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 
+OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/go/src/github.com/stretchr/testify/README.google b/go/src/github.com/stretchr/testify/README.google
new file mode 100644
index 0000000..ca19146
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/README.google
@@ -0,0 +1,11 @@
+URL: https://github.com/stretchr/testify/archive/6cb3b85ef5a0efef77caef88363ec4d4b5c0976d.zip
+Version: 6cb3b85ef5a0efef77caef88363ec4d4b5c0976d
+License: MIT
+License File: LICENSE
+
+Description:
+Go code (golang) set of packages that provide many tools for testifying that
+your code will behave as you intend.
+
+Local Modifications:
+None.
diff --git a/go/src/github.com/stretchr/testify/README.md b/go/src/github.com/stretchr/testify/README.md
new file mode 100644
index 0000000..aaf2aa0
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/README.md
@@ -0,0 +1,332 @@
+Testify - Thou Shalt Write Tests
+================================
+
+[![Build Status](https://travis-ci.org/stretchr/testify.svg)](https://travis-ci.org/stretchr/testify)
+
+Go code (golang) set of packages that provide many tools for testifying that your code will behave as you intend.
+
+Features include:
+
+  * [Easy assertions](#assert-package)
+  * [Mocking](#mock-package)
+  * [HTTP response trapping](#http-package)
+  * [Testing suite interfaces and functions](#suite-package)
+
+Get started:
+
+  * Install testify with [one line of code](#installation), or [update it with another](#staying-up-to-date)
+  * For an introduction to writing test code in Go, see http://golang.org/doc/code.html#Testing
+  * Check out the API Documentation http://godoc.org/github.com/stretchr/testify
+  * To make your testing life easier, check out our other project, [gorc](http://github.com/stretchr/gorc)
+  * A little about [Test-Driven Development (TDD)](http://en.wikipedia.org/wiki/Test-driven_development)
+
+
+
+[`assert`](http://godoc.org/github.com/stretchr/testify/assert "API documentation") package
+-------------------------------------------------------------------------------------------
+
+The `assert` package provides some helpful methods that allow you to write better test code in Go.
+
+  * Prints friendly, easy to read failure descriptions
+  * Allows for very readable code
+  * Optionally annotate each assertion with a message
+
+See it in action:
+
+```go
+package yours
+
+import (
+  "testing"
+  "github.com/stretchr/testify/assert"
+)
+
+func TestSomething(t *testing.T) {
+
+  // assert equality
+  assert.Equal(t, 123, 123, "they should be equal")
+
+  // assert inequality
+  assert.NotEqual(t, 123, 456, "they should not be equal")
+
+  // assert for nil (good for errors)
+  assert.Nil(t, object)
+
+  // assert for not nil (good when you expect something)
+  if assert.NotNil(t, object) {
+
+    // now we know that object isn't nil, we are safe to make
+    // further assertions without causing any errors
+    assert.Equal(t, "Something", object.Value)
+
+  }
+
+}
+```
+
+  * Every assert func takes the `testing.T` object as the first argument.  This is how it writes the errors out through the normal `go test` capabilities.
+  * Every assert func returns a bool indicating whether the assertion was successful or not, this is useful for if you want to go on making further assertions under certain conditions.
+
+if you assert many times, use the below:
+
+```go
+package yours
+
+import (
+  "testing"
+  "github.com/stretchr/testify/assert"
+)
+
+func TestSomething(t *testing.T) {
+  assert := assert.New(t)
+
+  // assert equality
+  assert.Equal(123, 123, "they should be equal")
+
+  // assert inequality
+  assert.NotEqual(123, 456, "they should not be equal")
+
+  // assert for nil (good for errors)
+  assert.Nil(object)
+
+  // assert for not nil (good when you expect something)
+  if assert.NotNil(object) {
+
+    // now we know that object isn't nil, we are safe to make
+    // further assertions without causing any errors
+    assert.Equal("Something", object.Value)
+  }
+}
+```
+
+[`require`](http://godoc.org/github.com/stretchr/testify/require "API documentation") package
+---------------------------------------------------------------------------------------------
+
+The `require` package provides same global functions as the `assert` package, but instead of returning a boolean result they terminate current test.
+
+See [t.FailNow](http://golang.org/pkg/testing/#T.FailNow) for details.
+
+
+[`http`](http://godoc.org/github.com/stretchr/testify/http "API documentation") package
+---------------------------------------------------------------------------------------
+
+The `http` package contains test objects useful for testing code that relies on the `net/http` package.  Check out the [(deprecated) API documentation for the `http` package](http://godoc.org/github.com/stretchr/testify/http).
+
+We recommend you use [httptest](http://golang.org/pkg/net/http/httptest) instead.
+
+[`mock`](http://godoc.org/github.com/stretchr/testify/mock "API documentation") package
+----------------------------------------------------------------------------------------
+
+The `mock` package provides a mechanism for easily writing mock objects that can be used in place of real objects when writing test code.
+
+An example test function that tests a piece of code that relies on an external object `testObj`, can setup expectations (testify) and assert that they indeed happened:
+
+```go
+package yours
+
+import (
+  "testing"
+  "github.com/stretchr/testify/mock"
+)
+
+/*
+  Test objects
+*/
+
+// MyMockedObject is a mocked object that implements an interface
+// that describes an object that the code I am testing relies on.
+type MyMockedObject struct{
+  mock.Mock
+}
+
+// DoSomething is a method on MyMockedObject that implements some interface
+// and just records the activity, and returns what the Mock object tells it to.
+//
+// In the real object, this method would do something useful, but since this
+// is a mocked object - we're just going to stub it out.
+//
+// NOTE: This method is not being tested here, code that uses this object is.
+func (m *MyMockedObject) DoSomething(number int) (bool, error) {
+
+  args := m.Called(number)
+  return args.Bool(0), args.Error(1)
+
+}
+
+/*
+  Actual test functions
+*/
+
+// TestSomething is an example of how to use our test object to
+// make assertions about some target code we are testing.
+func TestSomething(t *testing.T) {
+
+  // create an instance of our test object
+  testObj := new(MyMockedObject)
+
+  // setup expectations
+  testObj.On("DoSomething", 123).Return(true, nil)
+
+  // call the code we are testing
+  targetFuncThatDoesSomethingWithObj(testObj)
+
+  // assert that the expectations were met
+  testObj.AssertExpectations(t)
+
+}
+```
+
+For more information on how to write mock code, check out the [API documentation for the `mock` package](http://godoc.org/github.com/stretchr/testify/mock).
+
+You can use the [mockery tool](http://github.com/vektra/mockery) to autogenerate the mock code against an interface as well, making using mocks much quicker.
+
+[`suite`](http://godoc.org/github.com/stretchr/testify/suite "API documentation") package
+-----------------------------------------------------------------------------------------
+
+The `suite` package provides functionality that you might be used to from more common object oriented languages.  With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal.
+
+An example suite is shown below:
+
+```go
+// Basic imports
+import (
+    "testing"
+    "github.com/stretchr/testify/assert"
+    "github.com/stretchr/testify/suite"
+)
+
+// Define the suite, and absorb the built-in basic suite
+// functionality from testify - including a T() method which
+// returns the current testing context
+type ExampleTestSuite struct {
+    suite.Suite
+    VariableThatShouldStartAtFive int
+}
+
+// Make sure that VariableThatShouldStartAtFive is set to five
+// before each test
+func (suite *ExampleTestSuite) SetupTest() {
+    suite.VariableThatShouldStartAtFive = 5
+}
+
+// All methods that begin with "Test" are run as tests within a
+// suite.
+func (suite *ExampleTestSuite) TestExample() {
+    assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
+}
+
+// In order for 'go test' to run this suite, we need to create
+// a normal test function and pass our suite to suite.Run
+func TestExampleTestSuite(t *testing.T) {
+    suite.Run(t, new(ExampleTestSuite))
+}
+```
+
+For a more complete example, using all of the functionality provided by the suite package, look at our [example testing suite](https://github.com/stretchr/testify/blob/master/suite/suite_test.go)
+
+For more information on writing suites, check out the [API documentation for the `suite` package](http://godoc.org/github.com/stretchr/testify/suite).
+
+`Suite` object has assertion methods:
+
+```go
+// Basic imports
+import (
+    "testing"
+    "github.com/stretchr/testify/suite"
+)
+
+// Define the suite, and absorb the built-in basic suite
+// functionality from testify - including assertion methods.
+type ExampleTestSuite struct {
+    suite.Suite
+    VariableThatShouldStartAtFive int
+}
+
+// Make sure that VariableThatShouldStartAtFive is set to five
+// before each test
+func (suite *ExampleTestSuite) SetupTest() {
+    suite.VariableThatShouldStartAtFive = 5
+}
+
+// All methods that begin with "Test" are run as tests within a
+// suite.
+func (suite *ExampleTestSuite) TestExample() {
+    suite.Equal(suite.VariableThatShouldStartAtFive, 5)
+}
+
+// In order for 'go test' to run this suite, we need to create
+// a normal test function and pass our suite to suite.Run
+func TestExampleTestSuite(t *testing.T) {
+    suite.Run(t, new(ExampleTestSuite))
+}
+```
+
+------
+
+Installation
+============
+
+To install Testify, use `go get`:
+
+    * Latest version: go get github.com/stretchr/testify
+    * Specific version: go get gopkg.in/stretchr/testify.v1
+
+This will then make the following packages available to you:
+
+    github.com/stretchr/testify/assert
+    github.com/stretchr/testify/mock
+    github.com/stretchr/testify/http
+
+Import the `testify/assert` package into your code using this template:
+
+```go
+package yours
+
+import (
+  "testing"
+  "github.com/stretchr/testify/assert"
+)
+
+func TestSomething(t *testing.T) {
+
+  assert.True(t, true, "True is true!")
+
+}
+```
+
+------
+
+Staying up to date
+==================
+
+To update Testify to the latest version, use `go get -u github.com/stretchr/testify`.
+
+------
+
+Version History
+===============
+
+   * 1.0 - New package versioning strategy adopted.
+
+------
+
+Contributing
+============
+
+Please feel free to submit issues, fork the repository and send pull requests!
+
+When submitting an issue, we ask that you please include a complete test function that demonstrates the issue.  Extra credit for those using Testify to write the test code that demonstrates it.
+
+------
+
+Licence
+=======
+Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
+
+Please consider promoting this project if you find it useful.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/go/src/github.com/stretchr/testify/_codegen/main.go b/go/src/github.com/stretchr/testify/_codegen/main.go
new file mode 100644
index 0000000..328009f
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/_codegen/main.go
@@ -0,0 +1,287 @@
+// This program reads all assertion functions from the assert package and
+// automatically generates the corersponding requires and forwarded assertions
+
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/build"
+	"go/doc"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"path"
+	"strings"
+	"text/template"
+
+	"github.com/ernesto-jimenez/gogen/imports"
+)
+
+var (
+	pkg       = flag.String("assert-path", "github.com/stretchr/testify/assert", "Path to the assert package")
+	outputPkg = flag.String("output-package", "", "package for the resulting code")
+	tmplFile  = flag.String("template", "", "What file to load the function template from")
+	out       = flag.String("out", "", "What file to write the source code to")
+)
+
+func main() {
+	flag.Parse()
+
+	scope, docs, err := parsePackageSource(*pkg)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	importer, funcs, err := analyzeCode(scope, docs)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	if err := generateCode(importer, funcs); err != nil {
+		log.Fatal(err)
+	}
+}
+
+func generateCode(importer imports.Importer, funcs []testFunc) error {
+	buff := bytes.NewBuffer(nil)
+
+	tmplHead, tmplFunc, err := parseTemplates()
+	if err != nil {
+		return err
+	}
+
+	// Generate header
+	if err := tmplHead.Execute(buff, struct {
+		Name    string
+		Imports map[string]string
+	}{
+		*outputPkg,
+		importer.Imports(),
+	}); err != nil {
+		return err
+	}
+
+	// Generate funcs
+	for _, fn := range funcs {
+		buff.Write([]byte("\n\n"))
+		if err := tmplFunc.Execute(buff, &fn); err != nil {
+			return err
+		}
+	}
+
+	// Write file
+	output, err := outputFile()
+	if err != nil {
+		return err
+	}
+	defer output.Close()
+	_, err = io.Copy(output, buff)
+	return err
+}
+
+func parseTemplates() (*template.Template, *template.Template, error) {
+	tmplHead, err := template.New("header").Parse(headerTemplate)
+	if err != nil {
+		return nil, nil, err
+	}
+	if *tmplFile != "" {
+		f, err := ioutil.ReadFile(*tmplFile)
+		if err != nil {
+			return nil, nil, err
+		}
+		funcTemplate = string(f)
+	}
+	tmpl, err := template.New("function").Parse(funcTemplate)
+	if err != nil {
+		return nil, nil, err
+	}
+	return tmplHead, tmpl, nil
+}
+
+func outputFile() (*os.File, error) {
+	filename := *out
+	if filename == "-" || (filename == "" && *tmplFile == "") {
+		return os.Stdout, nil
+	}
+	if filename == "" {
+		filename = strings.TrimSuffix(strings.TrimSuffix(*tmplFile, ".tmpl"), ".go") + ".go"
+	}
+	return os.Create(filename)
+}
+
+// analyzeCode takes the types scope and the docs and returns the import
+// information and information about all the assertion functions.
+func analyzeCode(scope *types.Scope, docs *doc.Package) (imports.Importer, []testFunc, error) {
+	testingT := scope.Lookup("TestingT").Type().Underlying().(*types.Interface)
+
+	importer := imports.New(*outputPkg)
+	var funcs []testFunc
+	// Go through all the top level functions
+	for _, fdocs := range docs.Funcs {
+		// Find the function
+		obj := scope.Lookup(fdocs.Name)
+
+		fn, ok := obj.(*types.Func)
+		if !ok {
+			continue
+		}
+		// Check function signatuer has at least two arguments
+		sig := fn.Type().(*types.Signature)
+		if sig.Params().Len() < 2 {
+			continue
+		}
+		// Check first argument is of type testingT
+		first, ok := sig.Params().At(0).Type().(*types.Named)
+		if !ok {
+			continue
+		}
+		firstType, ok := first.Underlying().(*types.Interface)
+		if !ok {
+			continue
+		}
+		if !types.Implements(firstType, testingT) {
+			continue
+		}
+
+		funcs = append(funcs, testFunc{*outputPkg, fdocs, fn})
+		importer.AddImportsFrom(sig.Params())
+	}
+	return importer, funcs, nil
+}
+
+// parsePackageSource returns the types scope and the package documentation from the pa
+func parsePackageSource(pkg string) (*types.Scope, *doc.Package, error) {
+	pd, err := build.Import(pkg, ".", 0)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	fset := token.NewFileSet()
+	files := make(map[string]*ast.File)
+	fileList := make([]*ast.File, len(pd.GoFiles))
+	for i, fname := range pd.GoFiles {
+		src, err := ioutil.ReadFile(path.Join(pd.SrcRoot, pd.ImportPath, fname))
+		if err != nil {
+			return nil, nil, err
+		}
+		f, err := parser.ParseFile(fset, fname, src, parser.ParseComments|parser.AllErrors)
+		if err != nil {
+			return nil, nil, err
+		}
+		files[fname] = f
+		fileList[i] = f
+	}
+
+	cfg := types.Config{
+		Importer: importer.Default(),
+	}
+	info := types.Info{
+		Defs: make(map[*ast.Ident]types.Object),
+	}
+	tp, err := cfg.Check(pkg, fset, fileList, &info)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	scope := tp.Scope()
+
+	ap, _ := ast.NewPackage(fset, files, nil, nil)
+	docs := doc.New(ap, pkg, 0)
+
+	return scope, docs, nil
+}
+
+type testFunc struct {
+	CurrentPkg string
+	DocInfo    *doc.Func
+	TypeInfo   *types.Func
+}
+
+func (f *testFunc) Qualifier(p *types.Package) string {
+	if p == nil || p.Name() == f.CurrentPkg {
+		return ""
+	}
+	return p.Name()
+}
+
+func (f *testFunc) Params() string {
+	sig := f.TypeInfo.Type().(*types.Signature)
+	params := sig.Params()
+	p := ""
+	comma := ""
+	to := params.Len()
+	var i int
+
+	if sig.Variadic() {
+		to--
+	}
+	for i = 1; i < to; i++ {
+		param := params.At(i)
+		p += fmt.Sprintf("%s%s %s", comma, param.Name(), types.TypeString(param.Type(), f.Qualifier))
+		comma = ", "
+	}
+	if sig.Variadic() {
+		param := params.At(params.Len() - 1)
+		p += fmt.Sprintf("%s%s ...%s", comma, param.Name(), types.TypeString(param.Type().(*types.Slice).Elem(), f.Qualifier))
+	}
+	return p
+}
+
+func (f *testFunc) ForwardedParams() string {
+	sig := f.TypeInfo.Type().(*types.Signature)
+	params := sig.Params()
+	p := ""
+	comma := ""
+	to := params.Len()
+	var i int
+
+	if sig.Variadic() {
+		to--
+	}
+	for i = 1; i < to; i++ {
+		param := params.At(i)
+		p += fmt.Sprintf("%s%s", comma, param.Name())
+		comma = ", "
+	}
+	if sig.Variadic() {
+		param := params.At(params.Len() - 1)
+		p += fmt.Sprintf("%s%s...", comma, param.Name())
+	}
+	return p
+}
+
+func (f *testFunc) Comment() string {
+	return "// " + strings.Replace(strings.TrimSpace(f.DocInfo.Doc), "\n", "\n// ", -1)
+}
+
+func (f *testFunc) CommentWithoutT(receiver string) string {
+	search := fmt.Sprintf("assert.%s(t, ", f.DocInfo.Name)
+	replace := fmt.Sprintf("%s.%s(", receiver, f.DocInfo.Name)
+	return strings.Replace(f.Comment(), search, replace, -1)
+}
+
+var headerTemplate = `/*
+* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
+* THIS FILE MUST NOT BE EDITED BY HAND
+*/
+
+package {{.Name}}
+
+import (
+{{range $path, $name := .Imports}}
+	{{$name}} "{{$path}}"{{end}}
+)
+`
+
+var funcTemplate = `{{.Comment}}
+func (fwd *AssertionsForwarder) {{.DocInfo.Name}}({{.Params}}) bool {
+	return assert.{{.DocInfo.Name}}({{.ForwardedParams}})
+}`
diff --git a/go/src/github.com/stretchr/testify/assert/assertion_forward.go b/go/src/github.com/stretchr/testify/assert/assertion_forward.go
new file mode 100644
index 0000000..e6a7960
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/assert/assertion_forward.go
@@ -0,0 +1,387 @@
+/*
+* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
+* THIS FILE MUST NOT BE EDITED BY HAND
+*/
+
+package assert
+
+import (
+
+	http "net/http"
+	url "net/url"
+	time "time"
+)
+
+
+// Condition uses a Comparison to assert a complex condition.
+func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {
+	return Condition(a.t, comp, msgAndArgs...)
+}
+
+
+// Contains asserts that the specified string, list(array, slice...) or map contains the
+// specified substring or element.
+// 
+//    a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'")
+//    a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
+//    a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
+	return Contains(a.t, s, contains, msgAndArgs...)
+}
+
+
+// Empty asserts that the specified object is empty.  I.e. nil, "", false, 0 or either
+// a slice or a channel with len == 0.
+// 
+//  a.Empty(obj)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
+	return Empty(a.t, object, msgAndArgs...)
+}
+
+
+// Equal asserts that two objects are equal.
+// 
+//    a.Equal(123, 123, "123 and 123 should be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	return Equal(a.t, expected, actual, msgAndArgs...)
+}
+
+
+// EqualError asserts that a function returned an error (i.e. not `nil`)
+// and that it is equal to the provided error.
+// 
+//   actualObj, err := SomeFunction()
+//   if assert.Error(t, err, "An error was expected") {
+// 	   assert.Equal(t, err, expectedError)
+//   }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {
+	return EqualError(a.t, theError, errString, msgAndArgs...)
+}
+
+
+// EqualValues asserts that two objects are equal or convertable to the same types
+// and equal.
+// 
+//    a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	return EqualValues(a.t, expected, actual, msgAndArgs...)
+}
+
+
+// Error asserts that a function returned an error (i.e. not `nil`).
+// 
+//   actualObj, err := SomeFunction()
+//   if a.Error(err, "An error was expected") {
+// 	   assert.Equal(t, err, expectedError)
+//   }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
+	return Error(a.t, err, msgAndArgs...)
+}
+
+
+// Exactly asserts that two objects are equal is value and type.
+// 
+//    a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	return Exactly(a.t, expected, actual, msgAndArgs...)
+}
+
+
+// Fail reports a failure through
+func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {
+	return Fail(a.t, failureMessage, msgAndArgs...)
+}
+
+
+// FailNow fails test
+func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool {
+	return FailNow(a.t, failureMessage, msgAndArgs...)
+}
+
+
+// False asserts that the specified value is false.
+// 
+//    a.False(myBool, "myBool should be false")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
+	return False(a.t, value, msgAndArgs...)
+}
+
+
+// HTTPBodyContains asserts that a specified handler returns a
+// body that contains a string.
+// 
+//  a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool {
+	return HTTPBodyContains(a.t, handler, method, url, values, str)
+}
+
+
+// HTTPBodyNotContains asserts that a specified handler returns a
+// body that does not contain a string.
+// 
+//  a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool {
+	return HTTPBodyNotContains(a.t, handler, method, url, values, str)
+}
+
+
+// HTTPError asserts that a specified handler returns an error status code.
+// 
+//  a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) bool {
+	return HTTPError(a.t, handler, method, url, values)
+}
+
+
+// HTTPRedirect asserts that a specified handler returns a redirect status code.
+// 
+//  a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) bool {
+	return HTTPRedirect(a.t, handler, method, url, values)
+}
+
+
+// HTTPSuccess asserts that a specified handler returns a success status code.
+// 
+//  a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) bool {
+	return HTTPSuccess(a.t, handler, method, url, values)
+}
+
+
+// Implements asserts that an object is implemented by the specified interface.
+// 
+//    a.Implements((*MyInterface)(nil), new(MyObject), "MyObject")
+func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	return Implements(a.t, interfaceObject, object, msgAndArgs...)
+}
+
+
+// InDelta asserts that the two numerals are within delta of each other.
+// 
+// 	 a.InDelta(math.Pi, (22 / 7.0), 0.01)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	return InDelta(a.t, expected, actual, delta, msgAndArgs...)
+}
+
+
+// InDeltaSlice is the same as InDelta, except it compares two slices.
+func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
+}
+
+
+// InEpsilon asserts that expected and actual have a relative error less than epsilon
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
+}
+
+
+// InEpsilonSlice is the same as InEpsilon, except it compares two slices.
+func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	return InEpsilonSlice(a.t, expected, actual, delta, msgAndArgs...)
+}
+
+
+// IsType asserts that the specified objects are of the same type.
+func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	return IsType(a.t, expectedType, object, msgAndArgs...)
+}
+
+
+// JSONEq asserts that two JSON strings are equivalent.
+// 
+//  a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool {
+	return JSONEq(a.t, expected, actual, msgAndArgs...)
+}
+
+
+// Len asserts that the specified object has specific length.
+// Len also fails if the object has a type that len() not accept.
+// 
+//    a.Len(mySlice, 3, "The size of slice is not 3")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {
+	return Len(a.t, object, length, msgAndArgs...)
+}
+
+
+// Nil asserts that the specified object is nil.
+// 
+//    a.Nil(err, "err should be nothing")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
+	return Nil(a.t, object, msgAndArgs...)
+}
+
+
+// NoError asserts that a function returned no error (i.e. `nil`).
+// 
+//   actualObj, err := SomeFunction()
+//   if a.NoError(err) {
+// 	   assert.Equal(t, actualObj, expectedObj)
+//   }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
+	return NoError(a.t, err, msgAndArgs...)
+}
+
+
+// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
+// specified substring or element.
+// 
+//    a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
+//    a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
+//    a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
+	return NotContains(a.t, s, contains, msgAndArgs...)
+}
+
+
+// NotEmpty asserts that the specified object is NOT empty.  I.e. not nil, "", false, 0 or either
+// a slice or a channel with len == 0.
+// 
+//  if a.NotEmpty(obj) {
+//    assert.Equal(t, "two", obj[1])
+//  }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool {
+	return NotEmpty(a.t, object, msgAndArgs...)
+}
+
+
+// NotEqual asserts that the specified values are NOT equal.
+// 
+//    a.NotEqual(obj1, obj2, "two objects shouldn't be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	return NotEqual(a.t, expected, actual, msgAndArgs...)
+}
+
+
+// NotNil asserts that the specified object is not nil.
+// 
+//    a.NotNil(err, "err should be something")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {
+	return NotNil(a.t, object, msgAndArgs...)
+}
+
+
+// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
+// 
+//   a.NotPanics(func(){
+//     RemainCalm()
+//   }, "Calling RemainCalm() should NOT panic")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	return NotPanics(a.t, f, msgAndArgs...)
+}
+
+
+// NotRegexp asserts that a specified regexp does not match a string.
+// 
+//  a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
+//  a.NotRegexp("^start", "it's not starting")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	return NotRegexp(a.t, rx, str, msgAndArgs...)
+}
+
+
+// NotZero asserts that i is not the zero value for its type and returns the truth.
+func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {
+	return NotZero(a.t, i, msgAndArgs...)
+}
+
+
+// Panics asserts that the code inside the specified PanicTestFunc panics.
+// 
+//   a.Panics(func(){
+//     GoCrazy()
+//   }, "Calling GoCrazy() should panic")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	return Panics(a.t, f, msgAndArgs...)
+}
+
+
+// Regexp asserts that a specified regexp matches a string.
+// 
+//  a.Regexp(regexp.MustCompile("start"), "it's starting")
+//  a.Regexp("start...$", "it's not starting")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	return Regexp(a.t, rx, str, msgAndArgs...)
+}
+
+
+// True asserts that the specified value is true.
+// 
+//    a.True(myBool, "myBool should be true")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
+	return True(a.t, value, msgAndArgs...)
+}
+
+
+// WithinDuration asserts that the two times are within duration delta of each other.
+// 
+//   a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
+	return WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
+}
+
+
+// Zero asserts that i is the zero value for its type and returns the truth.
+func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {
+	return Zero(a.t, i, msgAndArgs...)
+}
diff --git a/go/src/github.com/stretchr/testify/assert/assertion_forward.go.tmpl b/go/src/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
new file mode 100644
index 0000000..99f9acf
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
@@ -0,0 +1,4 @@
+{{.CommentWithoutT "a"}}
+func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool {
+	return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
+}
diff --git a/go/src/github.com/stretchr/testify/assert/assertions.go b/go/src/github.com/stretchr/testify/assert/assertions.go
new file mode 100644
index 0000000..d7c16c5
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/assert/assertions.go
@@ -0,0 +1,1004 @@
+package assert
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"math"
+	"reflect"
+	"regexp"
+	"runtime"
+	"strings"
+	"time"
+	"unicode"
+	"unicode/utf8"
+
+	"github.com/davecgh/go-spew/spew"
+	"github.com/pmezard/go-difflib/difflib"
+)
+
+// TestingT is an interface wrapper around *testing.T
+type TestingT interface {
+	Errorf(format string, args ...interface{})
+}
+
+// Comparison a custom function that returns true on success and false on failure
+type Comparison func() (success bool)
+
+/*
+	Helper functions
+*/
+
+// ObjectsAreEqual determines if two objects are considered equal.
+//
+// This function does no assertion of any kind.
+func ObjectsAreEqual(expected, actual interface{}) bool {
+
+	if expected == nil || actual == nil {
+		return expected == actual
+	}
+
+	return reflect.DeepEqual(expected, actual)
+
+}
+
+// ObjectsAreEqualValues gets whether two objects are equal, or if their
+// values are equal.
+func ObjectsAreEqualValues(expected, actual interface{}) bool {
+	if ObjectsAreEqual(expected, actual) {
+		return true
+	}
+
+	actualType := reflect.TypeOf(actual)
+	if actualType == nil {
+		return false
+	}
+	expectedValue := reflect.ValueOf(expected)
+	if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
+		// Attempt comparison after type conversion
+		return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual)
+	}
+
+	return false
+}
+
+/* CallerInfo is necessary because the assert functions use the testing object
+internally, causing it to print the file:line of the assert method, rather than where
+the problem actually occured in calling code.*/
+
+// CallerInfo returns an array of strings containing the file and line number
+// of each stack frame leading from the current test to the assert call that
+// failed.
+func CallerInfo() []string {
+
+	pc := uintptr(0)
+	file := ""
+	line := 0
+	ok := false
+	name := ""
+
+	callers := []string{}
+	for i := 0; ; i++ {
+		pc, file, line, ok = runtime.Caller(i)
+		if !ok {
+			return nil
+		}
+
+		// This is a huge edge case, but it will panic if this is the case, see #180
+		if file == "<autogenerated>" {
+			break
+		}
+
+		parts := strings.Split(file, "/")
+		dir := parts[len(parts)-2]
+		file = parts[len(parts)-1]
+		if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
+			callers = append(callers, fmt.Sprintf("%s:%d", file, line))
+		}
+
+		f := runtime.FuncForPC(pc)
+		if f == nil {
+			break
+		}
+		name = f.Name()
+		// Drop the package
+		segments := strings.Split(name, ".")
+		name = segments[len(segments)-1]
+		if isTest(name, "Test") ||
+			isTest(name, "Benchmark") ||
+			isTest(name, "Example") {
+			break
+		}
+	}
+
+	return callers
+}
+
+// Stolen from the `go test` tool.
+// isTest tells whether name looks like a test (or benchmark, according to prefix).
+// It is a Test (say) if there is a character after Test that is not a lower-case letter.
+// We don't want TesticularCancer.
+func isTest(name, prefix string) bool {
+	if !strings.HasPrefix(name, prefix) {
+		return false
+	}
+	if len(name) == len(prefix) { // "Test" is ok
+		return true
+	}
+	rune, _ := utf8.DecodeRuneInString(name[len(prefix):])
+	return !unicode.IsLower(rune)
+}
+
+// getWhitespaceString returns a string that is long enough to overwrite the default
+// output from the go testing framework.
+func getWhitespaceString() string {
+
+	_, file, line, ok := runtime.Caller(1)
+	if !ok {
+		return ""
+	}
+	parts := strings.Split(file, "/")
+	file = parts[len(parts)-1]
+
+	return strings.Repeat(" ", len(fmt.Sprintf("%s:%d:      ", file, line)))
+
+}
+
+func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
+	if len(msgAndArgs) == 0 || msgAndArgs == nil {
+		return ""
+	}
+	if len(msgAndArgs) == 1 {
+		return msgAndArgs[0].(string)
+	}
+	if len(msgAndArgs) > 1 {
+		return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
+	}
+	return ""
+}
+
+// Indents all lines of the message by appending a number of tabs to each line, in an output format compatible with Go's
+// test printing (see inner comment for specifics)
+func indentMessageLines(message string, tabs int) string {
+	outBuf := new(bytes.Buffer)
+
+	for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ {
+		if i != 0 {
+			outBuf.WriteRune('\n')
+		}
+		for ii := 0; ii < tabs; ii++ {
+			outBuf.WriteRune('\t')
+			// Bizarrely, all lines except the first need one fewer tabs prepended, so deliberately advance the counter
+			// by 1 prematurely.
+			if ii == 0 && i > 0 {
+				ii++
+			}
+		}
+		outBuf.WriteString(scanner.Text())
+	}
+
+	return outBuf.String()
+}
+
+type failNower interface {
+	FailNow()
+}
+
+// FailNow fails test
+func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
+	Fail(t, failureMessage, msgAndArgs...)
+
+	// We cannot extend TestingT with FailNow() and
+	// maintain backwards compatibility, so we fallback
+	// to panicking when FailNow is not available in
+	// TestingT.
+	// See issue #263
+
+	if t, ok := t.(failNower); ok {
+		t.FailNow()
+	} else {
+		panic("test failed and t is missing `FailNow()`")
+	}
+	return false
+}
+
+// Fail reports a failure through
+func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
+
+	message := messageFromMsgAndArgs(msgAndArgs...)
+
+	errorTrace := strings.Join(CallerInfo(), "\n\r\t\t\t")
+	if len(message) > 0 {
+		t.Errorf("\r%s\r\tError Trace:\t%s\n"+
+			"\r\tError:%s\n"+
+			"\r\tMessages:\t%s\n\r",
+			getWhitespaceString(),
+			errorTrace,
+			indentMessageLines(failureMessage, 2),
+			message)
+	} else {
+		t.Errorf("\r%s\r\tError Trace:\t%s\n"+
+			"\r\tError:%s\n\r",
+			getWhitespaceString(),
+			errorTrace,
+			indentMessageLines(failureMessage, 2))
+	}
+
+	return false
+}
+
+// Implements asserts that an object is implemented by the specified interface.
+//
+//    assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject")
+func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+
+	interfaceType := reflect.TypeOf(interfaceObject).Elem()
+
+	if !reflect.TypeOf(object).Implements(interfaceType) {
+		return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...)
+	}
+
+	return true
+
+}
+
+// IsType asserts that the specified objects are of the same type.
+func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+
+	if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
+		return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
+	}
+
+	return true
+}
+
+// Equal asserts that two objects are equal.
+//
+//    assert.Equal(t, 123, 123, "123 and 123 should be equal")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+
+	if !ObjectsAreEqual(expected, actual) {
+		diff := diff(expected, actual)
+		return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+
+			"        != %#v (actual)%s", expected, actual, diff), msgAndArgs...)
+	}
+
+	return true
+
+}
+
+// EqualValues asserts that two objects are equal or convertable to the same types
+// and equal.
+//
+//    assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+
+	if !ObjectsAreEqualValues(expected, actual) {
+		return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+
+			"        != %#v (actual)", expected, actual), msgAndArgs...)
+	}
+
+	return true
+
+}
+
+// Exactly asserts that two objects are equal is value and type.
+//
+//    assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+
+	aType := reflect.TypeOf(expected)
+	bType := reflect.TypeOf(actual)
+
+	if aType != bType {
+		return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...)
+	}
+
+	return Equal(t, expected, actual, msgAndArgs...)
+
+}
+
+// NotNil asserts that the specified object is not nil.
+//
+//    assert.NotNil(t, err, "err should be something")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+	if !isNil(object) {
+		return true
+	}
+	return Fail(t, "Expected value not to be nil.", msgAndArgs...)
+}
+
+// isNil checks if a specified object is nil or not, without Failing.
+func isNil(object interface{}) bool {
+	if object == nil {
+		return true
+	}
+
+	value := reflect.ValueOf(object)
+	kind := value.Kind()
+	if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
+		return true
+	}
+
+	return false
+}
+
+// Nil asserts that the specified object is nil.
+//
+//    assert.Nil(t, err, "err should be nothing")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+	if isNil(object) {
+		return true
+	}
+	return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...)
+}
+
+var numericZeros = []interface{}{
+	int(0),
+	int8(0),
+	int16(0),
+	int32(0),
+	int64(0),
+	uint(0),
+	uint8(0),
+	uint16(0),
+	uint32(0),
+	uint64(0),
+	float32(0),
+	float64(0),
+}
+
+// isEmpty gets whether the specified object is considered empty or not.
+func isEmpty(object interface{}) bool {
+
+	if object == nil {
+		return true
+	} else if object == "" {
+		return true
+	} else if object == false {
+		return true
+	}
+
+	for _, v := range numericZeros {
+		if object == v {
+			return true
+		}
+	}
+
+	objValue := reflect.ValueOf(object)
+
+	switch objValue.Kind() {
+	case reflect.Map:
+		fallthrough
+	case reflect.Slice, reflect.Chan:
+		{
+			return (objValue.Len() == 0)
+		}
+	case reflect.Struct:
+		switch object.(type) {
+		case time.Time:
+			return object.(time.Time).IsZero()
+		}
+	case reflect.Ptr:
+		{
+			if objValue.IsNil() {
+				return true
+			}
+			switch object.(type) {
+			case *time.Time:
+				return object.(*time.Time).IsZero()
+			default:
+				return false
+			}
+		}
+	}
+	return false
+}
+
+// Empty asserts that the specified object is empty.  I.e. nil, "", false, 0 or either
+// a slice or a channel with len == 0.
+//
+//  assert.Empty(t, obj)
+//
+// Returns whether the assertion was successful (true) or not (false).
+func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+
+	pass := isEmpty(object)
+	if !pass {
+		Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...)
+	}
+
+	return pass
+
+}
+
+// NotEmpty asserts that the specified object is NOT empty.  I.e. not nil, "", false, 0 or either
+// a slice or a channel with len == 0.
+//
+//  if assert.NotEmpty(t, obj) {
+//    assert.Equal(t, "two", obj[1])
+//  }
+//
+// Returns whether the assertion was successful (true) or not (false).
+func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+
+	pass := !isEmpty(object)
+	if !pass {
+		Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...)
+	}
+
+	return pass
+
+}
+
+// getLen try to get length of object.
+// return (false, 0) if impossible.
+func getLen(x interface{}) (ok bool, length int) {
+	v := reflect.ValueOf(x)
+	defer func() {
+		if e := recover(); e != nil {
+			ok = false
+		}
+	}()
+	return true, v.Len()
+}
+
+// Len asserts that the specified object has specific length.
+// Len also fails if the object has a type that len() not accept.
+//
+//    assert.Len(t, mySlice, 3, "The size of slice is not 3")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
+	ok, l := getLen(object)
+	if !ok {
+		return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
+	}
+
+	if l != length {
+		return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
+	}
+	return true
+}
+
+// True asserts that the specified value is true.
+//
+//    assert.True(t, myBool, "myBool should be true")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
+
+	if value != true {
+		return Fail(t, "Should be true", msgAndArgs...)
+	}
+
+	return true
+
+}
+
+// False asserts that the specified value is false.
+//
+//    assert.False(t, myBool, "myBool should be false")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
+
+	if value != false {
+		return Fail(t, "Should be false", msgAndArgs...)
+	}
+
+	return true
+
+}
+
+// NotEqual asserts that the specified values are NOT equal.
+//
+//    assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+
+	if ObjectsAreEqual(expected, actual) {
+		return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...)
+	}
+
+	return true
+
+}
+
+// containsElement try loop over the list check if the list includes the element.
+// return (false, false) if impossible.
+// return (true, false) if element was not found.
+// return (true, true) if element was found.
+func includeElement(list interface{}, element interface{}) (ok, found bool) {
+
+	listValue := reflect.ValueOf(list)
+	elementValue := reflect.ValueOf(element)
+	defer func() {
+		if e := recover(); e != nil {
+			ok = false
+			found = false
+		}
+	}()
+
+	if reflect.TypeOf(list).Kind() == reflect.String {
+		return true, strings.Contains(listValue.String(), elementValue.String())
+	}
+
+	if reflect.TypeOf(list).Kind() == reflect.Map {
+		mapKeys := listValue.MapKeys()
+		for i := 0; i < len(mapKeys); i++ {
+			if ObjectsAreEqual(mapKeys[i].Interface(), element) {
+				return true, true
+			}
+		}
+		return true, false
+	}
+
+	for i := 0; i < listValue.Len(); i++ {
+		if ObjectsAreEqual(listValue.Index(i).Interface(), element) {
+			return true, true
+		}
+	}
+	return true, false
+
+}
+
+// Contains asserts that the specified string, list(array, slice...) or map contains the
+// specified substring or element.
+//
+//    assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'")
+//    assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
+//    assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
+
+	ok, found := includeElement(s, contains)
+	if !ok {
+		return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...)
+	}
+	if !found {
+		return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...)
+	}
+
+	return true
+
+}
+
+// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
+// specified substring or element.
+//
+//    assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
+//    assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
+//    assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
+
+	ok, found := includeElement(s, contains)
+	if !ok {
+		return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...)
+	}
+	if found {
+		return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...)
+	}
+
+	return true
+
+}
+
+// Condition uses a Comparison to assert a complex condition.
+func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
+	result := comp()
+	if !result {
+		Fail(t, "Condition failed!", msgAndArgs...)
+	}
+	return result
+}
+
+// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics
+// methods, and represents a simple func that takes no arguments, and returns nothing.
+type PanicTestFunc func()
+
+// didPanic returns true if the function passed to it panics. Otherwise, it returns false.
+func didPanic(f PanicTestFunc) (bool, interface{}) {
+
+	didPanic := false
+	var message interface{}
+	func() {
+
+		defer func() {
+			if message = recover(); message != nil {
+				didPanic = true
+			}
+		}()
+
+		// call the target function
+		f()
+
+	}()
+
+	return didPanic, message
+
+}
+
+// Panics asserts that the code inside the specified PanicTestFunc panics.
+//
+//   assert.Panics(t, func(){
+//     GoCrazy()
+//   }, "Calling GoCrazy() should panic")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+
+	if funcDidPanic, panicValue := didPanic(f); !funcDidPanic {
+		return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+	}
+
+	return true
+}
+
+// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
+//
+//   assert.NotPanics(t, func(){
+//     RemainCalm()
+//   }, "Calling RemainCalm() should NOT panic")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+
+	if funcDidPanic, panicValue := didPanic(f); funcDidPanic {
+		return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+	}
+
+	return true
+}
+
+// WithinDuration asserts that the two times are within duration delta of each other.
+//
+//   assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
+
+	dt := expected.Sub(actual)
+	if dt < -delta || dt > delta {
+		return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
+	}
+
+	return true
+}
+
+func toFloat(x interface{}) (float64, bool) {
+	var xf float64
+	xok := true
+
+	switch xn := x.(type) {
+	case uint8:
+		xf = float64(xn)
+	case uint16:
+		xf = float64(xn)
+	case uint32:
+		xf = float64(xn)
+	case uint64:
+		xf = float64(xn)
+	case int:
+		xf = float64(xn)
+	case int8:
+		xf = float64(xn)
+	case int16:
+		xf = float64(xn)
+	case int32:
+		xf = float64(xn)
+	case int64:
+		xf = float64(xn)
+	case float32:
+		xf = float64(xn)
+	case float64:
+		xf = float64(xn)
+	default:
+		xok = false
+	}
+
+	return xf, xok
+}
+
+// InDelta asserts that the two numerals are within delta of each other.
+//
+// 	 assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
+//
+// Returns whether the assertion was successful (true) or not (false).
+func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+
+	af, aok := toFloat(expected)
+	bf, bok := toFloat(actual)
+
+	if !aok || !bok {
+		return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...)
+	}
+
+	if math.IsNaN(af) {
+		return Fail(t, fmt.Sprintf("Actual must not be NaN"), msgAndArgs...)
+	}
+
+	if math.IsNaN(bf) {
+		return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...)
+	}
+
+	dt := af - bf
+	if dt < -delta || dt > delta {
+		return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
+	}
+
+	return true
+}
+
+// InDeltaSlice is the same as InDelta, except it compares two slices.
+func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if expected == nil || actual == nil ||
+		reflect.TypeOf(actual).Kind() != reflect.Slice ||
+		reflect.TypeOf(expected).Kind() != reflect.Slice {
+		return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...)
+	}
+
+	actualSlice := reflect.ValueOf(actual)
+	expectedSlice := reflect.ValueOf(expected)
+
+	for i := 0; i < actualSlice.Len(); i++ {
+		result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta)
+		if !result {
+			return result
+		}
+	}
+
+	return true
+}
+
+func calcRelativeError(expected, actual interface{}) (float64, error) {
+	af, aok := toFloat(expected)
+	if !aok {
+		return 0, fmt.Errorf("expected value %q cannot be converted to float", expected)
+	}
+	if af == 0 {
+		return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error")
+	}
+	bf, bok := toFloat(actual)
+	if !bok {
+		return 0, fmt.Errorf("expected value %q cannot be converted to float", actual)
+	}
+
+	return math.Abs(af-bf) / math.Abs(af), nil
+}
+
+// InEpsilon asserts that expected and actual have a relative error less than epsilon
+//
+// Returns whether the assertion was successful (true) or not (false).
+func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	actualEpsilon, err := calcRelativeError(expected, actual)
+	if err != nil {
+		return Fail(t, err.Error(), msgAndArgs...)
+	}
+	if actualEpsilon > epsilon {
+		return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+
+			"        < %#v (actual)", actualEpsilon, epsilon), msgAndArgs...)
+	}
+
+	return true
+}
+
+// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
+func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	if expected == nil || actual == nil ||
+		reflect.TypeOf(actual).Kind() != reflect.Slice ||
+		reflect.TypeOf(expected).Kind() != reflect.Slice {
+		return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...)
+	}
+
+	actualSlice := reflect.ValueOf(actual)
+	expectedSlice := reflect.ValueOf(expected)
+
+	for i := 0; i < actualSlice.Len(); i++ {
+		result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon)
+		if !result {
+			return result
+		}
+	}
+
+	return true
+}
+
+/*
+	Errors
+*/
+
+// NoError asserts that a function returned no error (i.e. `nil`).
+//
+//   actualObj, err := SomeFunction()
+//   if assert.NoError(t, err) {
+//	   assert.Equal(t, actualObj, expectedObj)
+//   }
+//
+// Returns whether the assertion was successful (true) or not (false).
+func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
+	if isNil(err) {
+		return true
+	}
+
+	return Fail(t, fmt.Sprintf("Received unexpected error %q", err), msgAndArgs...)
+}
+
+// Error asserts that a function returned an error (i.e. not `nil`).
+//
+//   actualObj, err := SomeFunction()
+//   if assert.Error(t, err, "An error was expected") {
+//	   assert.Equal(t, err, expectedError)
+//   }
+//
+// Returns whether the assertion was successful (true) or not (false).
+func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
+
+	message := messageFromMsgAndArgs(msgAndArgs...)
+	return NotNil(t, err, "An error is expected but got nil. %s", message)
+
+}
+
+// EqualError asserts that a function returned an error (i.e. not `nil`)
+// and that it is equal to the provided error.
+//
+//   actualObj, err := SomeFunction()
+//   if assert.Error(t, err, "An error was expected") {
+//	   assert.Equal(t, err, expectedError)
+//   }
+//
+// Returns whether the assertion was successful (true) or not (false).
+func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {
+
+	message := messageFromMsgAndArgs(msgAndArgs...)
+	if !NotNil(t, theError, "An error is expected but got nil. %s", message) {
+		return false
+	}
+	s := "An error with value \"%s\" is expected but got \"%s\". %s"
+	return Equal(t, errString, theError.Error(),
+		s, errString, theError.Error(), message)
+}
+
+// matchRegexp return true if a specified regexp matches a string.
+func matchRegexp(rx interface{}, str interface{}) bool {
+
+	var r *regexp.Regexp
+	if rr, ok := rx.(*regexp.Regexp); ok {
+		r = rr
+	} else {
+		r = regexp.MustCompile(fmt.Sprint(rx))
+	}
+
+	return (r.FindStringIndex(fmt.Sprint(str)) != nil)
+
+}
+
+// Regexp asserts that a specified regexp matches a string.
+//
+//  assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
+//  assert.Regexp(t, "start...$", "it's not starting")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+
+	match := matchRegexp(rx, str)
+
+	if !match {
+		Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...)
+	}
+
+	return match
+}
+
+// NotRegexp asserts that a specified regexp does not match a string.
+//
+//  assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
+//  assert.NotRegexp(t, "^start", "it's not starting")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	match := matchRegexp(rx, str)
+
+	if match {
+		Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...)
+	}
+
+	return !match
+
+}
+
+// Zero asserts that i is the zero value for its type and returns the truth.
+func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
+	if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
+		return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
+	}
+	return true
+}
+
+// NotZero asserts that i is not the zero value for its type and returns the truth.
+func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
+	if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
+		return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...)
+	}
+	return true
+}
+
+// JSONEq asserts that two JSON strings are equivalent.
+//
+//  assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+//
+// Returns whether the assertion was successful (true) or not (false).
+func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
+	var expectedJSONAsInterface, actualJSONAsInterface interface{}
+
+	if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {
+		return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...)
+	}
+
+	if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil {
+		return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...)
+	}
+
+	return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...)
+}
+
+func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
+	t := reflect.TypeOf(v)
+	k := t.Kind()
+
+	if k == reflect.Ptr {
+		t = t.Elem()
+		k = t.Kind()
+	}
+	return t, k
+}
+
+// diff returns a diff of both values as long as both are of the same type and
+// are a struct, map, slice or array. Otherwise it returns an empty string.
+func diff(expected interface{}, actual interface{}) string {
+	if expected == nil || actual == nil {
+		return ""
+	}
+
+	et, ek := typeAndKind(expected)
+	at, _ := typeAndKind(actual)
+
+	if et != at {
+		return ""
+	}
+
+	if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array {
+		return ""
+	}
+
+	spew.Config.SortKeys = true
+	e := spew.Sdump(expected)
+	a := spew.Sdump(actual)
+
+	diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
+		A:        difflib.SplitLines(e),
+		B:        difflib.SplitLines(a),
+		FromFile: "Expected",
+		FromDate: "",
+		ToFile:   "Actual",
+		ToDate:   "",
+		Context:  1,
+	})
+
+	return "\n\nDiff:\n" + diff
+}
diff --git a/go/src/github.com/stretchr/testify/assert/assertions_test.go b/go/src/github.com/stretchr/testify/assert/assertions_test.go
new file mode 100644
index 0000000..15a04b8
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/assert/assertions_test.go
@@ -0,0 +1,1122 @@
+package assert
+
+import (
+	"errors"
+	"io"
+	"math"
+	"os"
+	"reflect"
+	"regexp"
+	"testing"
+	"time"
+)
+
+var (
+	i     interface{}
+	zeros = []interface{}{
+		false,
+		byte(0),
+		complex64(0),
+		complex128(0),
+		float32(0),
+		float64(0),
+		int(0),
+		int8(0),
+		int16(0),
+		int32(0),
+		int64(0),
+		rune(0),
+		uint(0),
+		uint8(0),
+		uint16(0),
+		uint32(0),
+		uint64(0),
+		uintptr(0),
+		"",
+		[0]interface{}{},
+		[]interface{}(nil),
+		struct{ x int }{},
+		(*interface{})(nil),
+		(func())(nil),
+		nil,
+		interface{}(nil),
+		map[interface{}]interface{}(nil),
+		(chan interface{})(nil),
+		(<-chan interface{})(nil),
+		(chan<- interface{})(nil),
+	}
+	nonZeros = []interface{}{
+		true,
+		byte(1),
+		complex64(1),
+		complex128(1),
+		float32(1),
+		float64(1),
+		int(1),
+		int8(1),
+		int16(1),
+		int32(1),
+		int64(1),
+		rune(1),
+		uint(1),
+		uint8(1),
+		uint16(1),
+		uint32(1),
+		uint64(1),
+		uintptr(1),
+		"s",
+		[1]interface{}{1},
+		[]interface{}{},
+		struct{ x int }{1},
+		(*interface{})(&i),
+		(func())(func() {}),
+		interface{}(1),
+		map[interface{}]interface{}{},
+		(chan interface{})(make(chan interface{})),
+		(<-chan interface{})(make(chan interface{})),
+		(chan<- interface{})(make(chan interface{})),
+	}
+)
+
+// AssertionTesterInterface defines an interface to be used for testing assertion methods
+type AssertionTesterInterface interface {
+	TestMethod()
+}
+
+// AssertionTesterConformingObject is an object that conforms to the AssertionTesterInterface interface
+type AssertionTesterConformingObject struct {
+}
+
+func (a *AssertionTesterConformingObject) TestMethod() {
+}
+
+// AssertionTesterNonConformingObject is an object that does not conform to the AssertionTesterInterface interface
+type AssertionTesterNonConformingObject struct {
+}
+
+func TestObjectsAreEqual(t *testing.T) {
+
+	if !ObjectsAreEqual("Hello World", "Hello World") {
+		t.Error("objectsAreEqual should return true")
+	}
+	if !ObjectsAreEqual(123, 123) {
+		t.Error("objectsAreEqual should return true")
+	}
+	if !ObjectsAreEqual(123.5, 123.5) {
+		t.Error("objectsAreEqual should return true")
+	}
+	if !ObjectsAreEqual([]byte("Hello World"), []byte("Hello World")) {
+		t.Error("objectsAreEqual should return true")
+	}
+	if !ObjectsAreEqual(nil, nil) {
+		t.Error("objectsAreEqual should return true")
+	}
+	if ObjectsAreEqual(map[int]int{5: 10}, map[int]int{10: 20}) {
+		t.Error("objectsAreEqual should return false")
+	}
+	if ObjectsAreEqual('x', "x") {
+		t.Error("objectsAreEqual should return false")
+	}
+	if ObjectsAreEqual("x", 'x') {
+		t.Error("objectsAreEqual should return false")
+	}
+	if ObjectsAreEqual(0, 0.1) {
+		t.Error("objectsAreEqual should return false")
+	}
+	if ObjectsAreEqual(0.1, 0) {
+		t.Error("objectsAreEqual should return false")
+	}
+	if ObjectsAreEqual(uint32(10), int32(10)) {
+		t.Error("objectsAreEqual should return false")
+	}
+	if !ObjectsAreEqualValues(uint32(10), int32(10)) {
+		t.Error("ObjectsAreEqualValues should return true")
+	}
+	if ObjectsAreEqualValues(0, nil) {
+		t.Fail()
+	}
+	if ObjectsAreEqualValues(nil, 0) {
+		t.Fail()
+	}
+
+}
+
+func TestImplements(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	if !Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) {
+		t.Error("Implements method should return true: AssertionTesterConformingObject implements AssertionTesterInterface")
+	}
+	if Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) {
+		t.Error("Implements method should return false: AssertionTesterNonConformingObject does not implements AssertionTesterInterface")
+	}
+
+}
+
+func TestIsType(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	if !IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) {
+		t.Error("IsType should return true: AssertionTesterConformingObject is the same type as AssertionTesterConformingObject")
+	}
+	if IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) {
+		t.Error("IsType should return false: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject")
+	}
+
+}
+
+func TestEqual(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	if !Equal(mockT, "Hello World", "Hello World") {
+		t.Error("Equal should return true")
+	}
+	if !Equal(mockT, 123, 123) {
+		t.Error("Equal should return true")
+	}
+	if !Equal(mockT, 123.5, 123.5) {
+		t.Error("Equal should return true")
+	}
+	if !Equal(mockT, []byte("Hello World"), []byte("Hello World")) {
+		t.Error("Equal should return true")
+	}
+	if !Equal(mockT, nil, nil) {
+		t.Error("Equal should return true")
+	}
+	if !Equal(mockT, int32(123), int32(123)) {
+		t.Error("Equal should return true")
+	}
+	if !Equal(mockT, uint64(123), uint64(123)) {
+		t.Error("Equal should return true")
+	}
+
+}
+
+func TestNotNil(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	if !NotNil(mockT, new(AssertionTesterConformingObject)) {
+		t.Error("NotNil should return true: object is not nil")
+	}
+	if NotNil(mockT, nil) {
+		t.Error("NotNil should return false: object is nil")
+	}
+	if NotNil(mockT, (*struct{})(nil)) {
+		t.Error("NotNil should return false: object is (*struct{})(nil)")
+	}
+
+}
+
+func TestNil(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	if !Nil(mockT, nil) {
+		t.Error("Nil should return true: object is nil")
+	}
+	if !Nil(mockT, (*struct{})(nil)) {
+		t.Error("Nil should return true: object is (*struct{})(nil)")
+	}
+	if Nil(mockT, new(AssertionTesterConformingObject)) {
+		t.Error("Nil should return false: object is not nil")
+	}
+
+}
+
+func TestTrue(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	if !True(mockT, true) {
+		t.Error("True should return true")
+	}
+	if True(mockT, false) {
+		t.Error("True should return false")
+	}
+
+}
+
+func TestFalse(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	if !False(mockT, false) {
+		t.Error("False should return true")
+	}
+	if False(mockT, true) {
+		t.Error("False should return false")
+	}
+
+}
+
+func TestExactly(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	a := float32(1)
+	b := float64(1)
+	c := float32(1)
+	d := float32(2)
+
+	if Exactly(mockT, a, b) {
+		t.Error("Exactly should return false")
+	}
+	if Exactly(mockT, a, d) {
+		t.Error("Exactly should return false")
+	}
+	if !Exactly(mockT, a, c) {
+		t.Error("Exactly should return true")
+	}
+
+	if Exactly(mockT, nil, a) {
+		t.Error("Exactly should return false")
+	}
+	if Exactly(mockT, a, nil) {
+		t.Error("Exactly should return false")
+	}
+
+}
+
+func TestNotEqual(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	if !NotEqual(mockT, "Hello World", "Hello World!") {
+		t.Error("NotEqual should return true")
+	}
+	if !NotEqual(mockT, 123, 1234) {
+		t.Error("NotEqual should return true")
+	}
+	if !NotEqual(mockT, 123.5, 123.55) {
+		t.Error("NotEqual should return true")
+	}
+	if !NotEqual(mockT, []byte("Hello World"), []byte("Hello World!")) {
+		t.Error("NotEqual should return true")
+	}
+	if !NotEqual(mockT, nil, new(AssertionTesterConformingObject)) {
+		t.Error("NotEqual should return true")
+	}
+	funcA := func() int { return 23 }
+	funcB := func() int { return 42 }
+	if !NotEqual(mockT, funcA, funcB) {
+		t.Error("NotEqual should return true")
+	}
+
+	if NotEqual(mockT, "Hello World", "Hello World") {
+		t.Error("NotEqual should return false")
+	}
+	if NotEqual(mockT, 123, 123) {
+		t.Error("NotEqual should return false")
+	}
+	if NotEqual(mockT, 123.5, 123.5) {
+		t.Error("NotEqual should return false")
+	}
+	if NotEqual(mockT, []byte("Hello World"), []byte("Hello World")) {
+		t.Error("NotEqual should return false")
+	}
+	if NotEqual(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) {
+		t.Error("NotEqual should return false")
+	}
+}
+
+type A struct {
+	Name, Value string
+}
+
+func TestContains(t *testing.T) {
+
+	mockT := new(testing.T)
+	list := []string{"Foo", "Bar"}
+	complexList := []*A{
+		{"b", "c"},
+		{"d", "e"},
+		{"g", "h"},
+		{"j", "k"},
+	}
+	simpleMap := map[interface{}]interface{}{"Foo": "Bar"}
+
+	if !Contains(mockT, "Hello World", "Hello") {
+		t.Error("Contains should return true: \"Hello World\" contains \"Hello\"")
+	}
+	if Contains(mockT, "Hello World", "Salut") {
+		t.Error("Contains should return false: \"Hello World\" does not contain \"Salut\"")
+	}
+
+	if !Contains(mockT, list, "Bar") {
+		t.Error("Contains should return true: \"[\"Foo\", \"Bar\"]\" contains \"Bar\"")
+	}
+	if Contains(mockT, list, "Salut") {
+		t.Error("Contains should return false: \"[\"Foo\", \"Bar\"]\" does not contain \"Salut\"")
+	}
+	if !Contains(mockT, complexList, &A{"g", "h"}) {
+		t.Error("Contains should return true: complexList contains {\"g\", \"h\"}")
+	}
+	if Contains(mockT, complexList, &A{"g", "e"}) {
+		t.Error("Contains should return false: complexList contains {\"g\", \"e\"}")
+	}
+	if Contains(mockT, complexList, &A{"g", "e"}) {
+		t.Error("Contains should return false: complexList contains {\"g\", \"e\"}")
+	}
+	if !Contains(mockT, simpleMap, "Foo") {
+		t.Error("Contains should return true: \"{\"Foo\": \"Bar\"}\" contains \"Foo\"")
+	}
+	if Contains(mockT, simpleMap, "Bar") {
+		t.Error("Contains should return false: \"{\"Foo\": \"Bar\"}\" does not contains \"Bar\"")
+	}
+}
+
+func TestNotContains(t *testing.T) {
+
+	mockT := new(testing.T)
+	list := []string{"Foo", "Bar"}
+	simpleMap := map[interface{}]interface{}{"Foo": "Bar"}
+
+	if !NotContains(mockT, "Hello World", "Hello!") {
+		t.Error("NotContains should return true: \"Hello World\" does not contain \"Hello!\"")
+	}
+	if NotContains(mockT, "Hello World", "Hello") {
+		t.Error("NotContains should return false: \"Hello World\" contains \"Hello\"")
+	}
+
+	if !NotContains(mockT, list, "Foo!") {
+		t.Error("NotContains should return true: \"[\"Foo\", \"Bar\"]\" does not contain \"Foo!\"")
+	}
+	if NotContains(mockT, list, "Foo") {
+		t.Error("NotContains should return false: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"")
+	}
+	if NotContains(mockT, simpleMap, "Foo") {
+		t.Error("Contains should return true: \"{\"Foo\": \"Bar\"}\" contains \"Foo\"")
+	}
+	if !NotContains(mockT, simpleMap, "Bar") {
+		t.Error("Contains should return false: \"{\"Foo\": \"Bar\"}\" does not contains \"Bar\"")
+	}
+}
+
+func Test_includeElement(t *testing.T) {
+
+	list1 := []string{"Foo", "Bar"}
+	list2 := []int{1, 2}
+	simpleMap := map[interface{}]interface{}{"Foo": "Bar"}
+
+	ok, found := includeElement("Hello World", "World")
+	True(t, ok)
+	True(t, found)
+
+	ok, found = includeElement(list1, "Foo")
+	True(t, ok)
+	True(t, found)
+
+	ok, found = includeElement(list1, "Bar")
+	True(t, ok)
+	True(t, found)
+
+	ok, found = includeElement(list2, 1)
+	True(t, ok)
+	True(t, found)
+
+	ok, found = includeElement(list2, 2)
+	True(t, ok)
+	True(t, found)
+
+	ok, found = includeElement(list1, "Foo!")
+	True(t, ok)
+	False(t, found)
+
+	ok, found = includeElement(list2, 3)
+	True(t, ok)
+	False(t, found)
+
+	ok, found = includeElement(list2, "1")
+	True(t, ok)
+	False(t, found)
+
+	ok, found = includeElement(simpleMap, "Foo")
+	True(t, ok)
+	True(t, found)
+
+	ok, found = includeElement(simpleMap, "Bar")
+	True(t, ok)
+	False(t, found)
+
+	ok, found = includeElement(1433, "1")
+	False(t, ok)
+	False(t, found)
+}
+
+func TestCondition(t *testing.T) {
+	mockT := new(testing.T)
+
+	if !Condition(mockT, func() bool { return true }, "Truth") {
+		t.Error("Condition should return true")
+	}
+
+	if Condition(mockT, func() bool { return false }, "Lie") {
+		t.Error("Condition should return false")
+	}
+
+}
+
+func TestDidPanic(t *testing.T) {
+
+	if funcDidPanic, _ := didPanic(func() {
+		panic("Panic!")
+	}); !funcDidPanic {
+		t.Error("didPanic should return true")
+	}
+
+	if funcDidPanic, _ := didPanic(func() {
+	}); funcDidPanic {
+		t.Error("didPanic should return false")
+	}
+
+}
+
+func TestPanics(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	if !Panics(mockT, func() {
+		panic("Panic!")
+	}) {
+		t.Error("Panics should return true")
+	}
+
+	if Panics(mockT, func() {
+	}) {
+		t.Error("Panics should return false")
+	}
+
+}
+
+func TestNotPanics(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	if !NotPanics(mockT, func() {
+	}) {
+		t.Error("NotPanics should return true")
+	}
+
+	if NotPanics(mockT, func() {
+		panic("Panic!")
+	}) {
+		t.Error("NotPanics should return false")
+	}
+
+}
+
+func TestNoError(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	// start with a nil error
+	var err error
+
+	True(t, NoError(mockT, err), "NoError should return True for nil arg")
+
+	// now set an error
+	err = errors.New("some error")
+
+	False(t, NoError(mockT, err), "NoError with error should return False")
+
+}
+
+func TestError(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	// start with a nil error
+	var err error
+
+	False(t, Error(mockT, err), "Error should return False for nil arg")
+
+	// now set an error
+	err = errors.New("some error")
+
+	True(t, Error(mockT, err), "Error with error should return True")
+
+}
+
+func TestEqualError(t *testing.T) {
+	mockT := new(testing.T)
+
+	// start with a nil error
+	var err error
+	False(t, EqualError(mockT, err, ""),
+		"EqualError should return false for nil arg")
+
+	// now set an error
+	err = errors.New("some error")
+	False(t, EqualError(mockT, err, "Not some error"),
+		"EqualError should return false for different error string")
+	True(t, EqualError(mockT, err, "some error"),
+		"EqualError should return true")
+}
+
+func Test_isEmpty(t *testing.T) {
+
+	chWithValue := make(chan struct{}, 1)
+	chWithValue <- struct{}{}
+
+	True(t, isEmpty(""))
+	True(t, isEmpty(nil))
+	True(t, isEmpty([]string{}))
+	True(t, isEmpty(0))
+	True(t, isEmpty(int32(0)))
+	True(t, isEmpty(int64(0)))
+	True(t, isEmpty(false))
+	True(t, isEmpty(map[string]string{}))
+	True(t, isEmpty(new(time.Time)))
+	True(t, isEmpty(time.Time{}))
+	True(t, isEmpty(make(chan struct{})))
+	False(t, isEmpty("something"))
+	False(t, isEmpty(errors.New("something")))
+	False(t, isEmpty([]string{"something"}))
+	False(t, isEmpty(1))
+	False(t, isEmpty(true))
+	False(t, isEmpty(map[string]string{"Hello": "World"}))
+	False(t, isEmpty(chWithValue))
+
+}
+
+func TestEmpty(t *testing.T) {
+
+	mockT := new(testing.T)
+	chWithValue := make(chan struct{}, 1)
+	chWithValue <- struct{}{}
+	var tiP *time.Time
+	var tiNP time.Time
+	var s *string
+	var f *os.File
+
+	True(t, Empty(mockT, ""), "Empty string is empty")
+	True(t, Empty(mockT, nil), "Nil is empty")
+	True(t, Empty(mockT, []string{}), "Empty string array is empty")
+	True(t, Empty(mockT, 0), "Zero int value is empty")
+	True(t, Empty(mockT, false), "False value is empty")
+	True(t, Empty(mockT, make(chan struct{})), "Channel without values is empty")
+	True(t, Empty(mockT, s), "Nil string pointer is empty")
+	True(t, Empty(mockT, f), "Nil os.File pointer is empty")
+	True(t, Empty(mockT, tiP), "Nil time.Time pointer is empty")
+	True(t, Empty(mockT, tiNP), "time.Time is empty")
+
+	False(t, Empty(mockT, "something"), "Non Empty string is not empty")
+	False(t, Empty(mockT, errors.New("something")), "Non nil object is not empty")
+	False(t, Empty(mockT, []string{"something"}), "Non empty string array is not empty")
+	False(t, Empty(mockT, 1), "Non-zero int value is not empty")
+	False(t, Empty(mockT, true), "True value is not empty")
+	False(t, Empty(mockT, chWithValue), "Channel with values is not empty")
+}
+
+func TestNotEmpty(t *testing.T) {
+
+	mockT := new(testing.T)
+	chWithValue := make(chan struct{}, 1)
+	chWithValue <- struct{}{}
+
+	False(t, NotEmpty(mockT, ""), "Empty string is empty")
+	False(t, NotEmpty(mockT, nil), "Nil is empty")
+	False(t, NotEmpty(mockT, []string{}), "Empty string array is empty")
+	False(t, NotEmpty(mockT, 0), "Zero int value is empty")
+	False(t, NotEmpty(mockT, false), "False value is empty")
+	False(t, NotEmpty(mockT, make(chan struct{})), "Channel without values is empty")
+
+	True(t, NotEmpty(mockT, "something"), "Non Empty string is not empty")
+	True(t, NotEmpty(mockT, errors.New("something")), "Non nil object is not empty")
+	True(t, NotEmpty(mockT, []string{"something"}), "Non empty string array is not empty")
+	True(t, NotEmpty(mockT, 1), "Non-zero int value is not empty")
+	True(t, NotEmpty(mockT, true), "True value is not empty")
+	True(t, NotEmpty(mockT, chWithValue), "Channel with values is not empty")
+}
+
+func Test_getLen(t *testing.T) {
+	falseCases := []interface{}{
+		nil,
+		0,
+		true,
+		false,
+		'A',
+		struct{}{},
+	}
+	for _, v := range falseCases {
+		ok, l := getLen(v)
+		False(t, ok, "Expected getLen fail to get length of %#v", v)
+		Equal(t, 0, l, "getLen should return 0 for %#v", v)
+	}
+
+	ch := make(chan int, 5)
+	ch <- 1
+	ch <- 2
+	ch <- 3
+	trueCases := []struct {
+		v interface{}
+		l int
+	}{
+		{[]int{1, 2, 3}, 3},
+		{[...]int{1, 2, 3}, 3},
+		{"ABC", 3},
+		{map[int]int{1: 2, 2: 4, 3: 6}, 3},
+		{ch, 3},
+
+		{[]int{}, 0},
+		{map[int]int{}, 0},
+		{make(chan int), 0},
+
+		{[]int(nil), 0},
+		{map[int]int(nil), 0},
+		{(chan int)(nil), 0},
+	}
+
+	for _, c := range trueCases {
+		ok, l := getLen(c.v)
+		True(t, ok, "Expected getLen success to get length of %#v", c.v)
+		Equal(t, c.l, l)
+	}
+}
+
+func TestLen(t *testing.T) {
+	mockT := new(testing.T)
+
+	False(t, Len(mockT, nil, 0), "nil does not have length")
+	False(t, Len(mockT, 0, 0), "int does not have length")
+	False(t, Len(mockT, true, 0), "true does not have length")
+	False(t, Len(mockT, false, 0), "false does not have length")
+	False(t, Len(mockT, 'A', 0), "Rune does not have length")
+	False(t, Len(mockT, struct{}{}, 0), "Struct does not have length")
+
+	ch := make(chan int, 5)
+	ch <- 1
+	ch <- 2
+	ch <- 3
+
+	cases := []struct {
+		v interface{}
+		l int
+	}{
+		{[]int{1, 2, 3}, 3},
+		{[...]int{1, 2, 3}, 3},
+		{"ABC", 3},
+		{map[int]int{1: 2, 2: 4, 3: 6}, 3},
+		{ch, 3},
+
+		{[]int{}, 0},
+		{map[int]int{}, 0},
+		{make(chan int), 0},
+
+		{[]int(nil), 0},
+		{map[int]int(nil), 0},
+		{(chan int)(nil), 0},
+	}
+
+	for _, c := range cases {
+		True(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l)
+	}
+
+	cases = []struct {
+		v interface{}
+		l int
+	}{
+		{[]int{1, 2, 3}, 4},
+		{[...]int{1, 2, 3}, 2},
+		{"ABC", 2},
+		{map[int]int{1: 2, 2: 4, 3: 6}, 4},
+		{ch, 2},
+
+		{[]int{}, 1},
+		{map[int]int{}, 1},
+		{make(chan int), 1},
+
+		{[]int(nil), 1},
+		{map[int]int(nil), 1},
+		{(chan int)(nil), 1},
+	}
+
+	for _, c := range cases {
+		False(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l)
+	}
+}
+
+func TestWithinDuration(t *testing.T) {
+
+	mockT := new(testing.T)
+	a := time.Now()
+	b := a.Add(10 * time.Second)
+
+	True(t, WithinDuration(mockT, a, b, 10*time.Second), "A 10s difference is within a 10s time difference")
+	True(t, WithinDuration(mockT, b, a, 10*time.Second), "A 10s difference is within a 10s time difference")
+
+	False(t, WithinDuration(mockT, a, b, 9*time.Second), "A 10s difference is not within a 9s time difference")
+	False(t, WithinDuration(mockT, b, a, 9*time.Second), "A 10s difference is not within a 9s time difference")
+
+	False(t, WithinDuration(mockT, a, b, -9*time.Second), "A 10s difference is not within a 9s time difference")
+	False(t, WithinDuration(mockT, b, a, -9*time.Second), "A 10s difference is not within a 9s time difference")
+
+	False(t, WithinDuration(mockT, a, b, -11*time.Second), "A 10s difference is not within a 9s time difference")
+	False(t, WithinDuration(mockT, b, a, -11*time.Second), "A 10s difference is not within a 9s time difference")
+}
+
+func TestInDelta(t *testing.T) {
+	mockT := new(testing.T)
+
+	True(t, InDelta(mockT, 1.001, 1, 0.01), "|1.001 - 1| <= 0.01")
+	True(t, InDelta(mockT, 1, 1.001, 0.01), "|1 - 1.001| <= 0.01")
+	True(t, InDelta(mockT, 1, 2, 1), "|1 - 2| <= 1")
+	False(t, InDelta(mockT, 1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail")
+	False(t, InDelta(mockT, 2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail")
+	False(t, InDelta(mockT, "", nil, 1), "Expected non numerals to fail")
+	False(t, InDelta(mockT, 42, math.NaN(), 0.01), "Expected NaN for actual to fail")
+	False(t, InDelta(mockT, math.NaN(), 42, 0.01), "Expected NaN for expected to fail")
+
+	cases := []struct {
+		a, b  interface{}
+		delta float64
+	}{
+		{uint8(2), uint8(1), 1},
+		{uint16(2), uint16(1), 1},
+		{uint32(2), uint32(1), 1},
+		{uint64(2), uint64(1), 1},
+
+		{int(2), int(1), 1},
+		{int8(2), int8(1), 1},
+		{int16(2), int16(1), 1},
+		{int32(2), int32(1), 1},
+		{int64(2), int64(1), 1},
+
+		{float32(2), float32(1), 1},
+		{float64(2), float64(1), 1},
+	}
+
+	for _, tc := range cases {
+		True(t, InDelta(mockT, tc.a, tc.b, tc.delta), "Expected |%V - %V| <= %v", tc.a, tc.b, tc.delta)
+	}
+}
+
+func TestInDeltaSlice(t *testing.T) {
+	mockT := new(testing.T)
+
+	True(t, InDeltaSlice(mockT,
+		[]float64{1.001, 0.999},
+		[]float64{1, 1},
+		0.1), "{1.001, 0.009} is element-wise close to {1, 1} in delta=0.1")
+
+	True(t, InDeltaSlice(mockT,
+		[]float64{1, 2},
+		[]float64{0, 3},
+		1), "{1, 2} is element-wise close to {0, 3} in delta=1")
+
+	False(t, InDeltaSlice(mockT,
+		[]float64{1, 2},
+		[]float64{0, 3},
+		0.1), "{1, 2} is not element-wise close to {0, 3} in delta=0.1")
+
+	False(t, InDeltaSlice(mockT, "", nil, 1), "Expected non numeral slices to fail")
+}
+
+func TestInEpsilon(t *testing.T) {
+	mockT := new(testing.T)
+
+	cases := []struct {
+		a, b    interface{}
+		epsilon float64
+	}{
+		{uint8(2), uint16(2), .001},
+		{2.1, 2.2, 0.1},
+		{2.2, 2.1, 0.1},
+		{-2.1, -2.2, 0.1},
+		{-2.2, -2.1, 0.1},
+		{uint64(100), uint8(101), 0.01},
+		{0.1, -0.1, 2},
+		{0.1, 0, 2},
+	}
+
+	for _, tc := range cases {
+		True(t, InEpsilon(t, tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon), "test: %q", tc)
+	}
+
+	cases = []struct {
+		a, b    interface{}
+		epsilon float64
+	}{
+		{uint8(2), int16(-2), .001},
+		{uint64(100), uint8(102), 0.01},
+		{2.1, 2.2, 0.001},
+		{2.2, 2.1, 0.001},
+		{2.1, -2.2, 1},
+		{2.1, "bla-bla", 0},
+		{0.1, -0.1, 1.99},
+		{0, 0.1, 2}, // expected must be different to zero
+	}
+
+	for _, tc := range cases {
+		False(t, InEpsilon(mockT, tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
+	}
+
+}
+
+func TestInEpsilonSlice(t *testing.T) {
+	mockT := new(testing.T)
+
+	True(t, InEpsilonSlice(mockT,
+		[]float64{2.2, 2.0},
+		[]float64{2.1, 2.1},
+		0.06), "{2.2, 2.0} is element-wise close to {2.1, 2.1} in espilon=0.06")
+
+	False(t, InEpsilonSlice(mockT,
+		[]float64{2.2, 2.0},
+		[]float64{2.1, 2.1},
+		0.04), "{2.2, 2.0} is not element-wise close to {2.1, 2.1} in espilon=0.04")
+
+	False(t, InEpsilonSlice(mockT, "", nil, 1), "Expected non numeral slices to fail")
+}
+
+func TestRegexp(t *testing.T) {
+	mockT := new(testing.T)
+
+	cases := []struct {
+		rx, str string
+	}{
+		{"^start", "start of the line"},
+		{"end$", "in the end"},
+		{"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12.34"},
+	}
+
+	for _, tc := range cases {
+		True(t, Regexp(mockT, tc.rx, tc.str))
+		True(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str))
+		False(t, NotRegexp(mockT, tc.rx, tc.str))
+		False(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str))
+	}
+
+	cases = []struct {
+		rx, str string
+	}{
+		{"^asdfastart", "Not the start of the line"},
+		{"end$", "in the end."},
+		{"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12a.34"},
+	}
+
+	for _, tc := range cases {
+		False(t, Regexp(mockT, tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str)
+		False(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str))
+		True(t, NotRegexp(mockT, tc.rx, tc.str))
+		True(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str))
+	}
+}
+
+func testAutogeneratedFunction() {
+	defer func() {
+		if err := recover(); err == nil {
+			panic("did not panic")
+		}
+		CallerInfo()
+	}()
+	t := struct {
+		io.Closer
+	}{}
+	var c io.Closer
+	c = t
+	c.Close()
+}
+
+func TestCallerInfoWithAutogeneratedFunctions(t *testing.T) {
+	NotPanics(t, func() {
+		testAutogeneratedFunction()
+	})
+}
+
+func TestZero(t *testing.T) {
+	mockT := new(testing.T)
+
+	for _, test := range zeros {
+		True(t, Zero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test)))
+	}
+
+	for _, test := range nonZeros {
+		False(t, Zero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test)))
+	}
+}
+
+func TestNotZero(t *testing.T) {
+	mockT := new(testing.T)
+
+	for _, test := range zeros {
+		False(t, NotZero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test)))
+	}
+
+	for _, test := range nonZeros {
+		True(t, NotZero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test)))
+	}
+}
+
+func TestJSONEq_EqualSONString(t *testing.T) {
+	mockT := new(testing.T)
+	True(t, JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`))
+}
+
+func TestJSONEq_EquivalentButNotEqual(t *testing.T) {
+	mockT := new(testing.T)
+	True(t, JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`))
+}
+
+func TestJSONEq_HashOfArraysAndHashes(t *testing.T) {
+	mockT := new(testing.T)
+	True(t, JSONEq(mockT, "{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
+		"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}"))
+}
+
+func TestJSONEq_Array(t *testing.T) {
+	mockT := new(testing.T)
+	True(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`))
+}
+
+func TestJSONEq_HashAndArrayNotEquivalent(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`))
+}
+
+func TestJSONEq_HashesNotEquivalent(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, JSONEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`))
+}
+
+func TestJSONEq_ActualIsNotJSON(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, JSONEq(mockT, `{"foo": "bar"}`, "Not JSON"))
+}
+
+func TestJSONEq_ExpectedIsNotJSON(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, JSONEq(mockT, "Not JSON", `{"foo": "bar", "hello": "world"}`))
+}
+
+func TestJSONEq_ExpectedAndActualNotJSON(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, JSONEq(mockT, "Not JSON", "Not JSON"))
+}
+
+func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`))
+}
+
+func TestDiff(t *testing.T) {
+	expected := `
+
+Diff:
+--- Expected
++++ Actual
+@@ -1,3 +1,3 @@
+ (struct { foo string }) {
+- foo: (string) (len=5) "hello"
++ foo: (string) (len=3) "bar"
+ }
+`
+	actual := diff(
+		struct{ foo string }{"hello"},
+		struct{ foo string }{"bar"},
+	)
+	Equal(t, expected, actual)
+
+	expected = `
+
+Diff:
+--- Expected
++++ Actual
+@@ -2,5 +2,5 @@
+  (int) 1,
+- (int) 2,
+  (int) 3,
+- (int) 4
++ (int) 5,
++ (int) 7
+ }
+`
+	actual = diff(
+		[]int{1, 2, 3, 4},
+		[]int{1, 3, 5, 7},
+	)
+	Equal(t, expected, actual)
+
+	expected = `
+
+Diff:
+--- Expected
++++ Actual
+@@ -2,4 +2,4 @@
+  (int) 1,
+- (int) 2,
+- (int) 3
++ (int) 3,
++ (int) 5
+ }
+`
+	actual = diff(
+		[]int{1, 2, 3, 4}[0:3],
+		[]int{1, 3, 5, 7}[0:3],
+	)
+	Equal(t, expected, actual)
+
+	expected = `
+
+Diff:
+--- Expected
++++ Actual
+@@ -1,6 +1,6 @@
+ (map[string]int) (len=4) {
+- (string) (len=4) "four": (int) 4,
++ (string) (len=4) "five": (int) 5,
+  (string) (len=3) "one": (int) 1,
+- (string) (len=5) "three": (int) 3,
+- (string) (len=3) "two": (int) 2
++ (string) (len=5) "seven": (int) 7,
++ (string) (len=5) "three": (int) 3
+ }
+`
+
+	actual = diff(
+		map[string]int{"one": 1, "two": 2, "three": 3, "four": 4},
+		map[string]int{"one": 1, "three": 3, "five": 5, "seven": 7},
+	)
+	Equal(t, expected, actual)
+}
+
+func TestDiffEmptyCases(t *testing.T) {
+	Equal(t, "", diff(nil, nil))
+	Equal(t, "", diff(struct{ foo string }{}, nil))
+	Equal(t, "", diff(nil, struct{ foo string }{}))
+	Equal(t, "", diff(1, 2))
+	Equal(t, "", diff(1, 2))
+	Equal(t, "", diff([]int{1}, []bool{true}))
+}
+
+type mockTestingT struct {
+}
+
+func (m *mockTestingT) Errorf(format string, args ...interface{}) {}
+
+func TestFailNowWithPlainTestingT(t *testing.T) {
+	mockT := &mockTestingT{}
+
+	Panics(t, func() {
+		FailNow(mockT, "failed")
+	}, "should panic since mockT is missing FailNow()")
+}
+
+type mockFailNowTestingT struct {
+}
+
+func (m *mockFailNowTestingT) Errorf(format string, args ...interface{}) {}
+
+func (m *mockFailNowTestingT) FailNow() {}
+
+func TestFailNowWithFullTestingT(t *testing.T) {
+	mockT := &mockFailNowTestingT{}
+
+	NotPanics(t, func() {
+		FailNow(mockT, "failed")
+	}, "should call mockT.FailNow() rather than panicking")
+}
diff --git a/go/src/github.com/stretchr/testify/assert/doc.go b/go/src/github.com/stretchr/testify/assert/doc.go
new file mode 100644
index 0000000..c9dccc4
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/assert/doc.go
@@ -0,0 +1,45 @@
+// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.
+//
+// Example Usage
+//
+// The following is a complete example using assert in a standard test function:
+//    import (
+//      "testing"
+//      "github.com/stretchr/testify/assert"
+//    )
+//
+//    func TestSomething(t *testing.T) {
+//
+//      var a string = "Hello"
+//      var b string = "Hello"
+//
+//      assert.Equal(t, a, b, "The two words should be the same.")
+//
+//    }
+//
+// if you assert many times, use the format below:
+//
+//    import (
+//      "testing"
+//      "github.com/stretchr/testify/assert"
+//    )
+//
+//    func TestSomething(t *testing.T) {
+//      assert := assert.New(t)
+//
+//      var a string = "Hello"
+//      var b string = "Hello"
+//
+//      assert.Equal(a, b, "The two words should be the same.")
+//    }
+//
+// Assertions
+//
+// Assertions allow you to easily write test code, and are global funcs in the `assert` package.
+// All assertion functions take, as the first argument, the `*testing.T` object provided by the
+// testing framework. This allows the assertion funcs to write the failings and other details to
+// the correct place.
+//
+// Every assertion function also takes an optional string message as the final argument,
+// allowing custom error messages to be appended to the message the assertion method outputs.
+package assert
diff --git a/go/src/github.com/stretchr/testify/assert/errors.go b/go/src/github.com/stretchr/testify/assert/errors.go
new file mode 100644
index 0000000..ac9dc9d
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/assert/errors.go
@@ -0,0 +1,10 @@
+package assert
+
+import (
+	"errors"
+)
+
+// AnError is an error instance useful for testing.  If the code does not care
+// about error specifics, and only needs to return the error for example, this
+// error should be used to make the test code more readable.
+var AnError = errors.New("assert.AnError general error for testing")
diff --git a/go/src/github.com/stretchr/testify/assert/forward_assertions.go b/go/src/github.com/stretchr/testify/assert/forward_assertions.go
new file mode 100644
index 0000000..b867e95
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/assert/forward_assertions.go
@@ -0,0 +1,16 @@
+package assert
+
+// Assertions provides assertion methods around the
+// TestingT interface.
+type Assertions struct {
+	t TestingT
+}
+
+// New makes a new Assertions object for the specified TestingT.
+func New(t TestingT) *Assertions {
+	return &Assertions{
+		t: t,
+	}
+}
+
+//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl
diff --git a/go/src/github.com/stretchr/testify/assert/forward_assertions_test.go b/go/src/github.com/stretchr/testify/assert/forward_assertions_test.go
new file mode 100644
index 0000000..22e1df1
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/assert/forward_assertions_test.go
@@ -0,0 +1,611 @@
+package assert
+
+import (
+	"errors"
+	"regexp"
+	"testing"
+	"time"
+)
+
+func TestImplementsWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	if !assert.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) {
+		t.Error("Implements method should return true: AssertionTesterConformingObject implements AssertionTesterInterface")
+	}
+	if assert.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) {
+		t.Error("Implements method should return false: AssertionTesterNonConformingObject does not implements AssertionTesterInterface")
+	}
+}
+
+func TestIsTypeWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	if !assert.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) {
+		t.Error("IsType should return true: AssertionTesterConformingObject is the same type as AssertionTesterConformingObject")
+	}
+	if assert.IsType(new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) {
+		t.Error("IsType should return false: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject")
+	}
+
+}
+
+func TestEqualWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	if !assert.Equal("Hello World", "Hello World") {
+		t.Error("Equal should return true")
+	}
+	if !assert.Equal(123, 123) {
+		t.Error("Equal should return true")
+	}
+	if !assert.Equal(123.5, 123.5) {
+		t.Error("Equal should return true")
+	}
+	if !assert.Equal([]byte("Hello World"), []byte("Hello World")) {
+		t.Error("Equal should return true")
+	}
+	if !assert.Equal(nil, nil) {
+		t.Error("Equal should return true")
+	}
+}
+
+func TestEqualValuesWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	if !assert.EqualValues(uint32(10), int32(10)) {
+		t.Error("EqualValues should return true")
+	}
+}
+
+func TestNotNilWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	if !assert.NotNil(new(AssertionTesterConformingObject)) {
+		t.Error("NotNil should return true: object is not nil")
+	}
+	if assert.NotNil(nil) {
+		t.Error("NotNil should return false: object is nil")
+	}
+
+}
+
+func TestNilWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	if !assert.Nil(nil) {
+		t.Error("Nil should return true: object is nil")
+	}
+	if assert.Nil(new(AssertionTesterConformingObject)) {
+		t.Error("Nil should return false: object is not nil")
+	}
+
+}
+
+func TestTrueWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	if !assert.True(true) {
+		t.Error("True should return true")
+	}
+	if assert.True(false) {
+		t.Error("True should return false")
+	}
+
+}
+
+func TestFalseWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	if !assert.False(false) {
+		t.Error("False should return true")
+	}
+	if assert.False(true) {
+		t.Error("False should return false")
+	}
+
+}
+
+func TestExactlyWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	a := float32(1)
+	b := float64(1)
+	c := float32(1)
+	d := float32(2)
+
+	if assert.Exactly(a, b) {
+		t.Error("Exactly should return false")
+	}
+	if assert.Exactly(a, d) {
+		t.Error("Exactly should return false")
+	}
+	if !assert.Exactly(a, c) {
+		t.Error("Exactly should return true")
+	}
+
+	if assert.Exactly(nil, a) {
+		t.Error("Exactly should return false")
+	}
+	if assert.Exactly(a, nil) {
+		t.Error("Exactly should return false")
+	}
+
+}
+
+func TestNotEqualWrapper(t *testing.T) {
+
+	assert := New(new(testing.T))
+
+	if !assert.NotEqual("Hello World", "Hello World!") {
+		t.Error("NotEqual should return true")
+	}
+	if !assert.NotEqual(123, 1234) {
+		t.Error("NotEqual should return true")
+	}
+	if !assert.NotEqual(123.5, 123.55) {
+		t.Error("NotEqual should return true")
+	}
+	if !assert.NotEqual([]byte("Hello World"), []byte("Hello World!")) {
+		t.Error("NotEqual should return true")
+	}
+	if !assert.NotEqual(nil, new(AssertionTesterConformingObject)) {
+		t.Error("NotEqual should return true")
+	}
+}
+
+func TestContainsWrapper(t *testing.T) {
+
+	assert := New(new(testing.T))
+	list := []string{"Foo", "Bar"}
+
+	if !assert.Contains("Hello World", "Hello") {
+		t.Error("Contains should return true: \"Hello World\" contains \"Hello\"")
+	}
+	if assert.Contains("Hello World", "Salut") {
+		t.Error("Contains should return false: \"Hello World\" does not contain \"Salut\"")
+	}
+
+	if !assert.Contains(list, "Foo") {
+		t.Error("Contains should return true: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"")
+	}
+	if assert.Contains(list, "Salut") {
+		t.Error("Contains should return false: \"[\"Foo\", \"Bar\"]\" does not contain \"Salut\"")
+	}
+
+}
+
+func TestNotContainsWrapper(t *testing.T) {
+
+	assert := New(new(testing.T))
+	list := []string{"Foo", "Bar"}
+
+	if !assert.NotContains("Hello World", "Hello!") {
+		t.Error("NotContains should return true: \"Hello World\" does not contain \"Hello!\"")
+	}
+	if assert.NotContains("Hello World", "Hello") {
+		t.Error("NotContains should return false: \"Hello World\" contains \"Hello\"")
+	}
+
+	if !assert.NotContains(list, "Foo!") {
+		t.Error("NotContains should return true: \"[\"Foo\", \"Bar\"]\" does not contain \"Foo!\"")
+	}
+	if assert.NotContains(list, "Foo") {
+		t.Error("NotContains should return false: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"")
+	}
+
+}
+
+func TestConditionWrapper(t *testing.T) {
+
+	assert := New(new(testing.T))
+
+	if !assert.Condition(func() bool { return true }, "Truth") {
+		t.Error("Condition should return true")
+	}
+
+	if assert.Condition(func() bool { return false }, "Lie") {
+		t.Error("Condition should return false")
+	}
+
+}
+
+func TestDidPanicWrapper(t *testing.T) {
+
+	if funcDidPanic, _ := didPanic(func() {
+		panic("Panic!")
+	}); !funcDidPanic {
+		t.Error("didPanic should return true")
+	}
+
+	if funcDidPanic, _ := didPanic(func() {
+	}); funcDidPanic {
+		t.Error("didPanic should return false")
+	}
+
+}
+
+func TestPanicsWrapper(t *testing.T) {
+
+	assert := New(new(testing.T))
+
+	if !assert.Panics(func() {
+		panic("Panic!")
+	}) {
+		t.Error("Panics should return true")
+	}
+
+	if assert.Panics(func() {
+	}) {
+		t.Error("Panics should return false")
+	}
+
+}
+
+func TestNotPanicsWrapper(t *testing.T) {
+
+	assert := New(new(testing.T))
+
+	if !assert.NotPanics(func() {
+	}) {
+		t.Error("NotPanics should return true")
+	}
+
+	if assert.NotPanics(func() {
+		panic("Panic!")
+	}) {
+		t.Error("NotPanics should return false")
+	}
+
+}
+
+func TestNoErrorWrapper(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+
+	// start with a nil error
+	var err error
+
+	assert.True(mockAssert.NoError(err), "NoError should return True for nil arg")
+
+	// now set an error
+	err = errors.New("Some error")
+
+	assert.False(mockAssert.NoError(err), "NoError with error should return False")
+
+}
+
+func TestErrorWrapper(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+
+	// start with a nil error
+	var err error
+
+	assert.False(mockAssert.Error(err), "Error should return False for nil arg")
+
+	// now set an error
+	err = errors.New("Some error")
+
+	assert.True(mockAssert.Error(err), "Error with error should return True")
+
+}
+
+func TestEqualErrorWrapper(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+
+	// start with a nil error
+	var err error
+	assert.False(mockAssert.EqualError(err, ""),
+		"EqualError should return false for nil arg")
+
+	// now set an error
+	err = errors.New("some error")
+	assert.False(mockAssert.EqualError(err, "Not some error"),
+		"EqualError should return false for different error string")
+	assert.True(mockAssert.EqualError(err, "some error"),
+		"EqualError should return true")
+}
+
+func TestEmptyWrapper(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+
+	assert.True(mockAssert.Empty(""), "Empty string is empty")
+	assert.True(mockAssert.Empty(nil), "Nil is empty")
+	assert.True(mockAssert.Empty([]string{}), "Empty string array is empty")
+	assert.True(mockAssert.Empty(0), "Zero int value is empty")
+	assert.True(mockAssert.Empty(false), "False value is empty")
+
+	assert.False(mockAssert.Empty("something"), "Non Empty string is not empty")
+	assert.False(mockAssert.Empty(errors.New("something")), "Non nil object is not empty")
+	assert.False(mockAssert.Empty([]string{"something"}), "Non empty string array is not empty")
+	assert.False(mockAssert.Empty(1), "Non-zero int value is not empty")
+	assert.False(mockAssert.Empty(true), "True value is not empty")
+
+}
+
+func TestNotEmptyWrapper(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+
+	assert.False(mockAssert.NotEmpty(""), "Empty string is empty")
+	assert.False(mockAssert.NotEmpty(nil), "Nil is empty")
+	assert.False(mockAssert.NotEmpty([]string{}), "Empty string array is empty")
+	assert.False(mockAssert.NotEmpty(0), "Zero int value is empty")
+	assert.False(mockAssert.NotEmpty(false), "False value is empty")
+
+	assert.True(mockAssert.NotEmpty("something"), "Non Empty string is not empty")
+	assert.True(mockAssert.NotEmpty(errors.New("something")), "Non nil object is not empty")
+	assert.True(mockAssert.NotEmpty([]string{"something"}), "Non empty string array is not empty")
+	assert.True(mockAssert.NotEmpty(1), "Non-zero int value is not empty")
+	assert.True(mockAssert.NotEmpty(true), "True value is not empty")
+
+}
+
+func TestLenWrapper(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+
+	assert.False(mockAssert.Len(nil, 0), "nil does not have length")
+	assert.False(mockAssert.Len(0, 0), "int does not have length")
+	assert.False(mockAssert.Len(true, 0), "true does not have length")
+	assert.False(mockAssert.Len(false, 0), "false does not have length")
+	assert.False(mockAssert.Len('A', 0), "Rune does not have length")
+	assert.False(mockAssert.Len(struct{}{}, 0), "Struct does not have length")
+
+	ch := make(chan int, 5)
+	ch <- 1
+	ch <- 2
+	ch <- 3
+
+	cases := []struct {
+		v interface{}
+		l int
+	}{
+		{[]int{1, 2, 3}, 3},
+		{[...]int{1, 2, 3}, 3},
+		{"ABC", 3},
+		{map[int]int{1: 2, 2: 4, 3: 6}, 3},
+		{ch, 3},
+
+		{[]int{}, 0},
+		{map[int]int{}, 0},
+		{make(chan int), 0},
+
+		{[]int(nil), 0},
+		{map[int]int(nil), 0},
+		{(chan int)(nil), 0},
+	}
+
+	for _, c := range cases {
+		assert.True(mockAssert.Len(c.v, c.l), "%#v have %d items", c.v, c.l)
+	}
+}
+
+func TestWithinDurationWrapper(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+	a := time.Now()
+	b := a.Add(10 * time.Second)
+
+	assert.True(mockAssert.WithinDuration(a, b, 10*time.Second), "A 10s difference is within a 10s time difference")
+	assert.True(mockAssert.WithinDuration(b, a, 10*time.Second), "A 10s difference is within a 10s time difference")
+
+	assert.False(mockAssert.WithinDuration(a, b, 9*time.Second), "A 10s difference is not within a 9s time difference")
+	assert.False(mockAssert.WithinDuration(b, a, 9*time.Second), "A 10s difference is not within a 9s time difference")
+
+	assert.False(mockAssert.WithinDuration(a, b, -9*time.Second), "A 10s difference is not within a 9s time difference")
+	assert.False(mockAssert.WithinDuration(b, a, -9*time.Second), "A 10s difference is not within a 9s time difference")
+
+	assert.False(mockAssert.WithinDuration(a, b, -11*time.Second), "A 10s difference is not within a 9s time difference")
+	assert.False(mockAssert.WithinDuration(b, a, -11*time.Second), "A 10s difference is not within a 9s time difference")
+}
+
+func TestInDeltaWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	True(t, assert.InDelta(1.001, 1, 0.01), "|1.001 - 1| <= 0.01")
+	True(t, assert.InDelta(1, 1.001, 0.01), "|1 - 1.001| <= 0.01")
+	True(t, assert.InDelta(1, 2, 1), "|1 - 2| <= 1")
+	False(t, assert.InDelta(1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail")
+	False(t, assert.InDelta(2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail")
+	False(t, assert.InDelta("", nil, 1), "Expected non numerals to fail")
+
+	cases := []struct {
+		a, b  interface{}
+		delta float64
+	}{
+		{uint8(2), uint8(1), 1},
+		{uint16(2), uint16(1), 1},
+		{uint32(2), uint32(1), 1},
+		{uint64(2), uint64(1), 1},
+
+		{int(2), int(1), 1},
+		{int8(2), int8(1), 1},
+		{int16(2), int16(1), 1},
+		{int32(2), int32(1), 1},
+		{int64(2), int64(1), 1},
+
+		{float32(2), float32(1), 1},
+		{float64(2), float64(1), 1},
+	}
+
+	for _, tc := range cases {
+		True(t, assert.InDelta(tc.a, tc.b, tc.delta), "Expected |%V - %V| <= %v", tc.a, tc.b, tc.delta)
+	}
+}
+
+func TestInEpsilonWrapper(t *testing.T) {
+	assert := New(new(testing.T))
+
+	cases := []struct {
+		a, b    interface{}
+		epsilon float64
+	}{
+		{uint8(2), uint16(2), .001},
+		{2.1, 2.2, 0.1},
+		{2.2, 2.1, 0.1},
+		{-2.1, -2.2, 0.1},
+		{-2.2, -2.1, 0.1},
+		{uint64(100), uint8(101), 0.01},
+		{0.1, -0.1, 2},
+	}
+
+	for _, tc := range cases {
+		True(t, assert.InEpsilon(tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
+	}
+
+	cases = []struct {
+		a, b    interface{}
+		epsilon float64
+	}{
+		{uint8(2), int16(-2), .001},
+		{uint64(100), uint8(102), 0.01},
+		{2.1, 2.2, 0.001},
+		{2.2, 2.1, 0.001},
+		{2.1, -2.2, 1},
+		{2.1, "bla-bla", 0},
+		{0.1, -0.1, 1.99},
+	}
+
+	for _, tc := range cases {
+		False(t, assert.InEpsilon(tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
+	}
+}
+
+func TestRegexpWrapper(t *testing.T) {
+
+	assert := New(new(testing.T))
+
+	cases := []struct {
+		rx, str string
+	}{
+		{"^start", "start of the line"},
+		{"end$", "in the end"},
+		{"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12.34"},
+	}
+
+	for _, tc := range cases {
+		True(t, assert.Regexp(tc.rx, tc.str))
+		True(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str))
+		False(t, assert.NotRegexp(tc.rx, tc.str))
+		False(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str))
+	}
+
+	cases = []struct {
+		rx, str string
+	}{
+		{"^asdfastart", "Not the start of the line"},
+		{"end$", "in the end."},
+		{"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12a.34"},
+	}
+
+	for _, tc := range cases {
+		False(t, assert.Regexp(tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str)
+		False(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str))
+		True(t, assert.NotRegexp(tc.rx, tc.str))
+		True(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str))
+	}
+}
+
+func TestZeroWrapper(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+
+	for _, test := range zeros {
+		assert.True(mockAssert.Zero(test), "Zero should return true for %v", test)
+	}
+
+	for _, test := range nonZeros {
+		assert.False(mockAssert.Zero(test), "Zero should return false for %v", test)
+	}
+}
+
+func TestNotZeroWrapper(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+
+	for _, test := range zeros {
+		assert.False(mockAssert.NotZero(test), "Zero should return true for %v", test)
+	}
+
+	for _, test := range nonZeros {
+		assert.True(mockAssert.NotZero(test), "Zero should return false for %v", test)
+	}
+}
+
+func TestJSONEqWrapper_EqualSONString(t *testing.T) {
+	assert := New(new(testing.T))
+	if !assert.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) {
+		t.Error("JSONEq should return true")
+	}
+
+}
+
+func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) {
+	assert := New(new(testing.T))
+	if !assert.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
+		t.Error("JSONEq should return true")
+	}
+
+}
+
+func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) {
+	assert := New(new(testing.T))
+	if !assert.JSONEq("{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
+		"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}") {
+		t.Error("JSONEq should return true")
+	}
+}
+
+func TestJSONEqWrapper_Array(t *testing.T) {
+	assert := New(new(testing.T))
+	if !assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) {
+		t.Error("JSONEq should return true")
+	}
+
+}
+
+func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) {
+		t.Error("JSONEq should return false")
+	}
+}
+
+func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.JSONEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
+		t.Error("JSONEq should return false")
+	}
+}
+
+func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.JSONEq(`{"foo": "bar"}`, "Not JSON") {
+		t.Error("JSONEq should return false")
+	}
+}
+
+func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.JSONEq("Not JSON", `{"foo": "bar", "hello": "world"}`) {
+		t.Error("JSONEq should return false")
+	}
+}
+
+func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.JSONEq("Not JSON", "Not JSON") {
+		t.Error("JSONEq should return false")
+	}
+}
+
+func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) {
+		t.Error("JSONEq should return false")
+	}
+}
diff --git a/go/src/github.com/stretchr/testify/assert/http_assertions.go b/go/src/github.com/stretchr/testify/assert/http_assertions.go
new file mode 100644
index 0000000..e1b9442
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/assert/http_assertions.go
@@ -0,0 +1,106 @@
+package assert
+
+import (
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
+	"strings"
+)
+
+// httpCode is a helper that returns HTTP code of the response. It returns -1
+// if building a new request fails.
+func httpCode(handler http.HandlerFunc, method, url string, values url.Values) int {
+	w := httptest.NewRecorder()
+	req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
+	if err != nil {
+		return -1
+	}
+	handler(w, req)
+	return w.Code
+}
+
+// HTTPSuccess asserts that a specified handler returns a success status code.
+//
+//  assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
+//
+// Returns whether the assertion was successful (true) or not (false).
+func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
+	code := httpCode(handler, method, url, values)
+	if code == -1 {
+		return false
+	}
+	return code >= http.StatusOK && code <= http.StatusPartialContent
+}
+
+// HTTPRedirect asserts that a specified handler returns a redirect status code.
+//
+//  assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
+//
+// Returns whether the assertion was successful (true) or not (false).
+func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
+	code := httpCode(handler, method, url, values)
+	if code == -1 {
+		return false
+	}
+	return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect
+}
+
+// HTTPError asserts that a specified handler returns an error status code.
+//
+//  assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
+//
+// Returns whether the assertion was successful (true) or not (false).
+func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
+	code := httpCode(handler, method, url, values)
+	if code == -1 {
+		return false
+	}
+	return code >= http.StatusBadRequest
+}
+
+// HTTPBody is a helper that returns HTTP body of the response. It returns
+// empty string if building a new request fails.
+func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string {
+	w := httptest.NewRecorder()
+	req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
+	if err != nil {
+		return ""
+	}
+	handler(w, req)
+	return w.Body.String()
+}
+
+// HTTPBodyContains asserts that a specified handler returns a
+// body that contains a string.
+//
+//  assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
+	body := HTTPBody(handler, method, url, values)
+
+	contains := strings.Contains(body, fmt.Sprint(str))
+	if !contains {
+		Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body))
+	}
+
+	return contains
+}
+
+// HTTPBodyNotContains asserts that a specified handler returns a
+// body that does not contain a string.
+//
+//  assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//
+// Returns whether the assertion was successful (true) or not (false).
+func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
+	body := HTTPBody(handler, method, url, values)
+
+	contains := strings.Contains(body, fmt.Sprint(str))
+	if contains {
+		Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)
+	}
+
+	return !contains
+}
diff --git a/go/src/github.com/stretchr/testify/assert/http_assertions_test.go b/go/src/github.com/stretchr/testify/assert/http_assertions_test.go
new file mode 100644
index 0000000..684c2d5
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/assert/http_assertions_test.go
@@ -0,0 +1,86 @@
+package assert
+
+import (
+	"fmt"
+	"net/http"
+	"net/url"
+	"testing"
+)
+
+func httpOK(w http.ResponseWriter, r *http.Request) {
+	w.WriteHeader(http.StatusOK)
+}
+
+func httpRedirect(w http.ResponseWriter, r *http.Request) {
+	w.WriteHeader(http.StatusTemporaryRedirect)
+}
+
+func httpError(w http.ResponseWriter, r *http.Request) {
+	w.WriteHeader(http.StatusInternalServerError)
+}
+
+func TestHTTPStatuses(t *testing.T) {
+	assert := New(t)
+	mockT := new(testing.T)
+
+	assert.Equal(HTTPSuccess(mockT, httpOK, "GET", "/", nil), true)
+	assert.Equal(HTTPSuccess(mockT, httpRedirect, "GET", "/", nil), false)
+	assert.Equal(HTTPSuccess(mockT, httpError, "GET", "/", nil), false)
+
+	assert.Equal(HTTPRedirect(mockT, httpOK, "GET", "/", nil), false)
+	assert.Equal(HTTPRedirect(mockT, httpRedirect, "GET", "/", nil), true)
+	assert.Equal(HTTPRedirect(mockT, httpError, "GET", "/", nil), false)
+
+	assert.Equal(HTTPError(mockT, httpOK, "GET", "/", nil), false)
+	assert.Equal(HTTPError(mockT, httpRedirect, "GET", "/", nil), false)
+	assert.Equal(HTTPError(mockT, httpError, "GET", "/", nil), true)
+}
+
+func TestHTTPStatusesWrapper(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+
+	assert.Equal(mockAssert.HTTPSuccess(httpOK, "GET", "/", nil), true)
+	assert.Equal(mockAssert.HTTPSuccess(httpRedirect, "GET", "/", nil), false)
+	assert.Equal(mockAssert.HTTPSuccess(httpError, "GET", "/", nil), false)
+
+	assert.Equal(mockAssert.HTTPRedirect(httpOK, "GET", "/", nil), false)
+	assert.Equal(mockAssert.HTTPRedirect(httpRedirect, "GET", "/", nil), true)
+	assert.Equal(mockAssert.HTTPRedirect(httpError, "GET", "/", nil), false)
+
+	assert.Equal(mockAssert.HTTPError(httpOK, "GET", "/", nil), false)
+	assert.Equal(mockAssert.HTTPError(httpRedirect, "GET", "/", nil), false)
+	assert.Equal(mockAssert.HTTPError(httpError, "GET", "/", nil), true)
+}
+
+func httpHelloName(w http.ResponseWriter, r *http.Request) {
+	name := r.FormValue("name")
+	w.Write([]byte(fmt.Sprintf("Hello, %s!", name)))
+}
+
+func TestHttpBody(t *testing.T) {
+	assert := New(t)
+	mockT := new(testing.T)
+
+	assert.True(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
+	assert.True(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
+	assert.False(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
+
+	assert.False(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
+	assert.False(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
+	assert.True(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
+}
+
+func TestHttpBodyWrappers(t *testing.T) {
+	assert := New(t)
+	mockAssert := New(new(testing.T))
+
+	assert.True(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
+	assert.True(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
+	assert.False(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
+
+	assert.False(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
+	assert.False(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
+	assert.True(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
+
+}
diff --git a/go/src/github.com/stretchr/testify/doc.go b/go/src/github.com/stretchr/testify/doc.go
new file mode 100644
index 0000000..377d5cc
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/doc.go
@@ -0,0 +1,22 @@
+// Package testify is a set of packages that provide many tools for testifying that your code will behave as you intend.
+//
+// testify contains the following packages:
+//
+// The assert package provides a comprehensive set of assertion functions that tie in to the Go testing system.
+//
+// The http package contains tools to make it easier to test http activity using the Go testing system.
+//
+// The mock package provides a system by which it is possible to mock your objects and verify calls are happening as expected.
+//
+// The suite package provides a basic structure for using structs as testing suites, and methods on those structs as tests.  It includes setup/teardown functionality in the way of interfaces.
+package testify
+
+// blank imports help docs.
+import (
+	// assert package
+	_ "github.com/stretchr/testify/assert"
+	// http package
+	_ "github.com/stretchr/testify/http"
+	// mock package
+	_ "github.com/stretchr/testify/mock"
+)
diff --git a/go/src/github.com/stretchr/testify/http/doc.go b/go/src/github.com/stretchr/testify/http/doc.go
new file mode 100644
index 0000000..695167c
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/http/doc.go
@@ -0,0 +1,2 @@
+// Package http DEPRECATED USE net/http/httptest
+package http
diff --git a/go/src/github.com/stretchr/testify/http/test_response_writer.go b/go/src/github.com/stretchr/testify/http/test_response_writer.go
new file mode 100644
index 0000000..5c3f813
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/http/test_response_writer.go
@@ -0,0 +1,49 @@
+package http
+
+import (
+	"net/http"
+)
+
+// TestResponseWriter DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
+type TestResponseWriter struct {
+
+	// StatusCode is the last int written by the call to WriteHeader(int)
+	StatusCode int
+
+	// Output is a string containing the written bytes using the Write([]byte) func.
+	Output string
+
+	// header is the internal storage of the http.Header object
+	header http.Header
+}
+
+// Header DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
+func (rw *TestResponseWriter) Header() http.Header {
+
+	if rw.header == nil {
+		rw.header = make(http.Header)
+	}
+
+	return rw.header
+}
+
+// Write DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
+func (rw *TestResponseWriter) Write(bytes []byte) (int, error) {
+
+	// assume 200 success if no header has been set
+	if rw.StatusCode == 0 {
+		rw.WriteHeader(200)
+	}
+
+	// add these bytes to the output string
+	rw.Output = rw.Output + string(bytes)
+
+	// return normal values
+	return 0, nil
+
+}
+
+// WriteHeader DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
+func (rw *TestResponseWriter) WriteHeader(i int) {
+	rw.StatusCode = i
+}
diff --git a/go/src/github.com/stretchr/testify/http/test_round_tripper.go b/go/src/github.com/stretchr/testify/http/test_round_tripper.go
new file mode 100644
index 0000000..b1e32f1
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/http/test_round_tripper.go
@@ -0,0 +1,17 @@
+package http
+
+import (
+	"github.com/stretchr/testify/mock"
+	"net/http"
+)
+
+// TestRoundTripper DEPRECATED USE net/http/httptest
+type TestRoundTripper struct {
+	mock.Mock
+}
+
+// RoundTrip DEPRECATED USE net/http/httptest
+func (t *TestRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
+	args := t.Called(req)
+	return args.Get(0).(*http.Response), args.Error(1)
+}
diff --git a/go/src/github.com/stretchr/testify/mock/doc.go b/go/src/github.com/stretchr/testify/mock/doc.go
new file mode 100644
index 0000000..7324128
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/mock/doc.go
@@ -0,0 +1,44 @@
+// Package mock provides a system by which it is possible to mock your objects
+// and verify calls are happening as expected.
+//
+// Example Usage
+//
+// The mock package provides an object, Mock, that tracks activity on another object.  It is usually
+// embedded into a test object as shown below:
+//
+//   type MyTestObject struct {
+//     // add a Mock object instance
+//     mock.Mock
+//
+//     // other fields go here as normal
+//   }
+//
+// When implementing the methods of an interface, you wire your functions up
+// to call the Mock.Called(args...) method, and return the appropriate values.
+//
+// For example, to mock a method that saves the name and age of a person and returns
+// the year of their birth or an error, you might write this:
+//
+//     func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) {
+//       args := o.Called(firstname, lastname, age)
+//       return args.Int(0), args.Error(1)
+//     }
+//
+// The Int, Error and Bool methods are examples of strongly typed getters that take the argument
+// index position. Given this argument list:
+//
+//     (12, true, "Something")
+//
+// You could read them out strongly typed like this:
+//
+//     args.Int(0)
+//     args.Bool(1)
+//     args.String(2)
+//
+// For objects of your own type, use the generic Arguments.Get(index) method and make a type assertion:
+//
+//     return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine)
+//
+// This may cause a panic if the object you are getting is nil (the type assertion will fail), in those
+// cases you should check for nil first.
+package mock
diff --git a/go/src/github.com/stretchr/testify/mock/mock.go b/go/src/github.com/stretchr/testify/mock/mock.go
new file mode 100644
index 0000000..cba9009
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/mock/mock.go
@@ -0,0 +1,693 @@
+package mock
+
+import (
+	"fmt"
+	"reflect"
+	"regexp"
+	"runtime"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/stretchr/objx"
+	"github.com/stretchr/testify/assert"
+)
+
+// TestingT is an interface wrapper around *testing.T
+type TestingT interface {
+	Logf(format string, args ...interface{})
+	Errorf(format string, args ...interface{})
+	FailNow()
+}
+
+/*
+	Call
+*/
+
+// Call represents a method call and is used for setting expectations,
+// as well as recording activity.
+type Call struct {
+	Parent *Mock
+
+	// The name of the method that was or will be called.
+	Method string
+
+	// Holds the arguments of the method.
+	Arguments Arguments
+
+	// Holds the arguments that should be returned when
+	// this method is called.
+	ReturnArguments Arguments
+
+	// The number of times to return the return arguments when setting
+	// expectations. 0 means to always return the value.
+	Repeatability int
+
+	// Amount of times this call has been called
+	totalCalls int
+
+	// Holds a channel that will be used to block the Return until it either
+	// recieves a message or is closed. nil means it returns immediately.
+	WaitFor <-chan time.Time
+
+	// Holds a handler used to manipulate arguments content that are passed by
+	// reference. It's useful when mocking methods such as unmarshalers or
+	// decoders.
+	RunFn func(Arguments)
+}
+
+func newCall(parent *Mock, methodName string, methodArguments ...interface{}) *Call {
+	return &Call{
+		Parent:          parent,
+		Method:          methodName,
+		Arguments:       methodArguments,
+		ReturnArguments: make([]interface{}, 0),
+		Repeatability:   0,
+		WaitFor:         nil,
+		RunFn:           nil,
+	}
+}
+
+func (c *Call) lock() {
+	c.Parent.mutex.Lock()
+}
+
+func (c *Call) unlock() {
+	c.Parent.mutex.Unlock()
+}
+
+// Return specifies the return arguments for the expectation.
+//
+//    Mock.On("DoSomething").Return(errors.New("failed"))
+func (c *Call) Return(returnArguments ...interface{}) *Call {
+	c.lock()
+	defer c.unlock()
+
+	c.ReturnArguments = returnArguments
+
+	return c
+}
+
+// Once indicates that that the mock should only return the value once.
+//
+//    Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once()
+func (c *Call) Once() *Call {
+	return c.Times(1)
+}
+
+// Twice indicates that that the mock should only return the value twice.
+//
+//    Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice()
+func (c *Call) Twice() *Call {
+	return c.Times(2)
+}
+
+// Times indicates that that the mock should only return the indicated number
+// of times.
+//
+//    Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5)
+func (c *Call) Times(i int) *Call {
+	c.lock()
+	defer c.unlock()
+	c.Repeatability = i
+	return c
+}
+
+// WaitUntil sets the channel that will block the mock's return until its closed
+// or a message is received.
+//
+//    Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second))
+func (c *Call) WaitUntil(w <-chan time.Time) *Call {
+	c.lock()
+	defer c.unlock()
+	c.WaitFor = w
+	return c
+}
+
+// After sets how long to block until the call returns
+//
+//    Mock.On("MyMethod", arg1, arg2).After(time.Second)
+func (c *Call) After(d time.Duration) *Call {
+	return c.WaitUntil(time.After(d))
+}
+
+// Run sets a handler to be called before returning. It can be used when
+// mocking a method such as unmarshalers that takes a pointer to a struct and
+// sets properties in such struct
+//
+//    Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}").Return().Run(func(args Arguments) {
+//    	arg := args.Get(0).(*map[string]interface{})
+//    	arg["foo"] = "bar"
+//    })
+func (c *Call) Run(fn func(Arguments)) *Call {
+	c.lock()
+	defer c.unlock()
+	c.RunFn = fn
+	return c
+}
+
+// On chains a new expectation description onto the mocked interface. This
+// allows syntax like.
+//
+//    Mock.
+//       On("MyMethod", 1).Return(nil).
+//       On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error"))
+func (c *Call) On(methodName string, arguments ...interface{}) *Call {
+	return c.Parent.On(methodName, arguments...)
+}
+
+// Mock is the workhorse used to track activity on another object.
+// For an example of its usage, refer to the "Example Usage" section at the top
+// of this document.
+type Mock struct {
+	// Represents the calls that are expected of
+	// an object.
+	ExpectedCalls []*Call
+
+	// Holds the calls that were made to this mocked object.
+	Calls []Call
+
+	// TestData holds any data that might be useful for testing.  Testify ignores
+	// this data completely allowing you to do whatever you like with it.
+	testData objx.Map
+
+	mutex sync.Mutex
+}
+
+// TestData holds any data that might be useful for testing.  Testify ignores
+// this data completely allowing you to do whatever you like with it.
+func (m *Mock) TestData() objx.Map {
+
+	if m.testData == nil {
+		m.testData = make(objx.Map)
+	}
+
+	return m.testData
+}
+
+/*
+	Setting expectations
+*/
+
+// On starts a description of an expectation of the specified method
+// being called.
+//
+//     Mock.On("MyMethod", arg1, arg2)
+func (m *Mock) On(methodName string, arguments ...interface{}) *Call {
+	for _, arg := range arguments {
+		if v := reflect.ValueOf(arg); v.Kind() == reflect.Func {
+			panic(fmt.Sprintf("cannot use Func in expectations. Use mock.AnythingOfType(\"%T\")", arg))
+		}
+	}
+
+	m.mutex.Lock()
+	defer m.mutex.Unlock()
+	c := newCall(m, methodName, arguments...)
+	m.ExpectedCalls = append(m.ExpectedCalls, c)
+	return c
+}
+
+// /*
+// 	Recording and responding to activity
+// */
+
+func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *Call) {
+	m.mutex.Lock()
+	defer m.mutex.Unlock()
+	for i, call := range m.ExpectedCalls {
+		if call.Method == method && call.Repeatability > -1 {
+
+			_, diffCount := call.Arguments.Diff(arguments)
+			if diffCount == 0 {
+				return i, call
+			}
+
+		}
+	}
+	return -1, nil
+}
+
+func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) {
+	diffCount := 0
+	var closestCall *Call
+
+	for _, call := range m.expectedCalls() {
+		if call.Method == method {
+
+			_, tempDiffCount := call.Arguments.Diff(arguments)
+			if tempDiffCount < diffCount || diffCount == 0 {
+				diffCount = tempDiffCount
+				closestCall = call
+			}
+
+		}
+	}
+
+	if closestCall == nil {
+		return false, nil
+	}
+
+	return true, closestCall
+}
+
+func callString(method string, arguments Arguments, includeArgumentValues bool) string {
+
+	var argValsString string
+	if includeArgumentValues {
+		var argVals []string
+		for argIndex, arg := range arguments {
+			argVals = append(argVals, fmt.Sprintf("%d: %#v", argIndex, arg))
+		}
+		argValsString = fmt.Sprintf("\n\t\t%s", strings.Join(argVals, "\n\t\t"))
+	}
+
+	return fmt.Sprintf("%s(%s)%s", method, arguments.String(), argValsString)
+}
+
+// Called tells the mock object that a method has been called, and gets an array
+// of arguments to return.  Panics if the call is unexpected (i.e. not preceded by
+// appropriate .On .Return() calls)
+// If Call.WaitFor is set, blocks until the channel is closed or receives a message.
+func (m *Mock) Called(arguments ...interface{}) Arguments {
+	// get the calling function's name
+	pc, _, _, ok := runtime.Caller(1)
+	if !ok {
+		panic("Couldn't get the caller information")
+	}
+	functionPath := runtime.FuncForPC(pc).Name()
+	//Next four lines are required to use GCCGO function naming conventions.
+	//For Ex:  github_com_docker_libkv_store_mock.WatchTree.pN39_github_com_docker_libkv_store_mock.Mock
+	//uses inteface information unlike golang github.com/docker/libkv/store/mock.(*Mock).WatchTree
+	//With GCCGO we need to remove interface information starting from pN<dd>.
+	re := regexp.MustCompile("\\.pN\\d+_")
+	if re.MatchString(functionPath) {
+		functionPath = re.Split(functionPath, -1)[0]
+	}
+	parts := strings.Split(functionPath, ".")
+	functionName := parts[len(parts)-1]
+
+	found, call := m.findExpectedCall(functionName, arguments...)
+
+	if found < 0 {
+		// we have to fail here - because we don't know what to do
+		// as the return arguments.  This is because:
+		//
+		//   a) this is a totally unexpected call to this method,
+		//   b) the arguments are not what was expected, or
+		//   c) the developer has forgotten to add an accompanying On...Return pair.
+
+		closestFound, closestCall := m.findClosestCall(functionName, arguments...)
+
+		if closestFound {
+			panic(fmt.Sprintf("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n", callString(functionName, arguments, true), callString(functionName, closestCall.Arguments, true)))
+		} else {
+			panic(fmt.Sprintf("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", functionName, functionName, callString(functionName, arguments, true), assert.CallerInfo()))
+		}
+	} else {
+		m.mutex.Lock()
+		switch {
+		case call.Repeatability == 1:
+			call.Repeatability = -1
+			call.totalCalls++
+
+		case call.Repeatability > 1:
+			call.Repeatability--
+			call.totalCalls++
+
+		case call.Repeatability == 0:
+			call.totalCalls++
+		}
+		m.mutex.Unlock()
+	}
+
+	// add the call
+	m.mutex.Lock()
+	m.Calls = append(m.Calls, *newCall(m, functionName, arguments...))
+	m.mutex.Unlock()
+
+	// block if specified
+	if call.WaitFor != nil {
+		<-call.WaitFor
+	}
+
+	if call.RunFn != nil {
+		call.RunFn(arguments)
+	}
+
+	return call.ReturnArguments
+}
+
+/*
+	Assertions
+*/
+
+// AssertExpectationsForObjects asserts that everything specified with On and Return
+// of the specified objects was in fact called as expected.
+//
+// Calls may have occurred in any order.
+func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
+	var success = true
+	for _, obj := range testObjects {
+		mockObj := obj.(Mock)
+		success = success && mockObj.AssertExpectations(t)
+	}
+	return success
+}
+
+// AssertExpectations asserts that everything specified with On and Return was
+// in fact called as expected.  Calls may have occurred in any order.
+func (m *Mock) AssertExpectations(t TestingT) bool {
+	var somethingMissing bool
+	var failedExpectations int
+
+	// iterate through each expectation
+	expectedCalls := m.expectedCalls()
+	for _, expectedCall := range expectedCalls {
+		if !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) && expectedCall.totalCalls == 0 {
+			somethingMissing = true
+			failedExpectations++
+			t.Logf("\u274C\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
+		} else {
+			m.mutex.Lock()
+			if expectedCall.Repeatability > 0 {
+				somethingMissing = true
+				failedExpectations++
+			} else {
+				t.Logf("\u2705\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
+			}
+			m.mutex.Unlock()
+		}
+	}
+
+	if somethingMissing {
+		t.Errorf("FAIL: %d out of %d expectation(s) were met.\n\tThe code you are testing needs to make %d more call(s).\n\tat: %s", len(expectedCalls)-failedExpectations, len(expectedCalls), failedExpectations, assert.CallerInfo())
+	}
+
+	return !somethingMissing
+}
+
+// AssertNumberOfCalls asserts that the method was called expectedCalls times.
+func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls int) bool {
+	var actualCalls int
+	for _, call := range m.calls() {
+		if call.Method == methodName {
+			actualCalls++
+		}
+	}
+	return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls))
+}
+
+// AssertCalled asserts that the method was called.
+// It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.
+func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool {
+	if !assert.True(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method should have been called with %d argument(s), but was not.", methodName, len(arguments))) {
+		t.Logf("%v", m.expectedCalls())
+		return false
+	}
+	return true
+}
+
+// AssertNotCalled asserts that the method was not called.
+// It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.
+func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool {
+	if !assert.False(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method was called with %d argument(s), but should NOT have been.", methodName, len(arguments))) {
+		t.Logf("%v", m.expectedCalls())
+		return false
+	}
+	return true
+}
+
+func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool {
+	for _, call := range m.calls() {
+		if call.Method == methodName {
+
+			_, differences := Arguments(expected).Diff(call.Arguments)
+
+			if differences == 0 {
+				// found the expected call
+				return true
+			}
+
+		}
+	}
+	// we didn't find the expected call
+	return false
+}
+
+func (m *Mock) expectedCalls() []*Call {
+	m.mutex.Lock()
+	defer m.mutex.Unlock()
+	return append([]*Call{}, m.ExpectedCalls...)
+}
+
+func (m *Mock) calls() []Call {
+	m.mutex.Lock()
+	defer m.mutex.Unlock()
+	return append([]Call{}, m.Calls...)
+}
+
+/*
+	Arguments
+*/
+
+// Arguments holds an array of method arguments or return values.
+type Arguments []interface{}
+
+const (
+	// Anything is used in Diff and Assert when the argument being tested
+	// shouldn't be taken into consideration.
+	Anything string = "mock.Anything"
+)
+
+// AnythingOfTypeArgument is a string that contains the type of an argument
+// for use when type checking.  Used in Diff and Assert.
+type AnythingOfTypeArgument string
+
+// AnythingOfType returns an AnythingOfTypeArgument object containing the
+// name of the type to check for.  Used in Diff and Assert.
+//
+// For example:
+//	Assert(t, AnythingOfType("string"), AnythingOfType("int"))
+func AnythingOfType(t string) AnythingOfTypeArgument {
+	return AnythingOfTypeArgument(t)
+}
+
+// argumentMatcher performs custom argument matching, returning whether or
+// not the argument is matched by the expectation fixture function.
+type argumentMatcher struct {
+	// fn is a function which accepts one argument, and returns a bool.
+	fn reflect.Value
+}
+
+func (f argumentMatcher) Matches(argument interface{}) bool {
+	expectType := f.fn.Type().In(0)
+
+	if reflect.TypeOf(argument).AssignableTo(expectType) {
+		result := f.fn.Call([]reflect.Value{reflect.ValueOf(argument)})
+		return result[0].Bool()
+	}
+	return false
+}
+
+func (f argumentMatcher) String() string {
+	return fmt.Sprintf("func(%s) bool", f.fn.Type().In(0).Name())
+}
+
+// MatchedBy can be used to match a mock call based on only certain properties
+// from a complex struct or some calculation. It takes a function that will be
+// evaluated with the called argument and will return true when there's a match
+// and false otherwise.
+//
+// Example:
+// m.On("Do", MatchedBy(func(req *http.Request) bool { return req.Host == "example.com" }))
+//
+// |fn|, must be a function accepting a single argument (of the expected type)
+// which returns a bool. If |fn| doesn't match the required signature,
+// MathedBy() panics.
+func MatchedBy(fn interface{}) argumentMatcher {
+	fnType := reflect.TypeOf(fn)
+
+	if fnType.Kind() != reflect.Func {
+		panic(fmt.Sprintf("assert: arguments: %s is not a func", fn))
+	}
+	if fnType.NumIn() != 1 {
+		panic(fmt.Sprintf("assert: arguments: %s does not take exactly one argument", fn))
+	}
+	if fnType.NumOut() != 1 || fnType.Out(0).Kind() != reflect.Bool {
+		panic(fmt.Sprintf("assert: arguments: %s does not return a bool", fn))
+	}
+
+	return argumentMatcher{fn: reflect.ValueOf(fn)}
+}
+
+// Get Returns the argument at the specified index.
+func (args Arguments) Get(index int) interface{} {
+	if index+1 > len(args) {
+		panic(fmt.Sprintf("assert: arguments: Cannot call Get(%d) because there are %d argument(s).", index, len(args)))
+	}
+	return args[index]
+}
+
+// Is gets whether the objects match the arguments specified.
+func (args Arguments) Is(objects ...interface{}) bool {
+	for i, obj := range args {
+		if obj != objects[i] {
+			return false
+		}
+	}
+	return true
+}
+
+// Diff gets a string describing the differences between the arguments
+// and the specified objects.
+//
+// Returns the diff string and number of differences found.
+func (args Arguments) Diff(objects []interface{}) (string, int) {
+
+	var output = "\n"
+	var differences int
+
+	var maxArgCount = len(args)
+	if len(objects) > maxArgCount {
+		maxArgCount = len(objects)
+	}
+
+	for i := 0; i < maxArgCount; i++ {
+		var actual, expected interface{}
+
+		if len(objects) <= i {
+			actual = "(Missing)"
+		} else {
+			actual = objects[i]
+		}
+
+		if len(args) <= i {
+			expected = "(Missing)"
+		} else {
+			expected = args[i]
+		}
+
+		if matcher, ok := expected.(argumentMatcher); ok {
+			if matcher.Matches(actual) {
+				output = fmt.Sprintf("%s\t%d: \u2705  %s matched by %s\n", output, i, actual, matcher)
+			} else {
+				differences++
+				output = fmt.Sprintf("%s\t%d: \u2705  %s not matched by %s\n", output, i, actual, matcher)
+			}
+		} else if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() {
+
+			// type checking
+			if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) {
+				// not match
+				differences++
+				output = fmt.Sprintf("%s\t%d: \u274C  type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actual)
+			}
+
+		} else {
+
+			// normal checking
+
+			if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
+				// match
+				output = fmt.Sprintf("%s\t%d: \u2705  %s == %s\n", output, i, actual, expected)
+			} else {
+				// not match
+				differences++
+				output = fmt.Sprintf("%s\t%d: \u274C  %s != %s\n", output, i, actual, expected)
+			}
+		}
+
+	}
+
+	if differences == 0 {
+		return "No differences.", differences
+	}
+
+	return output, differences
+
+}
+
+// Assert compares the arguments with the specified objects and fails if
+// they do not exactly match.
+func (args Arguments) Assert(t TestingT, objects ...interface{}) bool {
+
+	// get the differences
+	diff, diffCount := args.Diff(objects)
+
+	if diffCount == 0 {
+		return true
+	}
+
+	// there are differences... report them...
+	t.Logf(diff)
+	t.Errorf("%sArguments do not match.", assert.CallerInfo())
+
+	return false
+
+}
+
+// String gets the argument at the specified index. Panics if there is no argument, or
+// if the argument is of the wrong type.
+//
+// If no index is provided, String() returns a complete string representation
+// of the arguments.
+func (args Arguments) String(indexOrNil ...int) string {
+
+	if len(indexOrNil) == 0 {
+		// normal String() method - return a string representation of the args
+		var argsStr []string
+		for _, arg := range args {
+			argsStr = append(argsStr, fmt.Sprintf("%s", reflect.TypeOf(arg)))
+		}
+		return strings.Join(argsStr, ",")
+	} else if len(indexOrNil) == 1 {
+		// Index has been specified - get the argument at that index
+		var index = indexOrNil[0]
+		var s string
+		var ok bool
+		if s, ok = args.Get(index).(string); !ok {
+			panic(fmt.Sprintf("assert: arguments: String(%d) failed because object wasn't correct type: %s", index, args.Get(index)))
+		}
+		return s
+	}
+
+	panic(fmt.Sprintf("assert: arguments: Wrong number of arguments passed to String.  Must be 0 or 1, not %d", len(indexOrNil)))
+
+}
+
+// Int gets the argument at the specified index. Panics if there is no argument, or
+// if the argument is of the wrong type.
+func (args Arguments) Int(index int) int {
+	var s int
+	var ok bool
+	if s, ok = args.Get(index).(int); !ok {
+		panic(fmt.Sprintf("assert: arguments: Int(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
+	}
+	return s
+}
+
+// Error gets the argument at the specified index. Panics if there is no argument, or
+// if the argument is of the wrong type.
+func (args Arguments) Error(index int) error {
+	obj := args.Get(index)
+	var s error
+	var ok bool
+	if obj == nil {
+		return nil
+	}
+	if s, ok = obj.(error); !ok {
+		panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
+	}
+	return s
+}
+
+// Bool gets the argument at the specified index. Panics if there is no argument, or
+// if the argument is of the wrong type.
+func (args Arguments) Bool(index int) bool {
+	var s bool
+	var ok bool
+	if s, ok = args.Get(index).(bool); !ok {
+		panic(fmt.Sprintf("assert: arguments: Bool(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
+	}
+	return s
+}
diff --git a/go/src/github.com/stretchr/testify/mock/mock_test.go b/go/src/github.com/stretchr/testify/mock/mock_test.go
new file mode 100644
index 0000000..166c324
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/mock/mock_test.go
@@ -0,0 +1,1130 @@
+package mock
+
+import (
+	"errors"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"testing"
+	"time"
+)
+
+/*
+	Test objects
+*/
+
+// ExampleInterface represents an example interface.
+type ExampleInterface interface {
+	TheExampleMethod(a, b, c int) (int, error)
+}
+
+// TestExampleImplementation is a test implementation of ExampleInterface
+type TestExampleImplementation struct {
+	Mock
+}
+
+func (i *TestExampleImplementation) TheExampleMethod(a, b, c int) (int, error) {
+	args := i.Called(a, b, c)
+	return args.Int(0), errors.New("Whoops")
+}
+
+func (i *TestExampleImplementation) TheExampleMethod2(yesorno bool) {
+	i.Called(yesorno)
+}
+
+type ExampleType struct {
+	ran bool
+}
+
+func (i *TestExampleImplementation) TheExampleMethod3(et *ExampleType) error {
+	args := i.Called(et)
+	return args.Error(0)
+}
+
+func (i *TestExampleImplementation) TheExampleMethodFunc(fn func(string) error) error {
+	args := i.Called(fn)
+	return args.Error(0)
+}
+
+func (i *TestExampleImplementation) TheExampleMethodVariadic(a ...int) error {
+	args := i.Called(a)
+	return args.Error(0)
+}
+
+func (i *TestExampleImplementation) TheExampleMethodVariadicInterface(a ...interface{}) error {
+	args := i.Called(a)
+	return args.Error(0)
+}
+
+type ExampleFuncType func(string) error
+
+func (i *TestExampleImplementation) TheExampleMethodFuncType(fn ExampleFuncType) error {
+	args := i.Called(fn)
+	return args.Error(0)
+}
+
+/*
+	Mock
+*/
+
+func Test_Mock_TestData(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	if assert.NotNil(t, mockedService.TestData()) {
+
+		mockedService.TestData().Set("something", 123)
+		assert.Equal(t, 123, mockedService.TestData().Get("something").Data())
+	}
+}
+
+func Test_Mock_On(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.On("TheExampleMethod")
+	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+	assert.Equal(t, "TheExampleMethod", c.Method)
+}
+
+func Test_Mock_Chained_On(t *testing.T) {
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.
+		On("TheExampleMethod", 1, 2, 3).
+		Return(0).
+		On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).
+		Return(nil)
+
+	expectedCalls := []*Call{
+		&Call{
+			Parent:          &mockedService.Mock,
+			Method:          "TheExampleMethod",
+			Arguments:       []interface{}{1, 2, 3},
+			ReturnArguments: []interface{}{0},
+		},
+		&Call{
+			Parent:          &mockedService.Mock,
+			Method:          "TheExampleMethod3",
+			Arguments:       []interface{}{AnythingOfType("*mock.ExampleType")},
+			ReturnArguments: []interface{}{nil},
+		},
+	}
+	assert.Equal(t, expectedCalls, mockedService.ExpectedCalls)
+}
+
+func Test_Mock_On_WithArgs(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.On("TheExampleMethod", 1, 2, 3, 4)
+
+	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+	assert.Equal(t, "TheExampleMethod", c.Method)
+	assert.Equal(t, Arguments{1, 2, 3, 4}, c.Arguments)
+}
+
+func Test_Mock_On_WithFuncArg(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.
+		On("TheExampleMethodFunc", AnythingOfType("func(string) error")).
+		Return(nil)
+
+	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+	assert.Equal(t, "TheExampleMethodFunc", c.Method)
+	assert.Equal(t, 1, len(c.Arguments))
+	assert.Equal(t, AnythingOfType("func(string) error"), c.Arguments[0])
+
+	fn := func(string) error { return nil }
+
+	assert.NotPanics(t, func() {
+		mockedService.TheExampleMethodFunc(fn)
+	})
+}
+
+func Test_Mock_On_WithIntArgMatcher(t *testing.T) {
+	var mockedService TestExampleImplementation
+
+	mockedService.On("TheExampleMethod",
+		MatchedBy(func(a int) bool {
+			return a == 1
+		}), MatchedBy(func(b int) bool {
+			return b == 2
+		}), MatchedBy(func(c int) bool {
+			return c == 3
+		})).Return(0, nil)
+
+	assert.Panics(t, func() {
+		mockedService.TheExampleMethod(1, 2, 4)
+	})
+	assert.Panics(t, func() {
+		mockedService.TheExampleMethod(2, 2, 3)
+	})
+	assert.NotPanics(t, func() {
+		mockedService.TheExampleMethod(1, 2, 3)
+	})
+}
+
+func Test_Mock_On_WithPtrArgMatcher(t *testing.T) {
+	var mockedService TestExampleImplementation
+
+	mockedService.On("TheExampleMethod3",
+		MatchedBy(func(a *ExampleType) bool { return a.ran == true }),
+	).Return(nil)
+
+	mockedService.On("TheExampleMethod3",
+		MatchedBy(func(a *ExampleType) bool { return a.ran == false }),
+	).Return(errors.New("error"))
+
+	assert.Equal(t, mockedService.TheExampleMethod3(&ExampleType{true}), nil)
+	assert.EqualError(t, mockedService.TheExampleMethod3(&ExampleType{false}), "error")
+}
+
+func Test_Mock_On_WithFuncArgMatcher(t *testing.T) {
+	var mockedService TestExampleImplementation
+
+	fixture1, fixture2 := errors.New("fixture1"), errors.New("fixture2")
+
+	mockedService.On("TheExampleMethodFunc",
+		MatchedBy(func(a func(string) error) bool { return a("string") == fixture1 }),
+	).Return(errors.New("fixture1"))
+
+	mockedService.On("TheExampleMethodFunc",
+		MatchedBy(func(a func(string) error) bool { return a("string") == fixture2 }),
+	).Return(errors.New("fixture2"))
+
+	assert.EqualError(t, mockedService.TheExampleMethodFunc(
+		func(string) error { return fixture1 }), "fixture1")
+	assert.EqualError(t, mockedService.TheExampleMethodFunc(
+		func(string) error { return fixture2 }), "fixture2")
+}
+
+func Test_Mock_On_WithVariadicFunc(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.
+		On("TheExampleMethodVariadic", []int{1, 2, 3}).
+		Return(nil)
+
+	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+	assert.Equal(t, 1, len(c.Arguments))
+	assert.Equal(t, []int{1, 2, 3}, c.Arguments[0])
+
+	assert.NotPanics(t, func() {
+		mockedService.TheExampleMethodVariadic(1, 2, 3)
+	})
+	assert.Panics(t, func() {
+		mockedService.TheExampleMethodVariadic(1, 2)
+	})
+
+}
+
+func Test_Mock_On_WithVariadicFuncWithInterface(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.On("TheExampleMethodVariadicInterface", []interface{}{1, 2, 3}).
+		Return(nil)
+
+	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+	assert.Equal(t, 1, len(c.Arguments))
+	assert.Equal(t, []interface{}{1, 2, 3}, c.Arguments[0])
+
+	assert.NotPanics(t, func() {
+		mockedService.TheExampleMethodVariadicInterface(1, 2, 3)
+	})
+	assert.Panics(t, func() {
+		mockedService.TheExampleMethodVariadicInterface(1, 2)
+	})
+
+}
+
+func Test_Mock_On_WithVariadicFuncWithEmptyInterfaceArray(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	var expected []interface{}
+	c := mockedService.
+		On("TheExampleMethodVariadicInterface", expected).
+		Return(nil)
+
+	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+	assert.Equal(t, 1, len(c.Arguments))
+	assert.Equal(t, expected, c.Arguments[0])
+
+	assert.NotPanics(t, func() {
+		mockedService.TheExampleMethodVariadicInterface()
+	})
+	assert.Panics(t, func() {
+		mockedService.TheExampleMethodVariadicInterface(1, 2)
+	})
+
+}
+
+func Test_Mock_On_WithFuncPanics(t *testing.T) {
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	assert.Panics(t, func() {
+		mockedService.On("TheExampleMethodFunc", func(string) error { return nil })
+	})
+}
+
+func Test_Mock_On_WithFuncTypeArg(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.
+		On("TheExampleMethodFuncType", AnythingOfType("mock.ExampleFuncType")).
+		Return(nil)
+
+	assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+	assert.Equal(t, 1, len(c.Arguments))
+	assert.Equal(t, AnythingOfType("mock.ExampleFuncType"), c.Arguments[0])
+
+	fn := func(string) error { return nil }
+	assert.NotPanics(t, func() {
+		mockedService.TheExampleMethodFuncType(fn)
+	})
+}
+
+func Test_Mock_Return(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.
+		On("TheExampleMethod", "A", "B", true).
+		Return(1, "two", true)
+
+	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+
+	call := mockedService.ExpectedCalls[0]
+
+	assert.Equal(t, "TheExampleMethod", call.Method)
+	assert.Equal(t, "A", call.Arguments[0])
+	assert.Equal(t, "B", call.Arguments[1])
+	assert.Equal(t, true, call.Arguments[2])
+	assert.Equal(t, 1, call.ReturnArguments[0])
+	assert.Equal(t, "two", call.ReturnArguments[1])
+	assert.Equal(t, true, call.ReturnArguments[2])
+	assert.Equal(t, 0, call.Repeatability)
+	assert.Nil(t, call.WaitFor)
+}
+
+func Test_Mock_Return_WaitUntil(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+	ch := time.After(time.Second)
+
+	c := mockedService.Mock.
+		On("TheExampleMethod", "A", "B", true).
+		WaitUntil(ch).
+		Return(1, "two", true)
+
+	// assert that the call was created
+	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+
+	call := mockedService.ExpectedCalls[0]
+
+	assert.Equal(t, "TheExampleMethod", call.Method)
+	assert.Equal(t, "A", call.Arguments[0])
+	assert.Equal(t, "B", call.Arguments[1])
+	assert.Equal(t, true, call.Arguments[2])
+	assert.Equal(t, 1, call.ReturnArguments[0])
+	assert.Equal(t, "two", call.ReturnArguments[1])
+	assert.Equal(t, true, call.ReturnArguments[2])
+	assert.Equal(t, 0, call.Repeatability)
+	assert.Equal(t, ch, call.WaitFor)
+}
+
+func Test_Mock_Return_After(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.Mock.
+		On("TheExampleMethod", "A", "B", true).
+		Return(1, "two", true).
+		After(time.Second)
+
+	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+
+	call := mockedService.Mock.ExpectedCalls[0]
+
+	assert.Equal(t, "TheExampleMethod", call.Method)
+	assert.Equal(t, "A", call.Arguments[0])
+	assert.Equal(t, "B", call.Arguments[1])
+	assert.Equal(t, true, call.Arguments[2])
+	assert.Equal(t, 1, call.ReturnArguments[0])
+	assert.Equal(t, "two", call.ReturnArguments[1])
+	assert.Equal(t, true, call.ReturnArguments[2])
+	assert.Equal(t, 0, call.Repeatability)
+	assert.NotEqual(t, nil, call.WaitFor)
+
+}
+
+func Test_Mock_Return_Run(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	fn := func(args Arguments) {
+		arg := args.Get(0).(*ExampleType)
+		arg.ran = true
+	}
+
+	c := mockedService.Mock.
+		On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).
+		Return(nil).
+		Run(fn)
+
+	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+
+	call := mockedService.Mock.ExpectedCalls[0]
+
+	assert.Equal(t, "TheExampleMethod3", call.Method)
+	assert.Equal(t, AnythingOfType("*mock.ExampleType"), call.Arguments[0])
+	assert.Equal(t, nil, call.ReturnArguments[0])
+	assert.Equal(t, 0, call.Repeatability)
+	assert.NotEqual(t, nil, call.WaitFor)
+	assert.NotNil(t, call.Run)
+
+	et := ExampleType{}
+	assert.Equal(t, false, et.ran)
+	mockedService.TheExampleMethod3(&et)
+	assert.Equal(t, true, et.ran)
+}
+
+func Test_Mock_Return_Run_Out_Of_Order(t *testing.T) {
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+	f := func(args Arguments) {
+		arg := args.Get(0).(*ExampleType)
+		arg.ran = true
+	}
+
+	c := mockedService.Mock.
+		On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).
+		Run(f).
+		Return(nil)
+
+	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+
+	call := mockedService.Mock.ExpectedCalls[0]
+
+	assert.Equal(t, "TheExampleMethod3", call.Method)
+	assert.Equal(t, AnythingOfType("*mock.ExampleType"), call.Arguments[0])
+	assert.Equal(t, nil, call.ReturnArguments[0])
+	assert.Equal(t, 0, call.Repeatability)
+	assert.NotEqual(t, nil, call.WaitFor)
+	assert.NotNil(t, call.Run)
+}
+
+func Test_Mock_Return_Once(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.On("TheExampleMethod", "A", "B", true).
+		Return(1, "two", true).
+		Once()
+
+	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+
+	call := mockedService.ExpectedCalls[0]
+
+	assert.Equal(t, "TheExampleMethod", call.Method)
+	assert.Equal(t, "A", call.Arguments[0])
+	assert.Equal(t, "B", call.Arguments[1])
+	assert.Equal(t, true, call.Arguments[2])
+	assert.Equal(t, 1, call.ReturnArguments[0])
+	assert.Equal(t, "two", call.ReturnArguments[1])
+	assert.Equal(t, true, call.ReturnArguments[2])
+	assert.Equal(t, 1, call.Repeatability)
+	assert.Nil(t, call.WaitFor)
+}
+
+func Test_Mock_Return_Twice(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.
+		On("TheExampleMethod", "A", "B", true).
+		Return(1, "two", true).
+		Twice()
+
+	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+
+	call := mockedService.ExpectedCalls[0]
+
+	assert.Equal(t, "TheExampleMethod", call.Method)
+	assert.Equal(t, "A", call.Arguments[0])
+	assert.Equal(t, "B", call.Arguments[1])
+	assert.Equal(t, true, call.Arguments[2])
+	assert.Equal(t, 1, call.ReturnArguments[0])
+	assert.Equal(t, "two", call.ReturnArguments[1])
+	assert.Equal(t, true, call.ReturnArguments[2])
+	assert.Equal(t, 2, call.Repeatability)
+	assert.Nil(t, call.WaitFor)
+}
+
+func Test_Mock_Return_Times(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.
+		On("TheExampleMethod", "A", "B", true).
+		Return(1, "two", true).
+		Times(5)
+
+	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+
+	call := mockedService.ExpectedCalls[0]
+
+	assert.Equal(t, "TheExampleMethod", call.Method)
+	assert.Equal(t, "A", call.Arguments[0])
+	assert.Equal(t, "B", call.Arguments[1])
+	assert.Equal(t, true, call.Arguments[2])
+	assert.Equal(t, 1, call.ReturnArguments[0])
+	assert.Equal(t, "two", call.ReturnArguments[1])
+	assert.Equal(t, true, call.ReturnArguments[2])
+	assert.Equal(t, 5, call.Repeatability)
+	assert.Nil(t, call.WaitFor)
+}
+
+func Test_Mock_Return_Nothing(t *testing.T) {
+
+	// make a test impl object
+	var mockedService = new(TestExampleImplementation)
+
+	c := mockedService.
+		On("TheExampleMethod", "A", "B", true).
+		Return()
+
+	require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
+
+	call := mockedService.ExpectedCalls[0]
+
+	assert.Equal(t, "TheExampleMethod", call.Method)
+	assert.Equal(t, "A", call.Arguments[0])
+	assert.Equal(t, "B", call.Arguments[1])
+	assert.Equal(t, true, call.Arguments[2])
+	assert.Equal(t, 0, len(call.ReturnArguments))
+}
+
+func Test_Mock_findExpectedCall(t *testing.T) {
+
+	m := new(Mock)
+	m.On("One", 1).Return("one")
+	m.On("Two", 2).Return("two")
+	m.On("Two", 3).Return("three")
+
+	f, c := m.findExpectedCall("Two", 3)
+
+	if assert.Equal(t, 2, f) {
+		if assert.NotNil(t, c) {
+			assert.Equal(t, "Two", c.Method)
+			assert.Equal(t, 3, c.Arguments[0])
+			assert.Equal(t, "three", c.ReturnArguments[0])
+		}
+	}
+
+}
+
+func Test_Mock_findExpectedCall_For_Unknown_Method(t *testing.T) {
+
+	m := new(Mock)
+	m.On("One", 1).Return("one")
+	m.On("Two", 2).Return("two")
+	m.On("Two", 3).Return("three")
+
+	f, _ := m.findExpectedCall("Two")
+
+	assert.Equal(t, -1, f)
+
+}
+
+func Test_Mock_findExpectedCall_Respects_Repeatability(t *testing.T) {
+
+	m := new(Mock)
+	m.On("One", 1).Return("one")
+	m.On("Two", 2).Return("two").Once()
+	m.On("Two", 3).Return("three").Twice()
+	m.On("Two", 3).Return("three").Times(8)
+
+	f, c := m.findExpectedCall("Two", 3)
+
+	if assert.Equal(t, 2, f) {
+		if assert.NotNil(t, c) {
+			assert.Equal(t, "Two", c.Method)
+			assert.Equal(t, 3, c.Arguments[0])
+			assert.Equal(t, "three", c.ReturnArguments[0])
+		}
+	}
+
+}
+
+func Test_callString(t *testing.T) {
+
+	assert.Equal(t, `Method(int,bool,string)`, callString("Method", []interface{}{1, true, "something"}, false))
+
+}
+
+func Test_Mock_Called(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_Called", 1, 2, 3).Return(5, "6", true)
+
+	returnArguments := mockedService.Called(1, 2, 3)
+
+	if assert.Equal(t, 1, len(mockedService.Calls)) {
+		assert.Equal(t, "Test_Mock_Called", mockedService.Calls[0].Method)
+		assert.Equal(t, 1, mockedService.Calls[0].Arguments[0])
+		assert.Equal(t, 2, mockedService.Calls[0].Arguments[1])
+		assert.Equal(t, 3, mockedService.Calls[0].Arguments[2])
+	}
+
+	if assert.Equal(t, 3, len(returnArguments)) {
+		assert.Equal(t, 5, returnArguments[0])
+		assert.Equal(t, "6", returnArguments[1])
+		assert.Equal(t, true, returnArguments[2])
+	}
+
+}
+
+func asyncCall(m *Mock, ch chan Arguments) {
+	ch <- m.Called(1, 2, 3)
+}
+
+func Test_Mock_Called_blocks(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.Mock.On("asyncCall", 1, 2, 3).Return(5, "6", true).After(2 * time.Millisecond)
+
+	ch := make(chan Arguments)
+
+	go asyncCall(&mockedService.Mock, ch)
+
+	select {
+	case <-ch:
+		t.Fatal("should have waited")
+	case <-time.After(1 * time.Millisecond):
+	}
+
+	returnArguments := <-ch
+
+	if assert.Equal(t, 1, len(mockedService.Mock.Calls)) {
+		assert.Equal(t, "asyncCall", mockedService.Mock.Calls[0].Method)
+		assert.Equal(t, 1, mockedService.Mock.Calls[0].Arguments[0])
+		assert.Equal(t, 2, mockedService.Mock.Calls[0].Arguments[1])
+		assert.Equal(t, 3, mockedService.Mock.Calls[0].Arguments[2])
+	}
+
+	if assert.Equal(t, 3, len(returnArguments)) {
+		assert.Equal(t, 5, returnArguments[0])
+		assert.Equal(t, "6", returnArguments[1])
+		assert.Equal(t, true, returnArguments[2])
+	}
+
+}
+
+func Test_Mock_Called_For_Bounded_Repeatability(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.
+		On("Test_Mock_Called_For_Bounded_Repeatability", 1, 2, 3).
+		Return(5, "6", true).
+		Once()
+	mockedService.
+		On("Test_Mock_Called_For_Bounded_Repeatability", 1, 2, 3).
+		Return(-1, "hi", false)
+
+	returnArguments1 := mockedService.Called(1, 2, 3)
+	returnArguments2 := mockedService.Called(1, 2, 3)
+
+	if assert.Equal(t, 2, len(mockedService.Calls)) {
+		assert.Equal(t, "Test_Mock_Called_For_Bounded_Repeatability", mockedService.Calls[0].Method)
+		assert.Equal(t, 1, mockedService.Calls[0].Arguments[0])
+		assert.Equal(t, 2, mockedService.Calls[0].Arguments[1])
+		assert.Equal(t, 3, mockedService.Calls[0].Arguments[2])
+
+		assert.Equal(t, "Test_Mock_Called_For_Bounded_Repeatability", mockedService.Calls[1].Method)
+		assert.Equal(t, 1, mockedService.Calls[1].Arguments[0])
+		assert.Equal(t, 2, mockedService.Calls[1].Arguments[1])
+		assert.Equal(t, 3, mockedService.Calls[1].Arguments[2])
+	}
+
+	if assert.Equal(t, 3, len(returnArguments1)) {
+		assert.Equal(t, 5, returnArguments1[0])
+		assert.Equal(t, "6", returnArguments1[1])
+		assert.Equal(t, true, returnArguments1[2])
+	}
+
+	if assert.Equal(t, 3, len(returnArguments2)) {
+		assert.Equal(t, -1, returnArguments2[0])
+		assert.Equal(t, "hi", returnArguments2[1])
+		assert.Equal(t, false, returnArguments2[2])
+	}
+
+}
+
+func Test_Mock_Called_For_SetTime_Expectation(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("TheExampleMethod", 1, 2, 3).Return(5, "6", true).Times(4)
+
+	mockedService.TheExampleMethod(1, 2, 3)
+	mockedService.TheExampleMethod(1, 2, 3)
+	mockedService.TheExampleMethod(1, 2, 3)
+	mockedService.TheExampleMethod(1, 2, 3)
+	assert.Panics(t, func() {
+		mockedService.TheExampleMethod(1, 2, 3)
+	})
+
+}
+
+func Test_Mock_Called_Unexpected(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	// make sure it panics if no expectation was made
+	assert.Panics(t, func() {
+		mockedService.Called(1, 2, 3)
+	}, "Calling unexpected method should panic")
+
+}
+
+func Test_AssertExpectationsForObjects_Helper(t *testing.T) {
+
+	var mockedService1 = new(TestExampleImplementation)
+	var mockedService2 = new(TestExampleImplementation)
+	var mockedService3 = new(TestExampleImplementation)
+
+	mockedService1.On("Test_AssertExpectationsForObjects_Helper", 1).Return()
+	mockedService2.On("Test_AssertExpectationsForObjects_Helper", 2).Return()
+	mockedService3.On("Test_AssertExpectationsForObjects_Helper", 3).Return()
+
+	mockedService1.Called(1)
+	mockedService2.Called(2)
+	mockedService3.Called(3)
+
+	assert.True(t, AssertExpectationsForObjects(t, mockedService1.Mock, mockedService2.Mock, mockedService3.Mock))
+
+}
+
+func Test_AssertExpectationsForObjects_Helper_Failed(t *testing.T) {
+
+	var mockedService1 = new(TestExampleImplementation)
+	var mockedService2 = new(TestExampleImplementation)
+	var mockedService3 = new(TestExampleImplementation)
+
+	mockedService1.On("Test_AssertExpectationsForObjects_Helper_Failed", 1).Return()
+	mockedService2.On("Test_AssertExpectationsForObjects_Helper_Failed", 2).Return()
+	mockedService3.On("Test_AssertExpectationsForObjects_Helper_Failed", 3).Return()
+
+	mockedService1.Called(1)
+	mockedService3.Called(3)
+
+	tt := new(testing.T)
+	assert.False(t, AssertExpectationsForObjects(tt, mockedService1.Mock, mockedService2.Mock, mockedService3.Mock))
+
+}
+
+func Test_Mock_AssertExpectations(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_AssertExpectations", 1, 2, 3).Return(5, 6, 7)
+
+	tt := new(testing.T)
+	assert.False(t, mockedService.AssertExpectations(tt))
+
+	// make the call now
+	mockedService.Called(1, 2, 3)
+
+	// now assert expectations
+	assert.True(t, mockedService.AssertExpectations(tt))
+
+}
+
+func Test_Mock_AssertExpectations_Placeholder_NoArgs(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_AssertExpectations_Placeholder_NoArgs").Return(5, 6, 7).Once()
+	mockedService.On("Test_Mock_AssertExpectations_Placeholder_NoArgs").Return(7, 6, 5)
+
+	tt := new(testing.T)
+	assert.False(t, mockedService.AssertExpectations(tt))
+
+	// make the call now
+	mockedService.Called()
+
+	// now assert expectations
+	assert.True(t, mockedService.AssertExpectations(tt))
+
+}
+
+func Test_Mock_AssertExpectations_Placeholder(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_AssertExpectations_Placeholder", 1, 2, 3).Return(5, 6, 7).Once()
+	mockedService.On("Test_Mock_AssertExpectations_Placeholder", 3, 2, 1).Return(7, 6, 5)
+
+	tt := new(testing.T)
+	assert.False(t, mockedService.AssertExpectations(tt))
+
+	// make the call now
+	mockedService.Called(1, 2, 3)
+
+	// now assert expectations
+	assert.False(t, mockedService.AssertExpectations(tt))
+
+	// make call to the second expectation
+	mockedService.Called(3, 2, 1)
+
+	// now assert expectations again
+	assert.True(t, mockedService.AssertExpectations(tt))
+}
+
+func Test_Mock_AssertExpectations_With_Pointers(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_AssertExpectations_With_Pointers", &struct{ Foo int }{1}).Return(1)
+	mockedService.On("Test_Mock_AssertExpectations_With_Pointers", &struct{ Foo int }{2}).Return(2)
+
+	tt := new(testing.T)
+	assert.False(t, mockedService.AssertExpectations(tt))
+
+	s := struct{ Foo int }{1}
+	// make the calls now
+	mockedService.Called(&s)
+	s.Foo = 2
+	mockedService.Called(&s)
+
+	// now assert expectations
+	assert.True(t, mockedService.AssertExpectations(tt))
+
+}
+
+func Test_Mock_AssertExpectationsCustomType(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).Return(nil).Once()
+
+	tt := new(testing.T)
+	assert.False(t, mockedService.AssertExpectations(tt))
+
+	// make the call now
+	mockedService.TheExampleMethod3(&ExampleType{})
+
+	// now assert expectations
+	assert.True(t, mockedService.AssertExpectations(tt))
+
+}
+
+func Test_Mock_AssertExpectations_With_Repeatability(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_AssertExpectations_With_Repeatability", 1, 2, 3).Return(5, 6, 7).Twice()
+
+	tt := new(testing.T)
+	assert.False(t, mockedService.AssertExpectations(tt))
+
+	// make the call now
+	mockedService.Called(1, 2, 3)
+
+	assert.False(t, mockedService.AssertExpectations(tt))
+
+	mockedService.Called(1, 2, 3)
+
+	// now assert expectations
+	assert.True(t, mockedService.AssertExpectations(tt))
+
+}
+
+func Test_Mock_TwoCallsWithDifferentArguments(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_TwoCallsWithDifferentArguments", 1, 2, 3).Return(5, 6, 7)
+	mockedService.On("Test_Mock_TwoCallsWithDifferentArguments", 4, 5, 6).Return(5, 6, 7)
+
+	args1 := mockedService.Called(1, 2, 3)
+	assert.Equal(t, 5, args1.Int(0))
+	assert.Equal(t, 6, args1.Int(1))
+	assert.Equal(t, 7, args1.Int(2))
+
+	args2 := mockedService.Called(4, 5, 6)
+	assert.Equal(t, 5, args2.Int(0))
+	assert.Equal(t, 6, args2.Int(1))
+	assert.Equal(t, 7, args2.Int(2))
+
+}
+
+func Test_Mock_AssertNumberOfCalls(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_AssertNumberOfCalls", 1, 2, 3).Return(5, 6, 7)
+
+	mockedService.Called(1, 2, 3)
+	assert.True(t, mockedService.AssertNumberOfCalls(t, "Test_Mock_AssertNumberOfCalls", 1))
+
+	mockedService.Called(1, 2, 3)
+	assert.True(t, mockedService.AssertNumberOfCalls(t, "Test_Mock_AssertNumberOfCalls", 2))
+
+}
+
+func Test_Mock_AssertCalled(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_AssertCalled", 1, 2, 3).Return(5, 6, 7)
+
+	mockedService.Called(1, 2, 3)
+
+	assert.True(t, mockedService.AssertCalled(t, "Test_Mock_AssertCalled", 1, 2, 3))
+
+}
+
+func Test_Mock_AssertCalled_WithAnythingOfTypeArgument(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.
+		On("Test_Mock_AssertCalled_WithAnythingOfTypeArgument", Anything, Anything, Anything).
+		Return()
+
+	mockedService.Called(1, "two", []uint8("three"))
+
+	assert.True(t, mockedService.AssertCalled(t, "Test_Mock_AssertCalled_WithAnythingOfTypeArgument", AnythingOfType("int"), AnythingOfType("string"), AnythingOfType("[]uint8")))
+
+}
+
+func Test_Mock_AssertCalled_WithArguments(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_AssertCalled_WithArguments", 1, 2, 3).Return(5, 6, 7)
+
+	mockedService.Called(1, 2, 3)
+
+	tt := new(testing.T)
+	assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments", 1, 2, 3))
+	assert.False(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments", 2, 3, 4))
+
+}
+
+func Test_Mock_AssertCalled_WithArguments_With_Repeatability(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_AssertCalled_WithArguments_With_Repeatability", 1, 2, 3).Return(5, 6, 7).Once()
+	mockedService.On("Test_Mock_AssertCalled_WithArguments_With_Repeatability", 2, 3, 4).Return(5, 6, 7).Once()
+
+	mockedService.Called(1, 2, 3)
+	mockedService.Called(2, 3, 4)
+
+	tt := new(testing.T)
+	assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments_With_Repeatability", 1, 2, 3))
+	assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments_With_Repeatability", 2, 3, 4))
+	assert.False(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments_With_Repeatability", 3, 4, 5))
+
+}
+
+func Test_Mock_AssertNotCalled(t *testing.T) {
+
+	var mockedService = new(TestExampleImplementation)
+
+	mockedService.On("Test_Mock_AssertNotCalled", 1, 2, 3).Return(5, 6, 7)
+
+	mockedService.Called(1, 2, 3)
+
+	assert.True(t, mockedService.AssertNotCalled(t, "Test_Mock_NotCalled"))
+
+}
+
+/*
+	Arguments helper methods
+*/
+func Test_Arguments_Get(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", 123, true})
+
+	assert.Equal(t, "string", args.Get(0).(string))
+	assert.Equal(t, 123, args.Get(1).(int))
+	assert.Equal(t, true, args.Get(2).(bool))
+
+}
+
+func Test_Arguments_Is(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", 123, true})
+
+	assert.True(t, args.Is("string", 123, true))
+	assert.False(t, args.Is("wrong", 456, false))
+
+}
+
+func Test_Arguments_Diff(t *testing.T) {
+
+	var args = Arguments([]interface{}{"Hello World", 123, true})
+	var diff string
+	var count int
+	diff, count = args.Diff([]interface{}{"Hello World", 456, "false"})
+
+	assert.Equal(t, 2, count)
+	assert.Contains(t, diff, `%!s(int=456) != %!s(int=123)`)
+	assert.Contains(t, diff, `false != %!s(bool=true)`)
+
+}
+
+func Test_Arguments_Diff_DifferentNumberOfArgs(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", 123, true})
+	var diff string
+	var count int
+	diff, count = args.Diff([]interface{}{"string", 456, "false", "extra"})
+
+	assert.Equal(t, 3, count)
+	assert.Contains(t, diff, `extra != (Missing)`)
+
+}
+
+func Test_Arguments_Diff_WithAnythingArgument(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", 123, true})
+	var count int
+	_, count = args.Diff([]interface{}{"string", Anything, true})
+
+	assert.Equal(t, 0, count)
+
+}
+
+func Test_Arguments_Diff_WithAnythingArgument_InActualToo(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", Anything, true})
+	var count int
+	_, count = args.Diff([]interface{}{"string", 123, true})
+
+	assert.Equal(t, 0, count)
+
+}
+
+func Test_Arguments_Diff_WithAnythingOfTypeArgument(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", AnythingOfType("int"), true})
+	var count int
+	_, count = args.Diff([]interface{}{"string", 123, true})
+
+	assert.Equal(t, 0, count)
+
+}
+
+func Test_Arguments_Diff_WithAnythingOfTypeArgument_Failing(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", AnythingOfType("string"), true})
+	var count int
+	var diff string
+	diff, count = args.Diff([]interface{}{"string", 123, true})
+
+	assert.Equal(t, 1, count)
+	assert.Contains(t, diff, `string != type int - %!s(int=123)`)
+
+}
+
+func Test_Arguments_Diff_WithArgMatcher(t *testing.T) {
+	matchFn := func(a int) bool {
+		return a == 123
+	}
+	var args = Arguments([]interface{}{"string", MatchedBy(matchFn), true})
+
+	diff, count := args.Diff([]interface{}{"string", 124, true})
+	assert.Equal(t, 1, count)
+	assert.Contains(t, diff, `%!s(int=124) not matched by func(int) bool`)
+
+	diff, count = args.Diff([]interface{}{"string", false, true})
+	assert.Equal(t, 1, count)
+	assert.Contains(t, diff, `%!s(bool=false) not matched by func(int) bool`)
+
+	diff, count = args.Diff([]interface{}{"string", 123, false})
+	assert.Contains(t, diff, `%!s(int=123) matched by func(int) bool`)
+
+	diff, count = args.Diff([]interface{}{"string", 123, true})
+	assert.Equal(t, 0, count)
+	assert.Contains(t, diff, `No differences.`)
+}
+
+func Test_Arguments_Assert(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", 123, true})
+
+	assert.True(t, args.Assert(t, "string", 123, true))
+
+}
+
+func Test_Arguments_String_Representation(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", 123, true})
+	assert.Equal(t, `string,int,bool`, args.String())
+
+}
+
+func Test_Arguments_String(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", 123, true})
+	assert.Equal(t, "string", args.String(0))
+
+}
+
+func Test_Arguments_Error(t *testing.T) {
+
+	var err = errors.New("An Error")
+	var args = Arguments([]interface{}{"string", 123, true, err})
+	assert.Equal(t, err, args.Error(3))
+
+}
+
+func Test_Arguments_Error_Nil(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", 123, true, nil})
+	assert.Equal(t, nil, args.Error(3))
+
+}
+
+func Test_Arguments_Int(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", 123, true})
+	assert.Equal(t, 123, args.Int(1))
+
+}
+
+func Test_Arguments_Bool(t *testing.T) {
+
+	var args = Arguments([]interface{}{"string", 123, true})
+	assert.Equal(t, true, args.Bool(2))
+
+}
diff --git a/go/src/github.com/stretchr/testify/package_test.go b/go/src/github.com/stretchr/testify/package_test.go
new file mode 100644
index 0000000..7ac5d6d
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/package_test.go
@@ -0,0 +1,12 @@
+package testify
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestImports(t *testing.T) {
+	if assert.Equal(t, 1, 1) != true {
+		t.Error("Something is wrong.")
+	}
+}
diff --git a/go/src/github.com/stretchr/testify/require/doc.go b/go/src/github.com/stretchr/testify/require/doc.go
new file mode 100644
index 0000000..169de39
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/require/doc.go
@@ -0,0 +1,28 @@
+// Package require implements the same assertions as the `assert` package but
+// stops test execution when a test fails.
+//
+// Example Usage
+//
+// The following is a complete example using require in a standard test function:
+//    import (
+//      "testing"
+//      "github.com/stretchr/testify/require"
+//    )
+//
+//    func TestSomething(t *testing.T) {
+//
+//      var a string = "Hello"
+//      var b string = "Hello"
+//
+//      require.Equal(t, a, b, "The two words should be the same.")
+//
+//    }
+//
+// Assertions
+//
+// The `require` package have same global functions as in the `assert` package,
+// but instead of returning a boolean result they call `t.FailNow()`.
+//
+// Every assertion function also takes an optional string message as the final argument,
+// allowing custom error messages to be appended to the message the assertion method outputs.
+package require
diff --git a/go/src/github.com/stretchr/testify/require/forward_requirements.go b/go/src/github.com/stretchr/testify/require/forward_requirements.go
new file mode 100644
index 0000000..d3c2ab9
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/require/forward_requirements.go
@@ -0,0 +1,16 @@
+package require
+
+// Assertions provides assertion methods around the
+// TestingT interface.
+type Assertions struct {
+	t TestingT
+}
+
+// New makes a new Assertions object for the specified TestingT.
+func New(t TestingT) *Assertions {
+	return &Assertions{
+		t: t,
+	}
+}
+
+//go:generate go run ../_codegen/main.go -output-package=require -template=require_forward.go.tmpl
diff --git a/go/src/github.com/stretchr/testify/require/forward_requirements_test.go b/go/src/github.com/stretchr/testify/require/forward_requirements_test.go
new file mode 100644
index 0000000..b120ae3
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/require/forward_requirements_test.go
@@ -0,0 +1,385 @@
+package require
+
+import (
+	"errors"
+	"testing"
+	"time"
+)
+
+func TestImplementsWrapper(t *testing.T) {
+	require := New(t)
+
+	require.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject))
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject))
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestIsTypeWrapper(t *testing.T) {
+	require := New(t)
+	require.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject))
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.IsType(new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject))
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestEqualWrapper(t *testing.T) {
+	require := New(t)
+	require.Equal(1, 1)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.Equal(1, 2)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotEqualWrapper(t *testing.T) {
+	require := New(t)
+	require.NotEqual(1, 2)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.NotEqual(2, 2)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestExactlyWrapper(t *testing.T) {
+	require := New(t)
+
+	a := float32(1)
+	b := float32(1)
+	c := float64(1)
+
+	require.Exactly(a, b)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.Exactly(a, c)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotNilWrapper(t *testing.T) {
+	require := New(t)
+	require.NotNil(t, new(AssertionTesterConformingObject))
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.NotNil(nil)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNilWrapper(t *testing.T) {
+	require := New(t)
+	require.Nil(nil)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.Nil(new(AssertionTesterConformingObject))
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestTrueWrapper(t *testing.T) {
+	require := New(t)
+	require.True(true)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.True(false)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestFalseWrapper(t *testing.T) {
+	require := New(t)
+	require.False(false)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.False(true)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestContainsWrapper(t *testing.T) {
+	require := New(t)
+	require.Contains("Hello World", "Hello")
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.Contains("Hello World", "Salut")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotContainsWrapper(t *testing.T) {
+	require := New(t)
+	require.NotContains("Hello World", "Hello!")
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.NotContains("Hello World", "Hello")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestPanicsWrapper(t *testing.T) {
+	require := New(t)
+	require.Panics(func() {
+		panic("Panic!")
+	})
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.Panics(func() {})
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotPanicsWrapper(t *testing.T) {
+	require := New(t)
+	require.NotPanics(func() {})
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.NotPanics(func() {
+		panic("Panic!")
+	})
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNoErrorWrapper(t *testing.T) {
+	require := New(t)
+	require.NoError(nil)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.NoError(errors.New("some error"))
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestErrorWrapper(t *testing.T) {
+	require := New(t)
+	require.Error(errors.New("some error"))
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.Error(nil)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestEqualErrorWrapper(t *testing.T) {
+	require := New(t)
+	require.EqualError(errors.New("some error"), "some error")
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.EqualError(errors.New("some error"), "Not some error")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestEmptyWrapper(t *testing.T) {
+	require := New(t)
+	require.Empty("")
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.Empty("x")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotEmptyWrapper(t *testing.T) {
+	require := New(t)
+	require.NotEmpty("x")
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.NotEmpty("")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestWithinDurationWrapper(t *testing.T) {
+	require := New(t)
+	a := time.Now()
+	b := a.Add(10 * time.Second)
+
+	require.WithinDuration(a, b, 15*time.Second)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.WithinDuration(a, b, 5*time.Second)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestInDeltaWrapper(t *testing.T) {
+	require := New(t)
+	require.InDelta(1.001, 1, 0.01)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.InDelta(1, 2, 0.5)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestZeroWrapper(t *testing.T) {
+	require := New(t)
+	require.Zero(0)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.Zero(1)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotZeroWrapper(t *testing.T) {
+	require := New(t)
+	require.NotZero(1)
+
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+	mockRequire.NotZero(0)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEqWrapper_EqualSONString(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.JSONEq("{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
+		"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}")
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestJSONEqWrapper_Array(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.JSONEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.JSONEq(`{"foo": "bar"}`, "Not JSON")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.JSONEq("Not JSON", `{"foo": "bar", "hello": "world"}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.JSONEq("Not JSON", "Not JSON")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
diff --git a/go/src/github.com/stretchr/testify/require/require.go b/go/src/github.com/stretchr/testify/require/require.go
new file mode 100644
index 0000000..1bcfcb0
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/require/require.go
@@ -0,0 +1,464 @@
+/*
+* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
+* THIS FILE MUST NOT BE EDITED BY HAND
+*/
+
+package require
+
+import (
+
+	assert "github.com/stretchr/testify/assert"
+	http "net/http"
+	url "net/url"
+	time "time"
+)
+
+
+// Condition uses a Comparison to assert a complex condition.
+func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) {
+  if !assert.Condition(t, comp, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Contains asserts that the specified string, list(array, slice...) or map contains the
+// specified substring or element.
+// 
+//    assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'")
+//    assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
+//    assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {
+  if !assert.Contains(t, s, contains, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Empty asserts that the specified object is empty.  I.e. nil, "", false, 0 or either
+// a slice or a channel with len == 0.
+// 
+//  assert.Empty(t, obj)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
+  if !assert.Empty(t, object, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Equal asserts that two objects are equal.
+// 
+//    assert.Equal(t, 123, 123, "123 and 123 should be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+  if !assert.Equal(t, expected, actual, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// EqualError asserts that a function returned an error (i.e. not `nil`)
+// and that it is equal to the provided error.
+// 
+//   actualObj, err := SomeFunction()
+//   if assert.Error(t, err, "An error was expected") {
+// 	   assert.Equal(t, err, expectedError)
+//   }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) {
+  if !assert.EqualError(t, theError, errString, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// EqualValues asserts that two objects are equal or convertable to the same types
+// and equal.
+// 
+//    assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+  if !assert.EqualValues(t, expected, actual, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Error asserts that a function returned an error (i.e. not `nil`).
+// 
+//   actualObj, err := SomeFunction()
+//   if assert.Error(t, err, "An error was expected") {
+// 	   assert.Equal(t, err, expectedError)
+//   }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func Error(t TestingT, err error, msgAndArgs ...interface{}) {
+  if !assert.Error(t, err, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Exactly asserts that two objects are equal is value and type.
+// 
+//    assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+  if !assert.Exactly(t, expected, actual, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Fail reports a failure through
+func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
+  if !assert.Fail(t, failureMessage, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// FailNow fails test
+func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
+  if !assert.FailNow(t, failureMessage, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// False asserts that the specified value is false.
+// 
+//    assert.False(t, myBool, "myBool should be false")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func False(t TestingT, value bool, msgAndArgs ...interface{}) {
+  if !assert.False(t, value, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// HTTPBodyContains asserts that a specified handler returns a
+// body that contains a string.
+// 
+//  assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
+  if !assert.HTTPBodyContains(t, handler, method, url, values, str) {
+    t.FailNow()
+  }
+}
+
+
+// HTTPBodyNotContains asserts that a specified handler returns a
+// body that does not contain a string.
+// 
+//  assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
+  if !assert.HTTPBodyNotContains(t, handler, method, url, values, str) {
+    t.FailNow()
+  }
+}
+
+
+// HTTPError asserts that a specified handler returns an error status code.
+// 
+//  assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
+  if !assert.HTTPError(t, handler, method, url, values) {
+    t.FailNow()
+  }
+}
+
+
+// HTTPRedirect asserts that a specified handler returns a redirect status code.
+// 
+//  assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
+  if !assert.HTTPRedirect(t, handler, method, url, values) {
+    t.FailNow()
+  }
+}
+
+
+// HTTPSuccess asserts that a specified handler returns a success status code.
+// 
+//  assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
+  if !assert.HTTPSuccess(t, handler, method, url, values) {
+    t.FailNow()
+  }
+}
+
+
+// Implements asserts that an object is implemented by the specified interface.
+// 
+//    assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject")
+func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
+  if !assert.Implements(t, interfaceObject, object, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// InDelta asserts that the two numerals are within delta of each other.
+// 
+// 	 assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
+  if !assert.InDelta(t, expected, actual, delta, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// InDeltaSlice is the same as InDelta, except it compares two slices.
+func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
+  if !assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// InEpsilon asserts that expected and actual have a relative error less than epsilon
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
+  if !assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// InEpsilonSlice is the same as InEpsilon, except it compares two slices.
+func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
+  if !assert.InEpsilonSlice(t, expected, actual, delta, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// IsType asserts that the specified objects are of the same type.
+func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
+  if !assert.IsType(t, expectedType, object, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// JSONEq asserts that two JSON strings are equivalent.
+// 
+//  assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {
+  if !assert.JSONEq(t, expected, actual, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Len asserts that the specified object has specific length.
+// Len also fails if the object has a type that len() not accept.
+// 
+//    assert.Len(t, mySlice, 3, "The size of slice is not 3")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) {
+  if !assert.Len(t, object, length, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Nil asserts that the specified object is nil.
+// 
+//    assert.Nil(t, err, "err should be nothing")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
+  if !assert.Nil(t, object, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// NoError asserts that a function returned no error (i.e. `nil`).
+// 
+//   actualObj, err := SomeFunction()
+//   if assert.NoError(t, err) {
+// 	   assert.Equal(t, actualObj, expectedObj)
+//   }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func NoError(t TestingT, err error, msgAndArgs ...interface{}) {
+  if !assert.NoError(t, err, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
+// specified substring or element.
+// 
+//    assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
+//    assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
+//    assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {
+  if !assert.NotContains(t, s, contains, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// NotEmpty asserts that the specified object is NOT empty.  I.e. not nil, "", false, 0 or either
+// a slice or a channel with len == 0.
+// 
+//  if assert.NotEmpty(t, obj) {
+//    assert.Equal(t, "two", obj[1])
+//  }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
+  if !assert.NotEmpty(t, object, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// NotEqual asserts that the specified values are NOT equal.
+// 
+//    assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+  if !assert.NotEqual(t, expected, actual, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// NotNil asserts that the specified object is not nil.
+// 
+//    assert.NotNil(t, err, "err should be something")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
+  if !assert.NotNil(t, object, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
+// 
+//   assert.NotPanics(t, func(){
+//     RemainCalm()
+//   }, "Calling RemainCalm() should NOT panic")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
+  if !assert.NotPanics(t, f, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// NotRegexp asserts that a specified regexp does not match a string.
+// 
+//  assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
+//  assert.NotRegexp(t, "^start", "it's not starting")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {
+  if !assert.NotRegexp(t, rx, str, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// NotZero asserts that i is not the zero value for its type and returns the truth.
+func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
+  if !assert.NotZero(t, i, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Panics asserts that the code inside the specified PanicTestFunc panics.
+// 
+//   assert.Panics(t, func(){
+//     GoCrazy()
+//   }, "Calling GoCrazy() should panic")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
+  if !assert.Panics(t, f, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Regexp asserts that a specified regexp matches a string.
+// 
+//  assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
+//  assert.Regexp(t, "start...$", "it's not starting")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {
+  if !assert.Regexp(t, rx, str, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// True asserts that the specified value is true.
+// 
+//    assert.True(t, myBool, "myBool should be true")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func True(t TestingT, value bool, msgAndArgs ...interface{}) {
+  if !assert.True(t, value, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// WithinDuration asserts that the two times are within duration delta of each other.
+// 
+//   assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
+  if !assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) {
+    t.FailNow()
+  }
+}
+
+
+// Zero asserts that i is the zero value for its type and returns the truth.
+func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
+  if !assert.Zero(t, i, msgAndArgs...) {
+    t.FailNow()
+  }
+}
diff --git a/go/src/github.com/stretchr/testify/require/require.go.tmpl b/go/src/github.com/stretchr/testify/require/require.go.tmpl
new file mode 100644
index 0000000..ab1b1e9
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/require/require.go.tmpl
@@ -0,0 +1,6 @@
+{{.Comment}}
+func {{.DocInfo.Name}}(t TestingT, {{.Params}}) {
+  if !assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) {
+    t.FailNow()
+  }
+}
diff --git a/go/src/github.com/stretchr/testify/require/require_forward.go b/go/src/github.com/stretchr/testify/require/require_forward.go
new file mode 100644
index 0000000..58324f1
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/require/require_forward.go
@@ -0,0 +1,388 @@
+/*
+* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
+* THIS FILE MUST NOT BE EDITED BY HAND
+*/
+
+package require
+
+import (
+
+	assert "github.com/stretchr/testify/assert"
+	http "net/http"
+	url "net/url"
+	time "time"
+)
+
+
+// Condition uses a Comparison to assert a complex condition.
+func (a *Assertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) {
+	Condition(a.t, comp, msgAndArgs...)
+}
+
+
+// Contains asserts that the specified string, list(array, slice...) or map contains the
+// specified substring or element.
+// 
+//    a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'")
+//    a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
+//    a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {
+	Contains(a.t, s, contains, msgAndArgs...)
+}
+
+
+// Empty asserts that the specified object is empty.  I.e. nil, "", false, 0 or either
+// a slice or a channel with len == 0.
+// 
+//  a.Empty(obj)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {
+	Empty(a.t, object, msgAndArgs...)
+}
+
+
+// Equal asserts that two objects are equal.
+// 
+//    a.Equal(123, 123, "123 and 123 should be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+	Equal(a.t, expected, actual, msgAndArgs...)
+}
+
+
+// EqualError asserts that a function returned an error (i.e. not `nil`)
+// and that it is equal to the provided error.
+// 
+//   actualObj, err := SomeFunction()
+//   if assert.Error(t, err, "An error was expected") {
+// 	   assert.Equal(t, err, expectedError)
+//   }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) {
+	EqualError(a.t, theError, errString, msgAndArgs...)
+}
+
+
+// EqualValues asserts that two objects are equal or convertable to the same types
+// and equal.
+// 
+//    a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+	EqualValues(a.t, expected, actual, msgAndArgs...)
+}
+
+
+// Error asserts that a function returned an error (i.e. not `nil`).
+// 
+//   actualObj, err := SomeFunction()
+//   if a.Error(err, "An error was expected") {
+// 	   assert.Equal(t, err, expectedError)
+//   }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Error(err error, msgAndArgs ...interface{}) {
+	Error(a.t, err, msgAndArgs...)
+}
+
+
+// Exactly asserts that two objects are equal is value and type.
+// 
+//    a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+	Exactly(a.t, expected, actual, msgAndArgs...)
+}
+
+
+// Fail reports a failure through
+func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) {
+	Fail(a.t, failureMessage, msgAndArgs...)
+}
+
+
+// FailNow fails test
+func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) {
+	FailNow(a.t, failureMessage, msgAndArgs...)
+}
+
+
+// False asserts that the specified value is false.
+// 
+//    a.False(myBool, "myBool should be false")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) False(value bool, msgAndArgs ...interface{}) {
+	False(a.t, value, msgAndArgs...)
+}
+
+
+// HTTPBodyContains asserts that a specified handler returns a
+// body that contains a string.
+// 
+//  a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
+	HTTPBodyContains(a.t, handler, method, url, values, str)
+}
+
+
+// HTTPBodyNotContains asserts that a specified handler returns a
+// body that does not contain a string.
+// 
+//  a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
+	HTTPBodyNotContains(a.t, handler, method, url, values, str)
+}
+
+
+// HTTPError asserts that a specified handler returns an error status code.
+// 
+//  a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) {
+	HTTPError(a.t, handler, method, url, values)
+}
+
+
+// HTTPRedirect asserts that a specified handler returns a redirect status code.
+// 
+//  a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) {
+	HTTPRedirect(a.t, handler, method, url, values)
+}
+
+
+// HTTPSuccess asserts that a specified handler returns a success status code.
+// 
+//  a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) {
+	HTTPSuccess(a.t, handler, method, url, values)
+}
+
+
+// Implements asserts that an object is implemented by the specified interface.
+// 
+//    a.Implements((*MyInterface)(nil), new(MyObject), "MyObject")
+func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
+	Implements(a.t, interfaceObject, object, msgAndArgs...)
+}
+
+
+// InDelta asserts that the two numerals are within delta of each other.
+// 
+// 	 a.InDelta(math.Pi, (22 / 7.0), 0.01)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
+	InDelta(a.t, expected, actual, delta, msgAndArgs...)
+}
+
+
+// InDeltaSlice is the same as InDelta, except it compares two slices.
+func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
+	InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
+}
+
+
+// InEpsilon asserts that expected and actual have a relative error less than epsilon
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
+	InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
+}
+
+
+// InEpsilonSlice is the same as InEpsilon, except it compares two slices.
+func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
+	InEpsilonSlice(a.t, expected, actual, delta, msgAndArgs...)
+}
+
+
+// IsType asserts that the specified objects are of the same type.
+func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
+	IsType(a.t, expectedType, object, msgAndArgs...)
+}
+
+
+// JSONEq asserts that two JSON strings are equivalent.
+// 
+//  a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) {
+	JSONEq(a.t, expected, actual, msgAndArgs...)
+}
+
+
+// Len asserts that the specified object has specific length.
+// Len also fails if the object has a type that len() not accept.
+// 
+//    a.Len(mySlice, 3, "The size of slice is not 3")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) {
+	Len(a.t, object, length, msgAndArgs...)
+}
+
+
+// Nil asserts that the specified object is nil.
+// 
+//    a.Nil(err, "err should be nothing")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) {
+	Nil(a.t, object, msgAndArgs...)
+}
+
+
+// NoError asserts that a function returned no error (i.e. `nil`).
+// 
+//   actualObj, err := SomeFunction()
+//   if a.NoError(err) {
+// 	   assert.Equal(t, actualObj, expectedObj)
+//   }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) {
+	NoError(a.t, err, msgAndArgs...)
+}
+
+
+// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
+// specified substring or element.
+// 
+//    a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
+//    a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
+//    a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {
+	NotContains(a.t, s, contains, msgAndArgs...)
+}
+
+
+// NotEmpty asserts that the specified object is NOT empty.  I.e. not nil, "", false, 0 or either
+// a slice or a channel with len == 0.
+// 
+//  if a.NotEmpty(obj) {
+//    assert.Equal(t, "two", obj[1])
+//  }
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) {
+	NotEmpty(a.t, object, msgAndArgs...)
+}
+
+
+// NotEqual asserts that the specified values are NOT equal.
+// 
+//    a.NotEqual(obj1, obj2, "two objects shouldn't be equal")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+	NotEqual(a.t, expected, actual, msgAndArgs...)
+}
+
+
+// NotNil asserts that the specified object is not nil.
+// 
+//    a.NotNil(err, "err should be something")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) {
+	NotNil(a.t, object, msgAndArgs...)
+}
+
+
+// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
+// 
+//   a.NotPanics(func(){
+//     RemainCalm()
+//   }, "Calling RemainCalm() should NOT panic")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
+	NotPanics(a.t, f, msgAndArgs...)
+}
+
+
+// NotRegexp asserts that a specified regexp does not match a string.
+// 
+//  a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
+//  a.NotRegexp("^start", "it's not starting")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
+	NotRegexp(a.t, rx, str, msgAndArgs...)
+}
+
+
+// NotZero asserts that i is not the zero value for its type and returns the truth.
+func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) {
+	NotZero(a.t, i, msgAndArgs...)
+}
+
+
+// Panics asserts that the code inside the specified PanicTestFunc panics.
+// 
+//   a.Panics(func(){
+//     GoCrazy()
+//   }, "Calling GoCrazy() should panic")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
+	Panics(a.t, f, msgAndArgs...)
+}
+
+
+// Regexp asserts that a specified regexp matches a string.
+// 
+//  a.Regexp(regexp.MustCompile("start"), "it's starting")
+//  a.Regexp("start...$", "it's not starting")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
+	Regexp(a.t, rx, str, msgAndArgs...)
+}
+
+
+// True asserts that the specified value is true.
+// 
+//    a.True(myBool, "myBool should be true")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) True(value bool, msgAndArgs ...interface{}) {
+	True(a.t, value, msgAndArgs...)
+}
+
+
+// WithinDuration asserts that the two times are within duration delta of each other.
+// 
+//   a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
+// 
+// Returns whether the assertion was successful (true) or not (false).
+func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
+	WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
+}
+
+
+// Zero asserts that i is the zero value for its type and returns the truth.
+func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) {
+	Zero(a.t, i, msgAndArgs...)
+}
diff --git a/go/src/github.com/stretchr/testify/require/require_forward.go.tmpl b/go/src/github.com/stretchr/testify/require/require_forward.go.tmpl
new file mode 100644
index 0000000..b93569e
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/require/require_forward.go.tmpl
@@ -0,0 +1,4 @@
+{{.CommentWithoutT "a"}}
+func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) {
+	{{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
+}
diff --git a/go/src/github.com/stretchr/testify/require/requirements.go b/go/src/github.com/stretchr/testify/require/requirements.go
new file mode 100644
index 0000000..4114756
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/require/requirements.go
@@ -0,0 +1,9 @@
+package require
+
+// TestingT is an interface wrapper around *testing.T
+type TestingT interface {
+	Errorf(format string, args ...interface{})
+	FailNow()
+}
+
+//go:generate go run ../_codegen/main.go -output-package=require -template=require.go.tmpl
diff --git a/go/src/github.com/stretchr/testify/require/requirements_test.go b/go/src/github.com/stretchr/testify/require/requirements_test.go
new file mode 100644
index 0000000..d2ccc99
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/require/requirements_test.go
@@ -0,0 +1,369 @@
+package require
+
+import (
+	"errors"
+	"testing"
+	"time"
+)
+
+// AssertionTesterInterface defines an interface to be used for testing assertion methods
+type AssertionTesterInterface interface {
+	TestMethod()
+}
+
+// AssertionTesterConformingObject is an object that conforms to the AssertionTesterInterface interface
+type AssertionTesterConformingObject struct {
+}
+
+func (a *AssertionTesterConformingObject) TestMethod() {
+}
+
+// AssertionTesterNonConformingObject is an object that does not conform to the AssertionTesterInterface interface
+type AssertionTesterNonConformingObject struct {
+}
+
+type MockT struct {
+	Failed bool
+}
+
+func (t *MockT) FailNow() {
+	t.Failed = true
+}
+
+func (t *MockT) Errorf(format string, args ...interface{}) {
+	_, _ = format, args
+}
+
+func TestImplements(t *testing.T) {
+
+	Implements(t, (*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject))
+
+	mockT := new(MockT)
+	Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject))
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestIsType(t *testing.T) {
+
+	IsType(t, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject))
+
+	mockT := new(MockT)
+	IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject))
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestEqual(t *testing.T) {
+
+	Equal(t, 1, 1)
+
+	mockT := new(MockT)
+	Equal(mockT, 1, 2)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+
+}
+
+func TestNotEqual(t *testing.T) {
+
+	NotEqual(t, 1, 2)
+	mockT := new(MockT)
+	NotEqual(mockT, 2, 2)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestExactly(t *testing.T) {
+
+	a := float32(1)
+	b := float32(1)
+	c := float64(1)
+
+	Exactly(t, a, b)
+
+	mockT := new(MockT)
+	Exactly(mockT, a, c)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotNil(t *testing.T) {
+
+	NotNil(t, new(AssertionTesterConformingObject))
+
+	mockT := new(MockT)
+	NotNil(mockT, nil)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNil(t *testing.T) {
+
+	Nil(t, nil)
+
+	mockT := new(MockT)
+	Nil(mockT, new(AssertionTesterConformingObject))
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestTrue(t *testing.T) {
+
+	True(t, true)
+
+	mockT := new(MockT)
+	True(mockT, false)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestFalse(t *testing.T) {
+
+	False(t, false)
+
+	mockT := new(MockT)
+	False(mockT, true)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestContains(t *testing.T) {
+
+	Contains(t, "Hello World", "Hello")
+
+	mockT := new(MockT)
+	Contains(mockT, "Hello World", "Salut")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotContains(t *testing.T) {
+
+	NotContains(t, "Hello World", "Hello!")
+
+	mockT := new(MockT)
+	NotContains(mockT, "Hello World", "Hello")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestPanics(t *testing.T) {
+
+	Panics(t, func() {
+		panic("Panic!")
+	})
+
+	mockT := new(MockT)
+	Panics(mockT, func() {})
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotPanics(t *testing.T) {
+
+	NotPanics(t, func() {})
+
+	mockT := new(MockT)
+	NotPanics(mockT, func() {
+		panic("Panic!")
+	})
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNoError(t *testing.T) {
+
+	NoError(t, nil)
+
+	mockT := new(MockT)
+	NoError(mockT, errors.New("some error"))
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestError(t *testing.T) {
+
+	Error(t, errors.New("some error"))
+
+	mockT := new(MockT)
+	Error(mockT, nil)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestEqualError(t *testing.T) {
+
+	EqualError(t, errors.New("some error"), "some error")
+
+	mockT := new(MockT)
+	EqualError(mockT, errors.New("some error"), "Not some error")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestEmpty(t *testing.T) {
+
+	Empty(t, "")
+
+	mockT := new(MockT)
+	Empty(mockT, "x")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotEmpty(t *testing.T) {
+
+	NotEmpty(t, "x")
+
+	mockT := new(MockT)
+	NotEmpty(mockT, "")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestWithinDuration(t *testing.T) {
+
+	a := time.Now()
+	b := a.Add(10 * time.Second)
+
+	WithinDuration(t, a, b, 15*time.Second)
+
+	mockT := new(MockT)
+	WithinDuration(mockT, a, b, 5*time.Second)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestInDelta(t *testing.T) {
+
+	InDelta(t, 1.001, 1, 0.01)
+
+	mockT := new(MockT)
+	InDelta(mockT, 1, 2, 0.5)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestZero(t *testing.T) {
+
+	Zero(t, "")
+
+	mockT := new(MockT)
+	Zero(mockT, "x")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestNotZero(t *testing.T) {
+
+	NotZero(t, "x")
+
+	mockT := new(MockT)
+	NotZero(mockT, "")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEq_EqualSONString(t *testing.T) {
+	mockT := new(MockT)
+	JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestJSONEq_EquivalentButNotEqual(t *testing.T) {
+	mockT := new(MockT)
+	JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestJSONEq_HashOfArraysAndHashes(t *testing.T) {
+	mockT := new(MockT)
+	JSONEq(mockT, "{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
+		"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}")
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestJSONEq_Array(t *testing.T) {
+	mockT := new(MockT)
+	JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestJSONEq_HashAndArrayNotEquivalent(t *testing.T) {
+	mockT := new(MockT)
+	JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEq_HashesNotEquivalent(t *testing.T) {
+	mockT := new(MockT)
+	JSONEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEq_ActualIsNotJSON(t *testing.T) {
+	mockT := new(MockT)
+	JSONEq(mockT, `{"foo": "bar"}`, "Not JSON")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEq_ExpectedIsNotJSON(t *testing.T) {
+	mockT := new(MockT)
+	JSONEq(mockT, "Not JSON", `{"foo": "bar", "hello": "world"}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEq_ExpectedAndActualNotJSON(t *testing.T) {
+	mockT := new(MockT)
+	JSONEq(mockT, "Not JSON", "Not JSON")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) {
+	mockT := new(MockT)
+	JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
diff --git a/go/src/github.com/stretchr/testify/suite/doc.go b/go/src/github.com/stretchr/testify/suite/doc.go
new file mode 100644
index 0000000..f91a245
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/suite/doc.go
@@ -0,0 +1,65 @@
+// Package suite contains logic for creating testing suite structs
+// and running the methods on those structs as tests.  The most useful
+// piece of this package is that you can create setup/teardown methods
+// on your testing suites, which will run before/after the whole suite
+// or individual tests (depending on which interface(s) you
+// implement).
+//
+// A testing suite is usually built by first extending the built-in
+// suite functionality from suite.Suite in testify.  Alternatively,
+// you could reproduce that logic on your own if you wanted (you
+// just need to implement the TestingSuite interface from
+// suite/interfaces.go).
+//
+// After that, you can implement any of the interfaces in
+// suite/interfaces.go to add setup/teardown functionality to your
+// suite, and add any methods that start with "Test" to add tests.
+// Methods that do not match any suite interfaces and do not begin
+// with "Test" will not be run by testify, and can safely be used as
+// helper methods.
+//
+// Once you've built your testing suite, you need to run the suite
+// (using suite.Run from testify) inside any function that matches the
+// identity that "go test" is already looking for (i.e.
+// func(*testing.T)).
+//
+// Regular expression to select test suites specified command-line
+// argument "-run". Regular expression to select the methods
+// of test suites specified command-line argument "-m".
+// Suite object has assertion methods.
+//
+// A crude example:
+//     // Basic imports
+//     import (
+//         "testing"
+//         "github.com/stretchr/testify/assert"
+//         "github.com/stretchr/testify/suite"
+//     )
+//
+//     // Define the suite, and absorb the built-in basic suite
+//     // functionality from testify - including a T() method which
+//     // returns the current testing context
+//     type ExampleTestSuite struct {
+//         suite.Suite
+//         VariableThatShouldStartAtFive int
+//     }
+//
+//     // Make sure that VariableThatShouldStartAtFive is set to five
+//     // before each test
+//     func (suite *ExampleTestSuite) SetupTest() {
+//         suite.VariableThatShouldStartAtFive = 5
+//     }
+//
+//     // All methods that begin with "Test" are run as tests within a
+//     // suite.
+//     func (suite *ExampleTestSuite) TestExample() {
+//         assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
+//         suite.Equal(5, suite.VariableThatShouldStartAtFive)
+//     }
+//
+//     // In order for 'go test' to run this suite, we need to create
+//     // a normal test function and pass our suite to suite.Run
+//     func TestExampleTestSuite(t *testing.T) {
+//         suite.Run(t, new(ExampleTestSuite))
+//     }
+package suite
diff --git a/go/src/github.com/stretchr/testify/suite/interfaces.go b/go/src/github.com/stretchr/testify/suite/interfaces.go
new file mode 100644
index 0000000..2096947
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/suite/interfaces.go
@@ -0,0 +1,34 @@
+package suite
+
+import "testing"
+
+// TestingSuite can store and return the current *testing.T context
+// generated by 'go test'.
+type TestingSuite interface {
+	T() *testing.T
+	SetT(*testing.T)
+}
+
+// SetupAllSuite has a SetupSuite method, which will run before the
+// tests in the suite are run.
+type SetupAllSuite interface {
+	SetupSuite()
+}
+
+// SetupTestSuite has a SetupTest method, which will run before each
+// test in the suite.
+type SetupTestSuite interface {
+	SetupTest()
+}
+
+// TearDownAllSuite has a TearDownSuite method, which will run after
+// all the tests in the suite have been run.
+type TearDownAllSuite interface {
+	TearDownSuite()
+}
+
+// TearDownTestSuite has a TearDownTest method, which will run after
+// each test in the suite.
+type TearDownTestSuite interface {
+	TearDownTest()
+}
diff --git a/go/src/github.com/stretchr/testify/suite/suite.go b/go/src/github.com/stretchr/testify/suite/suite.go
new file mode 100644
index 0000000..f831e25
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/suite/suite.go
@@ -0,0 +1,115 @@
+package suite
+
+import (
+	"flag"
+	"fmt"
+	"os"
+	"reflect"
+	"regexp"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+var matchMethod = flag.String("m", "", "regular expression to select tests of the suite to run")
+
+// Suite is a basic testing suite with methods for storing and
+// retrieving the current *testing.T context.
+type Suite struct {
+	*assert.Assertions
+	require *require.Assertions
+	t       *testing.T
+}
+
+// T retrieves the current *testing.T context.
+func (suite *Suite) T() *testing.T {
+	return suite.t
+}
+
+// SetT sets the current *testing.T context.
+func (suite *Suite) SetT(t *testing.T) {
+	suite.t = t
+	suite.Assertions = assert.New(t)
+	suite.require = require.New(t)
+}
+
+// Require returns a require context for suite.
+func (suite *Suite) Require() *require.Assertions {
+	if suite.require == nil {
+		suite.require = require.New(suite.T())
+	}
+	return suite.require
+}
+
+// Assert returns an assert context for suite.  Normally, you can call
+// `suite.NoError(expected, actual)`, but for situations where the embedded
+// methods are overridden (for example, you might want to override
+// assert.Assertions with require.Assertions), this method is provided so you
+// can call `suite.Assert().NoError()`.
+func (suite *Suite) Assert() *assert.Assertions {
+	if suite.Assertions == nil {
+		suite.Assertions = assert.New(suite.T())
+	}
+	return suite.Assertions
+}
+
+// Run takes a testing suite and runs all of the tests attached
+// to it.
+func Run(t *testing.T, suite TestingSuite) {
+	suite.SetT(t)
+
+	if setupAllSuite, ok := suite.(SetupAllSuite); ok {
+		setupAllSuite.SetupSuite()
+	}
+	defer func() {
+		if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
+			tearDownAllSuite.TearDownSuite()
+		}
+	}()
+
+	methodFinder := reflect.TypeOf(suite)
+	tests := []testing.InternalTest{}
+	for index := 0; index < methodFinder.NumMethod(); index++ {
+		method := methodFinder.Method(index)
+		ok, err := methodFilter(method.Name)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
+			os.Exit(1)
+		}
+		if ok {
+			test := testing.InternalTest{
+				Name: method.Name,
+				F: func(t *testing.T) {
+					parentT := suite.T()
+					suite.SetT(t)
+					if setupTestSuite, ok := suite.(SetupTestSuite); ok {
+						setupTestSuite.SetupTest()
+					}
+					defer func() {
+						if tearDownTestSuite, ok := suite.(TearDownTestSuite); ok {
+							tearDownTestSuite.TearDownTest()
+						}
+						suite.SetT(parentT)
+					}()
+					method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
+				},
+			}
+			tests = append(tests, test)
+		}
+	}
+
+	if !testing.RunTests(func(_, _ string) (bool, error) { return true, nil },
+		tests) {
+		t.Fail()
+	}
+}
+
+// Filtering method according to set regular expression
+// specified command-line argument -m
+func methodFilter(name string) (bool, error) {
+	if ok, _ := regexp.MatchString("^Test", name); !ok {
+		return false, nil
+	}
+	return regexp.MatchString(*matchMethod, name)
+}
diff --git a/go/src/github.com/stretchr/testify/suite/suite_test.go b/go/src/github.com/stretchr/testify/suite/suite_test.go
new file mode 100644
index 0000000..c7c4e88
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/suite/suite_test.go
@@ -0,0 +1,239 @@
+package suite
+
+import (
+	"errors"
+	"io/ioutil"
+	"os"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+// SuiteRequireTwice is intended to test the usage of suite.Require in two
+// different tests
+type SuiteRequireTwice struct{ Suite }
+
+// TestSuiteRequireTwice checks for regressions of issue #149 where
+// suite.requirements was not initialised in suite.SetT()
+// A regression would result on these tests panicking rather than failing.
+func TestSuiteRequireTwice(t *testing.T) {
+	ok := testing.RunTests(
+		func(_, _ string) (bool, error) { return true, nil },
+		[]testing.InternalTest{{
+			Name: "TestSuiteRequireTwice",
+			F: func(t *testing.T) {
+				suite := new(SuiteRequireTwice)
+				Run(t, suite)
+			},
+		}},
+	)
+	assert.Equal(t, false, ok)
+}
+
+func (s *SuiteRequireTwice) TestRequireOne() {
+	r := s.Require()
+	r.Equal(1, 2)
+}
+
+func (s *SuiteRequireTwice) TestRequireTwo() {
+	r := s.Require()
+	r.Equal(1, 2)
+}
+
+// This suite is intended to store values to make sure that only
+// testing-suite-related methods are run.  It's also a fully
+// functional example of a testing suite, using setup/teardown methods
+// and a helper method that is ignored by testify.  To make this look
+// more like a real world example, all tests in the suite perform some
+// type of assertion.
+type SuiteTester struct {
+	// Include our basic suite logic.
+	Suite
+
+	// Keep counts of how many times each method is run.
+	SetupSuiteRunCount    int
+	TearDownSuiteRunCount int
+	SetupTestRunCount     int
+	TearDownTestRunCount  int
+	TestOneRunCount       int
+	TestTwoRunCount       int
+	NonTestMethodRunCount int
+}
+
+type SuiteSkipTester struct {
+	// Include our basic suite logic.
+	Suite
+
+	// Keep counts of how many times each method is run.
+	SetupSuiteRunCount    int
+	TearDownSuiteRunCount int
+}
+
+// The SetupSuite method will be run by testify once, at the very
+// start of the testing suite, before any tests are run.
+func (suite *SuiteTester) SetupSuite() {
+	suite.SetupSuiteRunCount++
+}
+
+func (suite *SuiteSkipTester) SetupSuite() {
+	suite.SetupSuiteRunCount++
+	suite.T().Skip()
+}
+
+// The TearDownSuite method will be run by testify once, at the very
+// end of the testing suite, after all tests have been run.
+func (suite *SuiteTester) TearDownSuite() {
+	suite.TearDownSuiteRunCount++
+}
+
+func (suite *SuiteSkipTester) TearDownSuite() {
+	suite.TearDownSuiteRunCount++
+}
+
+// The SetupTest method will be run before every test in the suite.
+func (suite *SuiteTester) SetupTest() {
+	suite.SetupTestRunCount++
+}
+
+// The TearDownTest method will be run after every test in the suite.
+func (suite *SuiteTester) TearDownTest() {
+	suite.TearDownTestRunCount++
+}
+
+// Every method in a testing suite that begins with "Test" will be run
+// as a test.  TestOne is an example of a test.  For the purposes of
+// this example, we've included assertions in the tests, since most
+// tests will issue assertions.
+func (suite *SuiteTester) TestOne() {
+	beforeCount := suite.TestOneRunCount
+	suite.TestOneRunCount++
+	assert.Equal(suite.T(), suite.TestOneRunCount, beforeCount+1)
+	suite.Equal(suite.TestOneRunCount, beforeCount+1)
+}
+
+// TestTwo is another example of a test.
+func (suite *SuiteTester) TestTwo() {
+	beforeCount := suite.TestTwoRunCount
+	suite.TestTwoRunCount++
+	assert.NotEqual(suite.T(), suite.TestTwoRunCount, beforeCount)
+	suite.NotEqual(suite.TestTwoRunCount, beforeCount)
+}
+
+func (suite *SuiteTester) TestSkip() {
+	suite.T().Skip()
+}
+
+// NonTestMethod does not begin with "Test", so it will not be run by
+// testify as a test in the suite.  This is useful for creating helper
+// methods for your tests.
+func (suite *SuiteTester) NonTestMethod() {
+	suite.NonTestMethodRunCount++
+}
+
+// TestRunSuite will be run by the 'go test' command, so within it, we
+// can run our suite using the Run(*testing.T, TestingSuite) function.
+func TestRunSuite(t *testing.T) {
+	suiteTester := new(SuiteTester)
+	Run(t, suiteTester)
+
+	// Normally, the test would end here.  The following are simply
+	// some assertions to ensure that the Run function is working as
+	// intended - they are not part of the example.
+
+	// The suite was only run once, so the SetupSuite and TearDownSuite
+	// methods should have each been run only once.
+	assert.Equal(t, suiteTester.SetupSuiteRunCount, 1)
+	assert.Equal(t, suiteTester.TearDownSuiteRunCount, 1)
+
+	// There are three test methods (TestOne, TestTwo, and TestSkip), so
+	// the SetupTest and TearDownTest methods (which should be run once for
+	// each test) should have been run three times.
+	assert.Equal(t, suiteTester.SetupTestRunCount, 3)
+	assert.Equal(t, suiteTester.TearDownTestRunCount, 3)
+
+	// Each test should have been run once.
+	assert.Equal(t, suiteTester.TestOneRunCount, 1)
+	assert.Equal(t, suiteTester.TestTwoRunCount, 1)
+
+	// Methods that don't match the test method identifier shouldn't
+	// have been run at all.
+	assert.Equal(t, suiteTester.NonTestMethodRunCount, 0)
+
+	suiteSkipTester := new(SuiteSkipTester)
+	Run(t, suiteSkipTester)
+
+	// The suite was only run once, so the SetupSuite and TearDownSuite
+	// methods should have each been run only once, even though SetupSuite
+	// called Skip()
+	assert.Equal(t, suiteSkipTester.SetupSuiteRunCount, 1)
+	assert.Equal(t, suiteSkipTester.TearDownSuiteRunCount, 1)
+
+}
+
+func TestSuiteGetters(t *testing.T) {
+	suite := new(SuiteTester)
+	suite.SetT(t)
+	assert.NotNil(t, suite.Assert())
+	assert.Equal(t, suite.Assertions, suite.Assert())
+	assert.NotNil(t, suite.Require())
+	assert.Equal(t, suite.require, suite.Require())
+}
+
+type SuiteLoggingTester struct {
+	Suite
+}
+
+func (s *SuiteLoggingTester) TestLoggingPass() {
+	s.T().Log("TESTLOGPASS")
+}
+
+func (s *SuiteLoggingTester) TestLoggingFail() {
+	s.T().Log("TESTLOGFAIL")
+	assert.NotNil(s.T(), nil) // expected to fail
+}
+
+type StdoutCapture struct {
+	oldStdout *os.File
+	readPipe  *os.File
+}
+
+func (sc *StdoutCapture) StartCapture() {
+	sc.oldStdout = os.Stdout
+	sc.readPipe, os.Stdout, _ = os.Pipe()
+}
+
+func (sc *StdoutCapture) StopCapture() (string, error) {
+	if sc.oldStdout == nil || sc.readPipe == nil {
+		return "", errors.New("StartCapture not called before StopCapture")
+	}
+	os.Stdout.Close()
+	os.Stdout = sc.oldStdout
+	bytes, err := ioutil.ReadAll(sc.readPipe)
+	if err != nil {
+		return "", err
+	}
+	return string(bytes), nil
+}
+
+func TestSuiteLogging(t *testing.T) {
+	testT := testing.T{}
+
+	suiteLoggingTester := new(SuiteLoggingTester)
+
+	capture := StdoutCapture{}
+	capture.StartCapture()
+	Run(&testT, suiteLoggingTester)
+	output, err := capture.StopCapture()
+
+	assert.Nil(t, err, "Got an error trying to capture stdout!")
+
+	// Failed tests' output is always printed
+	assert.Contains(t, output, "TESTLOGFAIL")
+
+	if testing.Verbose() {
+		// In verbose mode, output from successful tests is also printed
+		assert.Contains(t, output, "TESTLOGPASS")
+	} else {
+		assert.NotContains(t, output, "TESTLOGPASS")
+	}
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/LICENSE b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/LICENSE
new file mode 100644
index 0000000..2a7cfd2
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2012-2013 Dave Collins <dave@davec.name>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/bypass.go b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/bypass.go
new file mode 100644
index 0000000..565bf58
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/bypass.go
@@ -0,0 +1,151 @@
+// Copyright (c) 2015 Dave Collins <dave@davec.name>
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+// NOTE: Due to the following build constraints, this file will only be compiled
+// when the code is not running on Google App Engine and "-tags disableunsafe"
+// is not added to the go build command line.
+// +build !appengine,!disableunsafe
+
+package spew
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+const (
+	// UnsafeDisabled is a build-time constant which specifies whether or
+	// not access to the unsafe package is available.
+	UnsafeDisabled = false
+
+	// ptrSize is the size of a pointer on the current arch.
+	ptrSize = unsafe.Sizeof((*byte)(nil))
+)
+
+var (
+	// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
+	// internal reflect.Value fields.  These values are valid before golang
+	// commit ecccf07e7f9d which changed the format.  The are also valid
+	// after commit 82f48826c6c7 which changed the format again to mirror
+	// the original format.  Code in the init function updates these offsets
+	// as necessary.
+	offsetPtr    = uintptr(ptrSize)
+	offsetScalar = uintptr(0)
+	offsetFlag   = uintptr(ptrSize * 2)
+
+	// flagKindWidth and flagKindShift indicate various bits that the
+	// reflect package uses internally to track kind information.
+	//
+	// flagRO indicates whether or not the value field of a reflect.Value is
+	// read-only.
+	//
+	// flagIndir indicates whether the value field of a reflect.Value is
+	// the actual data or a pointer to the data.
+	//
+	// These values are valid before golang commit 90a7c3c86944 which
+	// changed their positions.  Code in the init function updates these
+	// flags as necessary.
+	flagKindWidth = uintptr(5)
+	flagKindShift = uintptr(flagKindWidth - 1)
+	flagRO        = uintptr(1 << 0)
+	flagIndir     = uintptr(1 << 1)
+)
+
+func init() {
+	// Older versions of reflect.Value stored small integers directly in the
+	// ptr field (which is named val in the older versions).  Versions
+	// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
+	// scalar for this purpose which unfortunately came before the flag
+	// field, so the offset of the flag field is different for those
+	// versions.
+	//
+	// This code constructs a new reflect.Value from a known small integer
+	// and checks if the size of the reflect.Value struct indicates it has
+	// the scalar field. When it does, the offsets are updated accordingly.
+	vv := reflect.ValueOf(0xf00)
+	if unsafe.Sizeof(vv) == (ptrSize * 4) {
+		offsetScalar = ptrSize * 2
+		offsetFlag = ptrSize * 3
+	}
+
+	// Commit 90a7c3c86944 changed the flag positions such that the low
+	// order bits are the kind.  This code extracts the kind from the flags
+	// field and ensures it's the correct type.  When it's not, the flag
+	// order has been changed to the newer format, so the flags are updated
+	// accordingly.
+	upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
+	upfv := *(*uintptr)(upf)
+	flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
+	if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
+		flagKindShift = 0
+		flagRO = 1 << 5
+		flagIndir = 1 << 6
+
+		// Commit adf9b30e5594 modified the flags to separate the
+		// flagRO flag into two bits which specifies whether or not the
+		// field is embedded.  This causes flagIndir to move over a bit
+		// and means that flagRO is the combination of either of the
+		// original flagRO bit and the new bit.
+		//
+		// This code detects the change by extracting what used to be
+		// the indirect bit to ensure it's set.  When it's not, the flag
+		// order has been changed to the newer format, so the flags are
+		// updated accordingly.
+		if upfv&flagIndir == 0 {
+			flagRO = 3 << 5
+			flagIndir = 1 << 7
+		}
+	}
+}
+
+// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
+// the typical safety restrictions preventing access to unaddressable and
+// unexported data.  It works by digging the raw pointer to the underlying
+// value out of the protected value and generating a new unprotected (unsafe)
+// reflect.Value to it.
+//
+// This allows us to check for implementations of the Stringer and error
+// interfaces to be used for pretty printing ordinarily unaddressable and
+// inaccessible values such as unexported struct fields.
+func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
+	indirects := 1
+	vt := v.Type()
+	upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
+	rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
+	if rvf&flagIndir != 0 {
+		vt = reflect.PtrTo(v.Type())
+		indirects++
+	} else if offsetScalar != 0 {
+		// The value is in the scalar field when it's not one of the
+		// reference types.
+		switch vt.Kind() {
+		case reflect.Uintptr:
+		case reflect.Chan:
+		case reflect.Func:
+		case reflect.Map:
+		case reflect.Ptr:
+		case reflect.UnsafePointer:
+		default:
+			upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
+				offsetScalar)
+		}
+	}
+
+	pv := reflect.NewAt(vt, upv)
+	rv = pv
+	for i := 0; i < indirects; i++ {
+		rv = rv.Elem()
+	}
+	return rv
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
new file mode 100644
index 0000000..457e412
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
@@ -0,0 +1,37 @@
+// Copyright (c) 2015 Dave Collins <dave@davec.name>
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+// NOTE: Due to the following build constraints, this file will only be compiled
+// when either the code is running on Google App Engine or "-tags disableunsafe"
+// is added to the go build command line.
+// +build appengine disableunsafe
+
+package spew
+
+import "reflect"
+
+const (
+	// UnsafeDisabled is a build-time constant which specifies whether or
+	// not access to the unsafe package is available.
+	UnsafeDisabled = true
+)
+
+// unsafeReflectValue typically converts the passed reflect.Value into a one
+// that bypasses the typical safety restrictions preventing access to
+// unaddressable and unexported data.  However, doing this relies on access to
+// the unsafe package.  This is a stub version which simply returns the passed
+// reflect.Value when the unsafe package is not available.
+func unsafeReflectValue(v reflect.Value) reflect.Value {
+	return v
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/common.go b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/common.go
new file mode 100644
index 0000000..14f02dc
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/common.go
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"reflect"
+	"sort"
+	"strconv"
+)
+
+// Some constants in the form of bytes to avoid string overhead.  This mirrors
+// the technique used in the fmt package.
+var (
+	panicBytes            = []byte("(PANIC=")
+	plusBytes             = []byte("+")
+	iBytes                = []byte("i")
+	trueBytes             = []byte("true")
+	falseBytes            = []byte("false")
+	interfaceBytes        = []byte("(interface {})")
+	commaNewlineBytes     = []byte(",\n")
+	newlineBytes          = []byte("\n")
+	openBraceBytes        = []byte("{")
+	openBraceNewlineBytes = []byte("{\n")
+	closeBraceBytes       = []byte("}")
+	asteriskBytes         = []byte("*")
+	colonBytes            = []byte(":")
+	colonSpaceBytes       = []byte(": ")
+	openParenBytes        = []byte("(")
+	closeParenBytes       = []byte(")")
+	spaceBytes            = []byte(" ")
+	pointerChainBytes     = []byte("->")
+	nilAngleBytes         = []byte("<nil>")
+	maxNewlineBytes       = []byte("<max depth reached>\n")
+	maxShortBytes         = []byte("<max>")
+	circularBytes         = []byte("<already shown>")
+	circularShortBytes    = []byte("<shown>")
+	invalidAngleBytes     = []byte("<invalid>")
+	openBracketBytes      = []byte("[")
+	closeBracketBytes     = []byte("]")
+	percentBytes          = []byte("%")
+	precisionBytes        = []byte(".")
+	openAngleBytes        = []byte("<")
+	closeAngleBytes       = []byte(">")
+	openMapBytes          = []byte("map[")
+	closeMapBytes         = []byte("]")
+	lenEqualsBytes        = []byte("len=")
+	capEqualsBytes        = []byte("cap=")
+)
+
+// hexDigits is used to map a decimal value to a hex digit.
+var hexDigits = "0123456789abcdef"
+
+// catchPanic handles any panics that might occur during the handleMethods
+// calls.
+func catchPanic(w io.Writer, v reflect.Value) {
+	if err := recover(); err != nil {
+		w.Write(panicBytes)
+		fmt.Fprintf(w, "%v", err)
+		w.Write(closeParenBytes)
+	}
+}
+
+// handleMethods attempts to call the Error and String methods on the underlying
+// type the passed reflect.Value represents and outputes the result to Writer w.
+//
+// It handles panics in any called methods by catching and displaying the error
+// as the formatted value.
+func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
+	// We need an interface to check if the type implements the error or
+	// Stringer interface.  However, the reflect package won't give us an
+	// interface on certain things like unexported struct fields in order
+	// to enforce visibility rules.  We use unsafe, when it's available,
+	// to bypass these restrictions since this package does not mutate the
+	// values.
+	if !v.CanInterface() {
+		if UnsafeDisabled {
+			return false
+		}
+
+		v = unsafeReflectValue(v)
+	}
+
+	// Choose whether or not to do error and Stringer interface lookups against
+	// the base type or a pointer to the base type depending on settings.
+	// Technically calling one of these methods with a pointer receiver can
+	// mutate the value, however, types which choose to satisify an error or
+	// Stringer interface with a pointer receiver should not be mutating their
+	// state inside these interface methods.
+	if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
+		v = unsafeReflectValue(v)
+	}
+	if v.CanAddr() {
+		v = v.Addr()
+	}
+
+	// Is it an error or Stringer?
+	switch iface := v.Interface().(type) {
+	case error:
+		defer catchPanic(w, v)
+		if cs.ContinueOnMethod {
+			w.Write(openParenBytes)
+			w.Write([]byte(iface.Error()))
+			w.Write(closeParenBytes)
+			w.Write(spaceBytes)
+			return false
+		}
+
+		w.Write([]byte(iface.Error()))
+		return true
+
+	case fmt.Stringer:
+		defer catchPanic(w, v)
+		if cs.ContinueOnMethod {
+			w.Write(openParenBytes)
+			w.Write([]byte(iface.String()))
+			w.Write(closeParenBytes)
+			w.Write(spaceBytes)
+			return false
+		}
+		w.Write([]byte(iface.String()))
+		return true
+	}
+	return false
+}
+
+// printBool outputs a boolean value as true or false to Writer w.
+func printBool(w io.Writer, val bool) {
+	if val {
+		w.Write(trueBytes)
+	} else {
+		w.Write(falseBytes)
+	}
+}
+
+// printInt outputs a signed integer value to Writer w.
+func printInt(w io.Writer, val int64, base int) {
+	w.Write([]byte(strconv.FormatInt(val, base)))
+}
+
+// printUint outputs an unsigned integer value to Writer w.
+func printUint(w io.Writer, val uint64, base int) {
+	w.Write([]byte(strconv.FormatUint(val, base)))
+}
+
+// printFloat outputs a floating point value using the specified precision,
+// which is expected to be 32 or 64bit, to Writer w.
+func printFloat(w io.Writer, val float64, precision int) {
+	w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
+}
+
+// printComplex outputs a complex value using the specified float precision
+// for the real and imaginary parts to Writer w.
+func printComplex(w io.Writer, c complex128, floatPrecision int) {
+	r := real(c)
+	w.Write(openParenBytes)
+	w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
+	i := imag(c)
+	if i >= 0 {
+		w.Write(plusBytes)
+	}
+	w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
+	w.Write(iBytes)
+	w.Write(closeParenBytes)
+}
+
+// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
+// prefix to Writer w.
+func printHexPtr(w io.Writer, p uintptr) {
+	// Null pointer.
+	num := uint64(p)
+	if num == 0 {
+		w.Write(nilAngleBytes)
+		return
+	}
+
+	// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
+	buf := make([]byte, 18)
+
+	// It's simpler to construct the hex string right to left.
+	base := uint64(16)
+	i := len(buf) - 1
+	for num >= base {
+		buf[i] = hexDigits[num%base]
+		num /= base
+		i--
+	}
+	buf[i] = hexDigits[num]
+
+	// Add '0x' prefix.
+	i--
+	buf[i] = 'x'
+	i--
+	buf[i] = '0'
+
+	// Strip unused leading bytes.
+	buf = buf[i:]
+	w.Write(buf)
+}
+
+// valuesSorter implements sort.Interface to allow a slice of reflect.Value
+// elements to be sorted.
+type valuesSorter struct {
+	values  []reflect.Value
+	strings []string // either nil or same len and values
+	cs      *ConfigState
+}
+
+// newValuesSorter initializes a valuesSorter instance, which holds a set of
+// surrogate keys on which the data should be sorted.  It uses flags in
+// ConfigState to decide if and how to populate those surrogate keys.
+func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
+	vs := &valuesSorter{values: values, cs: cs}
+	if canSortSimply(vs.values[0].Kind()) {
+		return vs
+	}
+	if !cs.DisableMethods {
+		vs.strings = make([]string, len(values))
+		for i := range vs.values {
+			b := bytes.Buffer{}
+			if !handleMethods(cs, &b, vs.values[i]) {
+				vs.strings = nil
+				break
+			}
+			vs.strings[i] = b.String()
+		}
+	}
+	if vs.strings == nil && cs.SpewKeys {
+		vs.strings = make([]string, len(values))
+		for i := range vs.values {
+			vs.strings[i] = Sprintf("%#v", vs.values[i].Interface())
+		}
+	}
+	return vs
+}
+
+// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
+// directly, or whether it should be considered for sorting by surrogate keys
+// (if the ConfigState allows it).
+func canSortSimply(kind reflect.Kind) bool {
+	// This switch parallels valueSortLess, except for the default case.
+	switch kind {
+	case reflect.Bool:
+		return true
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+		return true
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+		return true
+	case reflect.Float32, reflect.Float64:
+		return true
+	case reflect.String:
+		return true
+	case reflect.Uintptr:
+		return true
+	case reflect.Array:
+		return true
+	}
+	return false
+}
+
+// Len returns the number of values in the slice.  It is part of the
+// sort.Interface implementation.
+func (s *valuesSorter) Len() int {
+	return len(s.values)
+}
+
+// Swap swaps the values at the passed indices.  It is part of the
+// sort.Interface implementation.
+func (s *valuesSorter) Swap(i, j int) {
+	s.values[i], s.values[j] = s.values[j], s.values[i]
+	if s.strings != nil {
+		s.strings[i], s.strings[j] = s.strings[j], s.strings[i]
+	}
+}
+
+// valueSortLess returns whether the first value should sort before the second
+// value.  It is used by valueSorter.Less as part of the sort.Interface
+// implementation.
+func valueSortLess(a, b reflect.Value) bool {
+	switch a.Kind() {
+	case reflect.Bool:
+		return !a.Bool() && b.Bool()
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+		return a.Int() < b.Int()
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+		return a.Uint() < b.Uint()
+	case reflect.Float32, reflect.Float64:
+		return a.Float() < b.Float()
+	case reflect.String:
+		return a.String() < b.String()
+	case reflect.Uintptr:
+		return a.Uint() < b.Uint()
+	case reflect.Array:
+		// Compare the contents of both arrays.
+		l := a.Len()
+		for i := 0; i < l; i++ {
+			av := a.Index(i)
+			bv := b.Index(i)
+			if av.Interface() == bv.Interface() {
+				continue
+			}
+			return valueSortLess(av, bv)
+		}
+	}
+	return a.String() < b.String()
+}
+
+// Less returns whether the value at index i should sort before the
+// value at index j.  It is part of the sort.Interface implementation.
+func (s *valuesSorter) Less(i, j int) bool {
+	if s.strings == nil {
+		return valueSortLess(s.values[i], s.values[j])
+	}
+	return s.strings[i] < s.strings[j]
+}
+
+// sortValues is a sort function that handles both native types and any type that
+// can be converted to error or Stringer.  Other inputs are sorted according to
+// their Value.String() value to ensure display stability.
+func sortValues(values []reflect.Value, cs *ConfigState) {
+	if len(values) == 0 {
+		return
+	}
+	sort.Sort(newValuesSorter(values, cs))
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/config.go b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/config.go
new file mode 100644
index 0000000..ee1ab07
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/config.go
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+)
+
+// ConfigState houses the configuration options used by spew to format and
+// display values.  There is a global instance, Config, that is used to control
+// all top-level Formatter and Dump functionality.  Each ConfigState instance
+// provides methods equivalent to the top-level functions.
+//
+// The zero value for ConfigState provides no indentation.  You would typically
+// want to set it to a space or a tab.
+//
+// Alternatively, you can use NewDefaultConfig to get a ConfigState instance
+// with default settings.  See the documentation of NewDefaultConfig for default
+// values.
+type ConfigState struct {
+	// Indent specifies the string to use for each indentation level.  The
+	// global config instance that all top-level functions use set this to a
+	// single space by default.  If you would like more indentation, you might
+	// set this to a tab with "\t" or perhaps two spaces with "  ".
+	Indent string
+
+	// MaxDepth controls the maximum number of levels to descend into nested
+	// data structures.  The default, 0, means there is no limit.
+	//
+	// NOTE: Circular data structures are properly detected, so it is not
+	// necessary to set this value unless you specifically want to limit deeply
+	// nested data structures.
+	MaxDepth int
+
+	// DisableMethods specifies whether or not error and Stringer interfaces are
+	// invoked for types that implement them.
+	DisableMethods bool
+
+	// DisablePointerMethods specifies whether or not to check for and invoke
+	// error and Stringer interfaces on types which only accept a pointer
+	// receiver when the current type is not a pointer.
+	//
+	// NOTE: This might be an unsafe action since calling one of these methods
+	// with a pointer receiver could technically mutate the value, however,
+	// in practice, types which choose to satisify an error or Stringer
+	// interface with a pointer receiver should not be mutating their state
+	// inside these interface methods.  As a result, this option relies on
+	// access to the unsafe package, so it will not have any effect when
+	// running in environments without access to the unsafe package such as
+	// Google App Engine or with the "disableunsafe" build tag specified.
+	DisablePointerMethods bool
+
+	// ContinueOnMethod specifies whether or not recursion should continue once
+	// a custom error or Stringer interface is invoked.  The default, false,
+	// means it will print the results of invoking the custom error or Stringer
+	// interface and return immediately instead of continuing to recurse into
+	// the internals of the data type.
+	//
+	// NOTE: This flag does not have any effect if method invocation is disabled
+	// via the DisableMethods or DisablePointerMethods options.
+	ContinueOnMethod bool
+
+	// SortKeys specifies map keys should be sorted before being printed. Use
+	// this to have a more deterministic, diffable output.  Note that only
+	// native types (bool, int, uint, floats, uintptr and string) and types
+	// that support the error or Stringer interfaces (if methods are
+	// enabled) are supported, with other types sorted according to the
+	// reflect.Value.String() output which guarantees display stability.
+	SortKeys bool
+
+	// SpewKeys specifies that, as a last resort attempt, map keys should
+	// be spewed to strings and sorted by those strings.  This is only
+	// considered if SortKeys is true.
+	SpewKeys bool
+}
+
+// Config is the active configuration of the top-level functions.
+// The configuration can be changed by modifying the contents of spew.Config.
+var Config = ConfigState{Indent: " "}
+
+// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the formatted string as a value that satisfies error.  See NewFormatter
+// for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {
+	return fmt.Errorf(format, c.convertArgs(a)...)
+}
+
+// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
+	return fmt.Fprint(w, c.convertArgs(a)...)
+}
+
+// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
+	return fmt.Fprintf(w, format, c.convertArgs(a)...)
+}
+
+// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
+// passed with a Formatter interface returned by c.NewFormatter.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
+	return fmt.Fprintln(w, c.convertArgs(a)...)
+}
+
+// Print is a wrapper for fmt.Print that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
+	return fmt.Print(c.convertArgs(a)...)
+}
+
+// Printf is a wrapper for fmt.Printf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {
+	return fmt.Printf(format, c.convertArgs(a)...)
+}
+
+// Println is a wrapper for fmt.Println that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
+	return fmt.Println(c.convertArgs(a)...)
+}
+
+// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Sprint(a ...interface{}) string {
+	return fmt.Sprint(c.convertArgs(a)...)
+}
+
+// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
+// the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
+	return fmt.Sprintf(format, c.convertArgs(a)...)
+}
+
+// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
+// were passed with a Formatter interface returned by c.NewFormatter.  It
+// returns the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))
+func (c *ConfigState) Sprintln(a ...interface{}) string {
+	return fmt.Sprintln(c.convertArgs(a)...)
+}
+
+/*
+NewFormatter returns a custom formatter that satisfies the fmt.Formatter
+interface.  As a result, it integrates cleanly with standard fmt package
+printing functions.  The formatter is useful for inline printing of smaller data
+types similar to the standard %v format specifier.
+
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
+addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
+combinations.  Any other verbs such as %x and %q will be sent to the the
+standard fmt package for formatting.  In addition, the custom formatter ignores
+the width and precision arguments (however they will still work on the format
+specifiers not handled by the custom formatter).
+
+Typically this function shouldn't be called directly.  It is much easier to make
+use of the custom formatter by calling one of the convenience functions such as
+c.Printf, c.Println, or c.Printf.
+*/
+func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
+	return newFormatter(c, v)
+}
+
+// Fdump formats and displays the passed arguments to io.Writer w.  It formats
+// exactly the same as Dump.
+func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
+	fdump(c, w, a...)
+}
+
+/*
+Dump displays the passed parameters to standard out with newlines, customizable
+indentation, and additional debug information such as complete types and all
+pointer addresses used to indirect to the final value.  It provides the
+following features over the built-in printing facilities provided by the fmt
+package:
+
+	* Pointers are dereferenced and followed
+	* Circular data structures are detected and handled properly
+	* Custom Stringer/error interfaces are optionally invoked, including
+	  on unexported types
+	* Custom types which only implement the Stringer/error interfaces via
+	  a pointer receiver are optionally invoked when passing non-pointer
+	  variables
+	* Byte arrays and slices are dumped like the hexdump -C command which
+	  includes offsets, byte values in hex, and ASCII output
+
+The configuration options are controlled by modifying the public members
+of c.  See ConfigState for options documentation.
+
+See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
+get the formatted result as a string.
+*/
+func (c *ConfigState) Dump(a ...interface{}) {
+	fdump(c, os.Stdout, a...)
+}
+
+// Sdump returns a string with the passed arguments formatted exactly the same
+// as Dump.
+func (c *ConfigState) Sdump(a ...interface{}) string {
+	var buf bytes.Buffer
+	fdump(c, &buf, a...)
+	return buf.String()
+}
+
+// convertArgs accepts a slice of arguments and returns a slice of the same
+// length with each argument converted to a spew Formatter interface using
+// the ConfigState associated with s.
+func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {
+	formatters = make([]interface{}, len(args))
+	for index, arg := range args {
+		formatters[index] = newFormatter(c, arg)
+	}
+	return formatters
+}
+
+// NewDefaultConfig returns a ConfigState with the following default settings.
+//
+// 	Indent: " "
+// 	MaxDepth: 0
+// 	DisableMethods: false
+// 	DisablePointerMethods: false
+// 	ContinueOnMethod: false
+// 	SortKeys: false
+func NewDefaultConfig() *ConfigState {
+	return &ConfigState{Indent: " "}
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/doc.go b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/doc.go
new file mode 100644
index 0000000..5be0c40
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/doc.go
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+Package spew implements a deep pretty printer for Go data structures to aid in
+debugging.
+
+A quick overview of the additional features spew provides over the built-in
+printing facilities for Go data types are as follows:
+
+	* Pointers are dereferenced and followed
+	* Circular data structures are detected and handled properly
+	* Custom Stringer/error interfaces are optionally invoked, including
+	  on unexported types
+	* Custom types which only implement the Stringer/error interfaces via
+	  a pointer receiver are optionally invoked when passing non-pointer
+	  variables
+	* Byte arrays and slices are dumped like the hexdump -C command which
+	  includes offsets, byte values in hex, and ASCII output (only when using
+	  Dump style)
+
+There are two different approaches spew allows for dumping Go data structures:
+
+	* Dump style which prints with newlines, customizable indentation,
+	  and additional debug information such as types and all pointer addresses
+	  used to indirect to the final value
+	* A custom Formatter interface that integrates cleanly with the standard fmt
+	  package and replaces %v, %+v, %#v, and %#+v to provide inline printing
+	  similar to the default %v while providing the additional functionality
+	  outlined above and passing unsupported format verbs such as %x and %q
+	  along to fmt
+
+Quick Start
+
+This section demonstrates how to quickly get started with spew.  See the
+sections below for further details on formatting and configuration options.
+
+To dump a variable with full newlines, indentation, type, and pointer
+information use Dump, Fdump, or Sdump:
+	spew.Dump(myVar1, myVar2, ...)
+	spew.Fdump(someWriter, myVar1, myVar2, ...)
+	str := spew.Sdump(myVar1, myVar2, ...)
+
+Alternatively, if you would prefer to use format strings with a compacted inline
+printing style, use the convenience wrappers Printf, Fprintf, etc with
+%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
+%#+v (adds types and pointer addresses):
+	spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+	spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+	spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+	spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+
+Configuration Options
+
+Configuration of spew is handled by fields in the ConfigState type.  For
+convenience, all of the top-level functions use a global state available
+via the spew.Config global.
+
+It is also possible to create a ConfigState instance that provides methods
+equivalent to the top-level functions.  This allows concurrent configuration
+options.  See the ConfigState documentation for more details.
+
+The following configuration options are available:
+	* Indent
+		String to use for each indentation level for Dump functions.
+		It is a single space by default.  A popular alternative is "\t".
+
+	* MaxDepth
+		Maximum number of levels to descend into nested data structures.
+		There is no limit by default.
+
+	* DisableMethods
+		Disables invocation of error and Stringer interface methods.
+		Method invocation is enabled by default.
+
+	* DisablePointerMethods
+		Disables invocation of error and Stringer interface methods on types
+		which only accept pointer receivers from non-pointer variables.
+		Pointer method invocation is enabled by default.
+
+	* ContinueOnMethod
+		Enables recursion into types after invoking error and Stringer interface
+		methods. Recursion after method invocation is disabled by default.
+
+	* SortKeys
+		Specifies map keys should be sorted before being printed. Use
+		this to have a more deterministic, diffable output.  Note that
+		only native types (bool, int, uint, floats, uintptr and string)
+		and types which implement error or Stringer interfaces are
+		supported with other types sorted according to the
+		reflect.Value.String() output which guarantees display
+		stability.  Natural map order is used by default.
+
+	* SpewKeys
+		Specifies that, as a last resort attempt, map keys should be
+		spewed to strings and sorted by those strings.  This is only
+		considered if SortKeys is true.
+
+Dump Usage
+
+Simply call spew.Dump with a list of variables you want to dump:
+
+	spew.Dump(myVar1, myVar2, ...)
+
+You may also call spew.Fdump if you would prefer to output to an arbitrary
+io.Writer.  For example, to dump to standard error:
+
+	spew.Fdump(os.Stderr, myVar1, myVar2, ...)
+
+A third option is to call spew.Sdump to get the formatted output as a string:
+
+	str := spew.Sdump(myVar1, myVar2, ...)
+
+Sample Dump Output
+
+See the Dump example for details on the setup of the types and variables being
+shown here.
+
+	(main.Foo) {
+	 unexportedField: (*main.Bar)(0xf84002e210)({
+	  flag: (main.Flag) flagTwo,
+	  data: (uintptr) <nil>
+	 }),
+	 ExportedField: (map[interface {}]interface {}) (len=1) {
+	  (string) (len=3) "one": (bool) true
+	 }
+	}
+
+Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
+command as shown.
+	([]uint8) (len=32 cap=32) {
+	 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... |
+	 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0|
+	 00000020  31 32                                             |12|
+	}
+
+Custom Formatter
+
+Spew provides a custom formatter that implements the fmt.Formatter interface
+so that it integrates cleanly with standard fmt package printing functions. The
+formatter is useful for inline printing of smaller data types similar to the
+standard %v format specifier.
+
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
+addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
+combinations.  Any other verbs such as %x and %q will be sent to the the
+standard fmt package for formatting.  In addition, the custom formatter ignores
+the width and precision arguments (however they will still work on the format
+specifiers not handled by the custom formatter).
+
+Custom Formatter Usage
+
+The simplest way to make use of the spew custom formatter is to call one of the
+convenience functions such as spew.Printf, spew.Println, or spew.Printf.  The
+functions have syntax you are most likely already familiar with:
+
+	spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+	spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+	spew.Println(myVar, myVar2)
+	spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
+	spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
+
+See the Index for the full list convenience functions.
+
+Sample Formatter Output
+
+Double pointer to a uint8:
+	  %v: <**>5
+	 %+v: <**>(0xf8400420d0->0xf8400420c8)5
+	 %#v: (**uint8)5
+	%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
+
+Pointer to circular struct with a uint8 field and a pointer to itself:
+	  %v: <*>{1 <*><shown>}
+	 %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
+	 %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
+	%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}
+
+See the Printf example for details on the setup of variables being shown
+here.
+
+Errors
+
+Since it is possible for custom Stringer/error interfaces to panic, spew
+detects them and handles them internally by printing the panic information
+inline with the output.  Since spew is intended to provide deep pretty printing
+capabilities on structures, it intentionally does not return any errors.
+*/
+package spew
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/dump.go b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/dump.go
new file mode 100644
index 0000000..a0ff95e
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/dump.go
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+	"bytes"
+	"encoding/hex"
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+var (
+	// uint8Type is a reflect.Type representing a uint8.  It is used to
+	// convert cgo types to uint8 slices for hexdumping.
+	uint8Type = reflect.TypeOf(uint8(0))
+
+	// cCharRE is a regular expression that matches a cgo char.
+	// It is used to detect character arrays to hexdump them.
+	cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
+
+	// cUnsignedCharRE is a regular expression that matches a cgo unsigned
+	// char.  It is used to detect unsigned character arrays to hexdump
+	// them.
+	cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
+
+	// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
+	// It is used to detect uint8_t arrays to hexdump them.
+	cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
+)
+
+// dumpState contains information about the state of a dump operation.
+type dumpState struct {
+	w                io.Writer
+	depth            int
+	pointers         map[uintptr]int
+	ignoreNextType   bool
+	ignoreNextIndent bool
+	cs               *ConfigState
+}
+
+// indent performs indentation according to the depth level and cs.Indent
+// option.
+func (d *dumpState) indent() {
+	if d.ignoreNextIndent {
+		d.ignoreNextIndent = false
+		return
+	}
+	d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
+}
+
+// unpackValue returns values inside of non-nil interfaces when possible.
+// This is useful for data types like structs, arrays, slices, and maps which
+// can contain varying types packed inside an interface.
+func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
+	if v.Kind() == reflect.Interface && !v.IsNil() {
+		v = v.Elem()
+	}
+	return v
+}
+
+// dumpPtr handles formatting of pointers by indirecting them as necessary.
+func (d *dumpState) dumpPtr(v reflect.Value) {
+	// Remove pointers at or below the current depth from map used to detect
+	// circular refs.
+	for k, depth := range d.pointers {
+		if depth >= d.depth {
+			delete(d.pointers, k)
+		}
+	}
+
+	// Keep list of all dereferenced pointers to show later.
+	pointerChain := make([]uintptr, 0)
+
+	// Figure out how many levels of indirection there are by dereferencing
+	// pointers and unpacking interfaces down the chain while detecting circular
+	// references.
+	nilFound := false
+	cycleFound := false
+	indirects := 0
+	ve := v
+	for ve.Kind() == reflect.Ptr {
+		if ve.IsNil() {
+			nilFound = true
+			break
+		}
+		indirects++
+		addr := ve.Pointer()
+		pointerChain = append(pointerChain, addr)
+		if pd, ok := d.pointers[addr]; ok && pd < d.depth {
+			cycleFound = true
+			indirects--
+			break
+		}
+		d.pointers[addr] = d.depth
+
+		ve = ve.Elem()
+		if ve.Kind() == reflect.Interface {
+			if ve.IsNil() {
+				nilFound = true
+				break
+			}
+			ve = ve.Elem()
+		}
+	}
+
+	// Display type information.
+	d.w.Write(openParenBytes)
+	d.w.Write(bytes.Repeat(asteriskBytes, indirects))
+	d.w.Write([]byte(ve.Type().String()))
+	d.w.Write(closeParenBytes)
+
+	// Display pointer information.
+	if len(pointerChain) > 0 {
+		d.w.Write(openParenBytes)
+		for i, addr := range pointerChain {
+			if i > 0 {
+				d.w.Write(pointerChainBytes)
+			}
+			printHexPtr(d.w, addr)
+		}
+		d.w.Write(closeParenBytes)
+	}
+
+	// Display dereferenced value.
+	d.w.Write(openParenBytes)
+	switch {
+	case nilFound == true:
+		d.w.Write(nilAngleBytes)
+
+	case cycleFound == true:
+		d.w.Write(circularBytes)
+
+	default:
+		d.ignoreNextType = true
+		d.dump(ve)
+	}
+	d.w.Write(closeParenBytes)
+}
+
+// dumpSlice handles formatting of arrays and slices.  Byte (uint8 under
+// reflection) arrays and slices are dumped in hexdump -C fashion.
+func (d *dumpState) dumpSlice(v reflect.Value) {
+	// Determine whether this type should be hex dumped or not.  Also,
+	// for types which should be hexdumped, try to use the underlying data
+	// first, then fall back to trying to convert them to a uint8 slice.
+	var buf []uint8
+	doConvert := false
+	doHexDump := false
+	numEntries := v.Len()
+	if numEntries > 0 {
+		vt := v.Index(0).Type()
+		vts := vt.String()
+		switch {
+		// C types that need to be converted.
+		case cCharRE.MatchString(vts):
+			fallthrough
+		case cUnsignedCharRE.MatchString(vts):
+			fallthrough
+		case cUint8tCharRE.MatchString(vts):
+			doConvert = true
+
+		// Try to use existing uint8 slices and fall back to converting
+		// and copying if that fails.
+		case vt.Kind() == reflect.Uint8:
+			// We need an addressable interface to convert the type
+			// to a byte slice.  However, the reflect package won't
+			// give us an interface on certain things like
+			// unexported struct fields in order to enforce
+			// visibility rules.  We use unsafe, when available, to
+			// bypass these restrictions since this package does not
+			// mutate the values.
+			vs := v
+			if !vs.CanInterface() || !vs.CanAddr() {
+				vs = unsafeReflectValue(vs)
+			}
+			if !UnsafeDisabled {
+				vs = vs.Slice(0, numEntries)
+
+				// Use the existing uint8 slice if it can be
+				// type asserted.
+				iface := vs.Interface()
+				if slice, ok := iface.([]uint8); ok {
+					buf = slice
+					doHexDump = true
+					break
+				}
+			}
+
+			// The underlying data needs to be converted if it can't
+			// be type asserted to a uint8 slice.
+			doConvert = true
+		}
+
+		// Copy and convert the underlying type if needed.
+		if doConvert && vt.ConvertibleTo(uint8Type) {
+			// Convert and copy each element into a uint8 byte
+			// slice.
+			buf = make([]uint8, numEntries)
+			for i := 0; i < numEntries; i++ {
+				vv := v.Index(i)
+				buf[i] = uint8(vv.Convert(uint8Type).Uint())
+			}
+			doHexDump = true
+		}
+	}
+
+	// Hexdump the entire slice as needed.
+	if doHexDump {
+		indent := strings.Repeat(d.cs.Indent, d.depth)
+		str := indent + hex.Dump(buf)
+		str = strings.Replace(str, "\n", "\n"+indent, -1)
+		str = strings.TrimRight(str, d.cs.Indent)
+		d.w.Write([]byte(str))
+		return
+	}
+
+	// Recursively call dump for each item.
+	for i := 0; i < numEntries; i++ {
+		d.dump(d.unpackValue(v.Index(i)))
+		if i < (numEntries - 1) {
+			d.w.Write(commaNewlineBytes)
+		} else {
+			d.w.Write(newlineBytes)
+		}
+	}
+}
+
+// dump is the main workhorse for dumping a value.  It uses the passed reflect
+// value to figure out what kind of object we are dealing with and formats it
+// appropriately.  It is a recursive function, however circular data structures
+// are detected and handled properly.
+func (d *dumpState) dump(v reflect.Value) {
+	// Handle invalid reflect values immediately.
+	kind := v.Kind()
+	if kind == reflect.Invalid {
+		d.w.Write(invalidAngleBytes)
+		return
+	}
+
+	// Handle pointers specially.
+	if kind == reflect.Ptr {
+		d.indent()
+		d.dumpPtr(v)
+		return
+	}
+
+	// Print type information unless already handled elsewhere.
+	if !d.ignoreNextType {
+		d.indent()
+		d.w.Write(openParenBytes)
+		d.w.Write([]byte(v.Type().String()))
+		d.w.Write(closeParenBytes)
+		d.w.Write(spaceBytes)
+	}
+	d.ignoreNextType = false
+
+	// Display length and capacity if the built-in len and cap functions
+	// work with the value's kind and the len/cap itself is non-zero.
+	valueLen, valueCap := 0, 0
+	switch v.Kind() {
+	case reflect.Array, reflect.Slice, reflect.Chan:
+		valueLen, valueCap = v.Len(), v.Cap()
+	case reflect.Map, reflect.String:
+		valueLen = v.Len()
+	}
+	if valueLen != 0 || valueCap != 0 {
+		d.w.Write(openParenBytes)
+		if valueLen != 0 {
+			d.w.Write(lenEqualsBytes)
+			printInt(d.w, int64(valueLen), 10)
+		}
+		if valueCap != 0 {
+			if valueLen != 0 {
+				d.w.Write(spaceBytes)
+			}
+			d.w.Write(capEqualsBytes)
+			printInt(d.w, int64(valueCap), 10)
+		}
+		d.w.Write(closeParenBytes)
+		d.w.Write(spaceBytes)
+	}
+
+	// Call Stringer/error interfaces if they exist and the handle methods flag
+	// is enabled
+	if !d.cs.DisableMethods {
+		if (kind != reflect.Invalid) && (kind != reflect.Interface) {
+			if handled := handleMethods(d.cs, d.w, v); handled {
+				return
+			}
+		}
+	}
+
+	switch kind {
+	case reflect.Invalid:
+		// Do nothing.  We should never get here since invalid has already
+		// been handled above.
+
+	case reflect.Bool:
+		printBool(d.w, v.Bool())
+
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+		printInt(d.w, v.Int(), 10)
+
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+		printUint(d.w, v.Uint(), 10)
+
+	case reflect.Float32:
+		printFloat(d.w, v.Float(), 32)
+
+	case reflect.Float64:
+		printFloat(d.w, v.Float(), 64)
+
+	case reflect.Complex64:
+		printComplex(d.w, v.Complex(), 32)
+
+	case reflect.Complex128:
+		printComplex(d.w, v.Complex(), 64)
+
+	case reflect.Slice:
+		if v.IsNil() {
+			d.w.Write(nilAngleBytes)
+			break
+		}
+		fallthrough
+
+	case reflect.Array:
+		d.w.Write(openBraceNewlineBytes)
+		d.depth++
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
+			d.indent()
+			d.w.Write(maxNewlineBytes)
+		} else {
+			d.dumpSlice(v)
+		}
+		d.depth--
+		d.indent()
+		d.w.Write(closeBraceBytes)
+
+	case reflect.String:
+		d.w.Write([]byte(strconv.Quote(v.String())))
+
+	case reflect.Interface:
+		// The only time we should get here is for nil interfaces due to
+		// unpackValue calls.
+		if v.IsNil() {
+			d.w.Write(nilAngleBytes)
+		}
+
+	case reflect.Ptr:
+		// Do nothing.  We should never get here since pointers have already
+		// been handled above.
+
+	case reflect.Map:
+		// nil maps should be indicated as different than empty maps
+		if v.IsNil() {
+			d.w.Write(nilAngleBytes)
+			break
+		}
+
+		d.w.Write(openBraceNewlineBytes)
+		d.depth++
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
+			d.indent()
+			d.w.Write(maxNewlineBytes)
+		} else {
+			numEntries := v.Len()
+			keys := v.MapKeys()
+			if d.cs.SortKeys {
+				sortValues(keys, d.cs)
+			}
+			for i, key := range keys {
+				d.dump(d.unpackValue(key))
+				d.w.Write(colonSpaceBytes)
+				d.ignoreNextIndent = true
+				d.dump(d.unpackValue(v.MapIndex(key)))
+				if i < (numEntries - 1) {
+					d.w.Write(commaNewlineBytes)
+				} else {
+					d.w.Write(newlineBytes)
+				}
+			}
+		}
+		d.depth--
+		d.indent()
+		d.w.Write(closeBraceBytes)
+
+	case reflect.Struct:
+		d.w.Write(openBraceNewlineBytes)
+		d.depth++
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
+			d.indent()
+			d.w.Write(maxNewlineBytes)
+		} else {
+			vt := v.Type()
+			numFields := v.NumField()
+			for i := 0; i < numFields; i++ {
+				d.indent()
+				vtf := vt.Field(i)
+				d.w.Write([]byte(vtf.Name))
+				d.w.Write(colonSpaceBytes)
+				d.ignoreNextIndent = true
+				d.dump(d.unpackValue(v.Field(i)))
+				if i < (numFields - 1) {
+					d.w.Write(commaNewlineBytes)
+				} else {
+					d.w.Write(newlineBytes)
+				}
+			}
+		}
+		d.depth--
+		d.indent()
+		d.w.Write(closeBraceBytes)
+
+	case reflect.Uintptr:
+		printHexPtr(d.w, uintptr(v.Uint()))
+
+	case reflect.UnsafePointer, reflect.Chan, reflect.Func:
+		printHexPtr(d.w, v.Pointer())
+
+	// There were not any other types at the time this code was written, but
+	// fall back to letting the default fmt package handle it in case any new
+	// types are added.
+	default:
+		if v.CanInterface() {
+			fmt.Fprintf(d.w, "%v", v.Interface())
+		} else {
+			fmt.Fprintf(d.w, "%v", v.String())
+		}
+	}
+}
+
+// fdump is a helper function to consolidate the logic from the various public
+// methods which take varying writers and config states.
+func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
+	for _, arg := range a {
+		if arg == nil {
+			w.Write(interfaceBytes)
+			w.Write(spaceBytes)
+			w.Write(nilAngleBytes)
+			w.Write(newlineBytes)
+			continue
+		}
+
+		d := dumpState{w: w, cs: cs}
+		d.pointers = make(map[uintptr]int)
+		d.dump(reflect.ValueOf(arg))
+		d.w.Write(newlineBytes)
+	}
+}
+
+// Fdump formats and displays the passed arguments to io.Writer w.  It formats
+// exactly the same as Dump.
+func Fdump(w io.Writer, a ...interface{}) {
+	fdump(&Config, w, a...)
+}
+
+// Sdump returns a string with the passed arguments formatted exactly the same
+// as Dump.
+func Sdump(a ...interface{}) string {
+	var buf bytes.Buffer
+	fdump(&Config, &buf, a...)
+	return buf.String()
+}
+
+/*
+Dump displays the passed parameters to standard out with newlines, customizable
+indentation, and additional debug information such as complete types and all
+pointer addresses used to indirect to the final value.  It provides the
+following features over the built-in printing facilities provided by the fmt
+package:
+
+	* Pointers are dereferenced and followed
+	* Circular data structures are detected and handled properly
+	* Custom Stringer/error interfaces are optionally invoked, including
+	  on unexported types
+	* Custom types which only implement the Stringer/error interfaces via
+	  a pointer receiver are optionally invoked when passing non-pointer
+	  variables
+	* Byte arrays and slices are dumped like the hexdump -C command which
+	  includes offsets, byte values in hex, and ASCII output
+
+The configuration options are controlled by an exported package global,
+spew.Config.  See ConfigState for options documentation.
+
+See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
+get the formatted result as a string.
+*/
+func Dump(a ...interface{}) {
+	fdump(&Config, os.Stdout, a...)
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/format.go b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/format.go
new file mode 100644
index 0000000..ecf3b80
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/format.go
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+)
+
+// supportedFlags is a list of all the character flags supported by fmt package.
+const supportedFlags = "0-+# "
+
+// formatState implements the fmt.Formatter interface and contains information
+// about the state of a formatting operation.  The NewFormatter function can
+// be used to get a new Formatter which can be used directly as arguments
+// in standard fmt package printing calls.
+type formatState struct {
+	value          interface{}
+	fs             fmt.State
+	depth          int
+	pointers       map[uintptr]int
+	ignoreNextType bool
+	cs             *ConfigState
+}
+
+// buildDefaultFormat recreates the original format string without precision
+// and width information to pass in to fmt.Sprintf in the case of an
+// unrecognized type.  Unless new types are added to the language, this
+// function won't ever be called.
+func (f *formatState) buildDefaultFormat() (format string) {
+	buf := bytes.NewBuffer(percentBytes)
+
+	for _, flag := range supportedFlags {
+		if f.fs.Flag(int(flag)) {
+			buf.WriteRune(flag)
+		}
+	}
+
+	buf.WriteRune('v')
+
+	format = buf.String()
+	return format
+}
+
+// constructOrigFormat recreates the original format string including precision
+// and width information to pass along to the standard fmt package.  This allows
+// automatic deferral of all format strings this package doesn't support.
+func (f *formatState) constructOrigFormat(verb rune) (format string) {
+	buf := bytes.NewBuffer(percentBytes)
+
+	for _, flag := range supportedFlags {
+		if f.fs.Flag(int(flag)) {
+			buf.WriteRune(flag)
+		}
+	}
+
+	if width, ok := f.fs.Width(); ok {
+		buf.WriteString(strconv.Itoa(width))
+	}
+
+	if precision, ok := f.fs.Precision(); ok {
+		buf.Write(precisionBytes)
+		buf.WriteString(strconv.Itoa(precision))
+	}
+
+	buf.WriteRune(verb)
+
+	format = buf.String()
+	return format
+}
+
+// unpackValue returns values inside of non-nil interfaces when possible and
+// ensures that types for values which have been unpacked from an interface
+// are displayed when the show types flag is also set.
+// This is useful for data types like structs, arrays, slices, and maps which
+// can contain varying types packed inside an interface.
+func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
+	if v.Kind() == reflect.Interface {
+		f.ignoreNextType = false
+		if !v.IsNil() {
+			v = v.Elem()
+		}
+	}
+	return v
+}
+
+// formatPtr handles formatting of pointers by indirecting them as necessary.
+func (f *formatState) formatPtr(v reflect.Value) {
+	// Display nil if top level pointer is nil.
+	showTypes := f.fs.Flag('#')
+	if v.IsNil() && (!showTypes || f.ignoreNextType) {
+		f.fs.Write(nilAngleBytes)
+		return
+	}
+
+	// Remove pointers at or below the current depth from map used to detect
+	// circular refs.
+	for k, depth := range f.pointers {
+		if depth >= f.depth {
+			delete(f.pointers, k)
+		}
+	}
+
+	// Keep list of all dereferenced pointers to possibly show later.
+	pointerChain := make([]uintptr, 0)
+
+	// Figure out how many levels of indirection there are by derferencing
+	// pointers and unpacking interfaces down the chain while detecting circular
+	// references.
+	nilFound := false
+	cycleFound := false
+	indirects := 0
+	ve := v
+	for ve.Kind() == reflect.Ptr {
+		if ve.IsNil() {
+			nilFound = true
+			break
+		}
+		indirects++
+		addr := ve.Pointer()
+		pointerChain = append(pointerChain, addr)
+		if pd, ok := f.pointers[addr]; ok && pd < f.depth {
+			cycleFound = true
+			indirects--
+			break
+		}
+		f.pointers[addr] = f.depth
+
+		ve = ve.Elem()
+		if ve.Kind() == reflect.Interface {
+			if ve.IsNil() {
+				nilFound = true
+				break
+			}
+			ve = ve.Elem()
+		}
+	}
+
+	// Display type or indirection level depending on flags.
+	if showTypes && !f.ignoreNextType {
+		f.fs.Write(openParenBytes)
+		f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
+		f.fs.Write([]byte(ve.Type().String()))
+		f.fs.Write(closeParenBytes)
+	} else {
+		if nilFound || cycleFound {
+			indirects += strings.Count(ve.Type().String(), "*")
+		}
+		f.fs.Write(openAngleBytes)
+		f.fs.Write([]byte(strings.Repeat("*", indirects)))
+		f.fs.Write(closeAngleBytes)
+	}
+
+	// Display pointer information depending on flags.
+	if f.fs.Flag('+') && (len(pointerChain) > 0) {
+		f.fs.Write(openParenBytes)
+		for i, addr := range pointerChain {
+			if i > 0 {
+				f.fs.Write(pointerChainBytes)
+			}
+			printHexPtr(f.fs, addr)
+		}
+		f.fs.Write(closeParenBytes)
+	}
+
+	// Display dereferenced value.
+	switch {
+	case nilFound == true:
+		f.fs.Write(nilAngleBytes)
+
+	case cycleFound == true:
+		f.fs.Write(circularShortBytes)
+
+	default:
+		f.ignoreNextType = true
+		f.format(ve)
+	}
+}
+
+// format is the main workhorse for providing the Formatter interface.  It
+// uses the passed reflect value to figure out what kind of object we are
+// dealing with and formats it appropriately.  It is a recursive function,
+// however circular data structures are detected and handled properly.
+func (f *formatState) format(v reflect.Value) {
+	// Handle invalid reflect values immediately.
+	kind := v.Kind()
+	if kind == reflect.Invalid {
+		f.fs.Write(invalidAngleBytes)
+		return
+	}
+
+	// Handle pointers specially.
+	if kind == reflect.Ptr {
+		f.formatPtr(v)
+		return
+	}
+
+	// Print type information unless already handled elsewhere.
+	if !f.ignoreNextType && f.fs.Flag('#') {
+		f.fs.Write(openParenBytes)
+		f.fs.Write([]byte(v.Type().String()))
+		f.fs.Write(closeParenBytes)
+	}
+	f.ignoreNextType = false
+
+	// Call Stringer/error interfaces if they exist and the handle methods
+	// flag is enabled.
+	if !f.cs.DisableMethods {
+		if (kind != reflect.Invalid) && (kind != reflect.Interface) {
+			if handled := handleMethods(f.cs, f.fs, v); handled {
+				return
+			}
+		}
+	}
+
+	switch kind {
+	case reflect.Invalid:
+		// Do nothing.  We should never get here since invalid has already
+		// been handled above.
+
+	case reflect.Bool:
+		printBool(f.fs, v.Bool())
+
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+		printInt(f.fs, v.Int(), 10)
+
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+		printUint(f.fs, v.Uint(), 10)
+
+	case reflect.Float32:
+		printFloat(f.fs, v.Float(), 32)
+
+	case reflect.Float64:
+		printFloat(f.fs, v.Float(), 64)
+
+	case reflect.Complex64:
+		printComplex(f.fs, v.Complex(), 32)
+
+	case reflect.Complex128:
+		printComplex(f.fs, v.Complex(), 64)
+
+	case reflect.Slice:
+		if v.IsNil() {
+			f.fs.Write(nilAngleBytes)
+			break
+		}
+		fallthrough
+
+	case reflect.Array:
+		f.fs.Write(openBracketBytes)
+		f.depth++
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
+			f.fs.Write(maxShortBytes)
+		} else {
+			numEntries := v.Len()
+			for i := 0; i < numEntries; i++ {
+				if i > 0 {
+					f.fs.Write(spaceBytes)
+				}
+				f.ignoreNextType = true
+				f.format(f.unpackValue(v.Index(i)))
+			}
+		}
+		f.depth--
+		f.fs.Write(closeBracketBytes)
+
+	case reflect.String:
+		f.fs.Write([]byte(v.String()))
+
+	case reflect.Interface:
+		// The only time we should get here is for nil interfaces due to
+		// unpackValue calls.
+		if v.IsNil() {
+			f.fs.Write(nilAngleBytes)
+		}
+
+	case reflect.Ptr:
+		// Do nothing.  We should never get here since pointers have already
+		// been handled above.
+
+	case reflect.Map:
+		// nil maps should be indicated as different than empty maps
+		if v.IsNil() {
+			f.fs.Write(nilAngleBytes)
+			break
+		}
+
+		f.fs.Write(openMapBytes)
+		f.depth++
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
+			f.fs.Write(maxShortBytes)
+		} else {
+			keys := v.MapKeys()
+			if f.cs.SortKeys {
+				sortValues(keys, f.cs)
+			}
+			for i, key := range keys {
+				if i > 0 {
+					f.fs.Write(spaceBytes)
+				}
+				f.ignoreNextType = true
+				f.format(f.unpackValue(key))
+				f.fs.Write(colonBytes)
+				f.ignoreNextType = true
+				f.format(f.unpackValue(v.MapIndex(key)))
+			}
+		}
+		f.depth--
+		f.fs.Write(closeMapBytes)
+
+	case reflect.Struct:
+		numFields := v.NumField()
+		f.fs.Write(openBraceBytes)
+		f.depth++
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
+			f.fs.Write(maxShortBytes)
+		} else {
+			vt := v.Type()
+			for i := 0; i < numFields; i++ {
+				if i > 0 {
+					f.fs.Write(spaceBytes)
+				}
+				vtf := vt.Field(i)
+				if f.fs.Flag('+') || f.fs.Flag('#') {
+					f.fs.Write([]byte(vtf.Name))
+					f.fs.Write(colonBytes)
+				}
+				f.format(f.unpackValue(v.Field(i)))
+			}
+		}
+		f.depth--
+		f.fs.Write(closeBraceBytes)
+
+	case reflect.Uintptr:
+		printHexPtr(f.fs, uintptr(v.Uint()))
+
+	case reflect.UnsafePointer, reflect.Chan, reflect.Func:
+		printHexPtr(f.fs, v.Pointer())
+
+	// There were not any other types at the time this code was written, but
+	// fall back to letting the default fmt package handle it if any get added.
+	default:
+		format := f.buildDefaultFormat()
+		if v.CanInterface() {
+			fmt.Fprintf(f.fs, format, v.Interface())
+		} else {
+			fmt.Fprintf(f.fs, format, v.String())
+		}
+	}
+}
+
+// Format satisfies the fmt.Formatter interface. See NewFormatter for usage
+// details.
+func (f *formatState) Format(fs fmt.State, verb rune) {
+	f.fs = fs
+
+	// Use standard formatting for verbs that are not v.
+	if verb != 'v' {
+		format := f.constructOrigFormat(verb)
+		fmt.Fprintf(fs, format, f.value)
+		return
+	}
+
+	if f.value == nil {
+		if fs.Flag('#') {
+			fs.Write(interfaceBytes)
+		}
+		fs.Write(nilAngleBytes)
+		return
+	}
+
+	f.format(reflect.ValueOf(f.value))
+}
+
+// newFormatter is a helper function to consolidate the logic from the various
+// public methods which take varying config states.
+func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
+	fs := &formatState{value: v, cs: cs}
+	fs.pointers = make(map[uintptr]int)
+	return fs
+}
+
+/*
+NewFormatter returns a custom formatter that satisfies the fmt.Formatter
+interface.  As a result, it integrates cleanly with standard fmt package
+printing functions.  The formatter is useful for inline printing of smaller data
+types similar to the standard %v format specifier.
+
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
+addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
+combinations.  Any other verbs such as %x and %q will be sent to the the
+standard fmt package for formatting.  In addition, the custom formatter ignores
+the width and precision arguments (however they will still work on the format
+specifiers not handled by the custom formatter).
+
+Typically this function shouldn't be called directly.  It is much easier to make
+use of the custom formatter by calling one of the convenience functions such as
+Printf, Println, or Fprintf.
+*/
+func NewFormatter(v interface{}) fmt.Formatter {
+	return newFormatter(&Config, v)
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/spew.go b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/spew.go
new file mode 100644
index 0000000..d8233f5
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/spew.go
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+	"fmt"
+	"io"
+)
+
+// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the formatted string as a value that satisfies error.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Errorf(format string, a ...interface{}) (err error) {
+	return fmt.Errorf(format, convertArgs(a)...)
+}
+
+// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
+func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
+	return fmt.Fprint(w, convertArgs(a)...)
+}
+
+// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
+	return fmt.Fprintf(w, format, convertArgs(a)...)
+}
+
+// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
+// passed with a default Formatter interface returned by NewFormatter.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
+func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
+	return fmt.Fprintln(w, convertArgs(a)...)
+}
+
+// Print is a wrapper for fmt.Print that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
+func Print(a ...interface{}) (n int, err error) {
+	return fmt.Print(convertArgs(a)...)
+}
+
+// Printf is a wrapper for fmt.Printf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Printf(format string, a ...interface{}) (n int, err error) {
+	return fmt.Printf(format, convertArgs(a)...)
+}
+
+// Println is a wrapper for fmt.Println that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the number of bytes written and any write error encountered.  See
+// NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
+func Println(a ...interface{}) (n int, err error) {
+	return fmt.Println(convertArgs(a)...)
+}
+
+// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))
+func Sprint(a ...interface{}) string {
+	return fmt.Sprint(convertArgs(a)...)
+}
+
+// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
+// passed with a default Formatter interface returned by NewFormatter.  It
+// returns the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))
+func Sprintf(format string, a ...interface{}) string {
+	return fmt.Sprintf(format, convertArgs(a)...)
+}
+
+// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
+// were passed with a default Formatter interface returned by NewFormatter.  It
+// returns the resulting string.  See NewFormatter for formatting details.
+//
+// This function is shorthand for the following syntax:
+//
+//	fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))
+func Sprintln(a ...interface{}) string {
+	return fmt.Sprintln(convertArgs(a)...)
+}
+
+// convertArgs accepts a slice of arguments and returns a slice of the same
+// length with each argument converted to a default spew Formatter interface.
+func convertArgs(args []interface{}) (formatters []interface{}) {
+	formatters = make([]interface{}, len(args))
+	for index, arg := range args {
+		formatters[index] = NewFormatter(arg)
+	}
+	return formatters
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/LICENSE b/go/src/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/LICENSE
new file mode 100644
index 0000000..c67dad6
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013, Patrick Mezard
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+    The names of its contributors may not be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib/difflib.go b/go/src/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib/difflib.go
new file mode 100644
index 0000000..64cc40f
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib/difflib.go
@@ -0,0 +1,758 @@
+// Package difflib is a partial port of Python difflib module.
+//
+// It provides tools to compare sequences of strings and generate textual diffs.
+//
+// The following class and functions have been ported:
+//
+// - SequenceMatcher
+//
+// - unified_diff
+//
+// - context_diff
+//
+// Getting unified diffs was the main goal of the port. Keep in mind this code
+// is mostly suitable to output text differences in a human friendly way, there
+// are no guarantees generated diffs are consumable by patch(1).
+package difflib
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"strings"
+)
+
+func min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}
+
+func max(a, b int) int {
+	if a > b {
+		return a
+	}
+	return b
+}
+
+func calculateRatio(matches, length int) float64 {
+	if length > 0 {
+		return 2.0 * float64(matches) / float64(length)
+	}
+	return 1.0
+}
+
+type Match struct {
+	A    int
+	B    int
+	Size int
+}
+
+type OpCode struct {
+	Tag byte
+	I1  int
+	I2  int
+	J1  int
+	J2  int
+}
+
+// SequenceMatcher compares sequence of strings. The basic
+// algorithm predates, and is a little fancier than, an algorithm
+// published in the late 1980's by Ratcliff and Obershelp under the
+// hyperbolic name "gestalt pattern matching".  The basic idea is to find
+// the longest contiguous matching subsequence that contains no "junk"
+// elements (R-O doesn't address junk).  The same idea is then applied
+// recursively to the pieces of the sequences to the left and to the right
+// of the matching subsequence.  This does not yield minimal edit
+// sequences, but does tend to yield matches that "look right" to people.
+//
+// SequenceMatcher tries to compute a "human-friendly diff" between two
+// sequences.  Unlike e.g. UNIX(tm) diff, the fundamental notion is the
+// longest *contiguous* & junk-free matching subsequence.  That's what
+// catches peoples' eyes.  The Windows(tm) windiff has another interesting
+// notion, pairing up elements that appear uniquely in each sequence.
+// That, and the method here, appear to yield more intuitive difference
+// reports than does diff.  This method appears to be the least vulnerable
+// to synching up on blocks of "junk lines", though (like blank lines in
+// ordinary text files, or maybe "<P>" lines in HTML files).  That may be
+// because this is the only method of the 3 that has a *concept* of
+// "junk" <wink>.
+//
+// Timing:  Basic R-O is cubic time worst case and quadratic time expected
+// case.  SequenceMatcher is quadratic time for the worst case and has
+// expected-case behavior dependent in a complicated way on how many
+// elements the sequences have in common; best case time is linear.
+type SequenceMatcher struct {
+	a              []string
+	b              []string
+	b2j            map[string][]int
+	IsJunk         func(string) bool
+	autoJunk       bool
+	bJunk          map[string]struct{}
+	matchingBlocks []Match
+	fullBCount     map[string]int
+	bPopular       map[string]struct{}
+	opCodes        []OpCode
+}
+
+func NewMatcher(a, b []string) *SequenceMatcher {
+	m := SequenceMatcher{autoJunk: true}
+	m.SetSeqs(a, b)
+	return &m
+}
+
+func NewMatcherWithJunk(a, b []string, autoJunk bool,
+	isJunk func(string) bool) *SequenceMatcher {
+
+	m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk}
+	m.SetSeqs(a, b)
+	return &m
+}
+
+// Set two sequences to be compared.
+func (m *SequenceMatcher) SetSeqs(a, b []string) {
+	m.SetSeq1(a)
+	m.SetSeq2(b)
+}
+
+// Set the first sequence to be compared. The second sequence to be compared is
+// not changed.
+//
+// SequenceMatcher computes and caches detailed information about the second
+// sequence, so if you want to compare one sequence S against many sequences,
+// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other
+// sequences.
+//
+// See also SetSeqs() and SetSeq2().
+func (m *SequenceMatcher) SetSeq1(a []string) {
+	if &a == &m.a {
+		return
+	}
+	m.a = a
+	m.matchingBlocks = nil
+	m.opCodes = nil
+}
+
+// Set the second sequence to be compared. The first sequence to be compared is
+// not changed.
+func (m *SequenceMatcher) SetSeq2(b []string) {
+	if &b == &m.b {
+		return
+	}
+	m.b = b
+	m.matchingBlocks = nil
+	m.opCodes = nil
+	m.fullBCount = nil
+	m.chainB()
+}
+
+func (m *SequenceMatcher) chainB() {
+	// Populate line -> index mapping
+	b2j := map[string][]int{}
+	for i, s := range m.b {
+		indices := b2j[s]
+		indices = append(indices, i)
+		b2j[s] = indices
+	}
+
+	// Purge junk elements
+	m.bJunk = map[string]struct{}{}
+	if m.IsJunk != nil {
+		junk := m.bJunk
+		for s, _ := range b2j {
+			if m.IsJunk(s) {
+				junk[s] = struct{}{}
+			}
+		}
+		for s, _ := range junk {
+			delete(b2j, s)
+		}
+	}
+
+	// Purge remaining popular elements
+	popular := map[string]struct{}{}
+	n := len(m.b)
+	if m.autoJunk && n >= 200 {
+		ntest := n/100 + 1
+		for s, indices := range b2j {
+			if len(indices) > ntest {
+				popular[s] = struct{}{}
+			}
+		}
+		for s, _ := range popular {
+			delete(b2j, s)
+		}
+	}
+	m.bPopular = popular
+	m.b2j = b2j
+}
+
+func (m *SequenceMatcher) isBJunk(s string) bool {
+	_, ok := m.bJunk[s]
+	return ok
+}
+
+// Find longest matching block in a[alo:ahi] and b[blo:bhi].
+//
+// If IsJunk is not defined:
+//
+// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
+//     alo <= i <= i+k <= ahi
+//     blo <= j <= j+k <= bhi
+// and for all (i',j',k') meeting those conditions,
+//     k >= k'
+//     i <= i'
+//     and if i == i', j <= j'
+//
+// In other words, of all maximal matching blocks, return one that
+// starts earliest in a, and of all those maximal matching blocks that
+// start earliest in a, return the one that starts earliest in b.
+//
+// If IsJunk is defined, first the longest matching block is
+// determined as above, but with the additional restriction that no
+// junk element appears in the block.  Then that block is extended as
+// far as possible by matching (only) junk elements on both sides.  So
+// the resulting block never matches on junk except as identical junk
+// happens to be adjacent to an "interesting" match.
+//
+// If no blocks match, return (alo, blo, 0).
+func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {
+	// CAUTION:  stripping common prefix or suffix would be incorrect.
+	// E.g.,
+	//    ab
+	//    acab
+	// Longest matching block is "ab", but if common prefix is
+	// stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
+	// strip, so ends up claiming that ab is changed to acab by
+	// inserting "ca" in the middle.  That's minimal but unintuitive:
+	// "it's obvious" that someone inserted "ac" at the front.
+	// Windiff ends up at the same place as diff, but by pairing up
+	// the unique 'b's and then matching the first two 'a's.
+	besti, bestj, bestsize := alo, blo, 0
+
+	// find longest junk-free match
+	// during an iteration of the loop, j2len[j] = length of longest
+	// junk-free match ending with a[i-1] and b[j]
+	j2len := map[int]int{}
+	for i := alo; i != ahi; i++ {
+		// look at all instances of a[i] in b; note that because
+		// b2j has no junk keys, the loop is skipped if a[i] is junk
+		newj2len := map[int]int{}
+		for _, j := range m.b2j[m.a[i]] {
+			// a[i] matches b[j]
+			if j < blo {
+				continue
+			}
+			if j >= bhi {
+				break
+			}
+			k := j2len[j-1] + 1
+			newj2len[j] = k
+			if k > bestsize {
+				besti, bestj, bestsize = i-k+1, j-k+1, k
+			}
+		}
+		j2len = newj2len
+	}
+
+	// Extend the best by non-junk elements on each end.  In particular,
+	// "popular" non-junk elements aren't in b2j, which greatly speeds
+	// the inner loop above, but also means "the best" match so far
+	// doesn't contain any junk *or* popular non-junk elements.
+	for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) &&
+		m.a[besti-1] == m.b[bestj-1] {
+		besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
+	}
+	for besti+bestsize < ahi && bestj+bestsize < bhi &&
+		!m.isBJunk(m.b[bestj+bestsize]) &&
+		m.a[besti+bestsize] == m.b[bestj+bestsize] {
+		bestsize += 1
+	}
+
+	// Now that we have a wholly interesting match (albeit possibly
+	// empty!), we may as well suck up the matching junk on each
+	// side of it too.  Can't think of a good reason not to, and it
+	// saves post-processing the (possibly considerable) expense of
+	// figuring out what to do with it.  In the case of an empty
+	// interesting match, this is clearly the right thing to do,
+	// because no other kind of match is possible in the regions.
+	for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) &&
+		m.a[besti-1] == m.b[bestj-1] {
+		besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
+	}
+	for besti+bestsize < ahi && bestj+bestsize < bhi &&
+		m.isBJunk(m.b[bestj+bestsize]) &&
+		m.a[besti+bestsize] == m.b[bestj+bestsize] {
+		bestsize += 1
+	}
+
+	return Match{A: besti, B: bestj, Size: bestsize}
+}
+
+// Return list of triples describing matching subsequences.
+//
+// Each triple is of the form (i, j, n), and means that
+// a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in
+// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are
+// adjacent triples in the list, and the second is not the last triple in the
+// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe
+// adjacent equal blocks.
+//
+// The last triple is a dummy, (len(a), len(b), 0), and is the only
+// triple with n==0.
+func (m *SequenceMatcher) GetMatchingBlocks() []Match {
+	if m.matchingBlocks != nil {
+		return m.matchingBlocks
+	}
+
+	var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match
+	matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match {
+		match := m.findLongestMatch(alo, ahi, blo, bhi)
+		i, j, k := match.A, match.B, match.Size
+		if match.Size > 0 {
+			if alo < i && blo < j {
+				matched = matchBlocks(alo, i, blo, j, matched)
+			}
+			matched = append(matched, match)
+			if i+k < ahi && j+k < bhi {
+				matched = matchBlocks(i+k, ahi, j+k, bhi, matched)
+			}
+		}
+		return matched
+	}
+	matched := matchBlocks(0, len(m.a), 0, len(m.b), nil)
+
+	// It's possible that we have adjacent equal blocks in the
+	// matching_blocks list now.
+	nonAdjacent := []Match{}
+	i1, j1, k1 := 0, 0, 0
+	for _, b := range matched {
+		// Is this block adjacent to i1, j1, k1?
+		i2, j2, k2 := b.A, b.B, b.Size
+		if i1+k1 == i2 && j1+k1 == j2 {
+			// Yes, so collapse them -- this just increases the length of
+			// the first block by the length of the second, and the first
+			// block so lengthened remains the block to compare against.
+			k1 += k2
+		} else {
+			// Not adjacent.  Remember the first block (k1==0 means it's
+			// the dummy we started with), and make the second block the
+			// new block to compare against.
+			if k1 > 0 {
+				nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
+			}
+			i1, j1, k1 = i2, j2, k2
+		}
+	}
+	if k1 > 0 {
+		nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
+	}
+
+	nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0})
+	m.matchingBlocks = nonAdjacent
+	return m.matchingBlocks
+}
+
+// Return list of 5-tuples describing how to turn a into b.
+//
+// Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple
+// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the
+// tuple preceding it, and likewise for j1 == the previous j2.
+//
+// The tags are characters, with these meanings:
+//
+// 'r' (replace):  a[i1:i2] should be replaced by b[j1:j2]
+//
+// 'd' (delete):   a[i1:i2] should be deleted, j1==j2 in this case.
+//
+// 'i' (insert):   b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case.
+//
+// 'e' (equal):    a[i1:i2] == b[j1:j2]
+func (m *SequenceMatcher) GetOpCodes() []OpCode {
+	if m.opCodes != nil {
+		return m.opCodes
+	}
+	i, j := 0, 0
+	matching := m.GetMatchingBlocks()
+	opCodes := make([]OpCode, 0, len(matching))
+	for _, m := range matching {
+		//  invariant:  we've pumped out correct diffs to change
+		//  a[:i] into b[:j], and the next matching block is
+		//  a[ai:ai+size] == b[bj:bj+size]. So we need to pump
+		//  out a diff to change a[i:ai] into b[j:bj], pump out
+		//  the matching block, and move (i,j) beyond the match
+		ai, bj, size := m.A, m.B, m.Size
+		tag := byte(0)
+		if i < ai && j < bj {
+			tag = 'r'
+		} else if i < ai {
+			tag = 'd'
+		} else if j < bj {
+			tag = 'i'
+		}
+		if tag > 0 {
+			opCodes = append(opCodes, OpCode{tag, i, ai, j, bj})
+		}
+		i, j = ai+size, bj+size
+		// the list of matching blocks is terminated by a
+		// sentinel with size 0
+		if size > 0 {
+			opCodes = append(opCodes, OpCode{'e', ai, i, bj, j})
+		}
+	}
+	m.opCodes = opCodes
+	return m.opCodes
+}
+
+// Isolate change clusters by eliminating ranges with no changes.
+//
+// Return a generator of groups with up to n lines of context.
+// Each group is in the same format as returned by GetOpCodes().
+func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
+	if n < 0 {
+		n = 3
+	}
+	codes := m.GetOpCodes()
+	if len(codes) == 0 {
+		codes = []OpCode{OpCode{'e', 0, 1, 0, 1}}
+	}
+	// Fixup leading and trailing groups if they show no changes.
+	if codes[0].Tag == 'e' {
+		c := codes[0]
+		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+		codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2}
+	}
+	if codes[len(codes)-1].Tag == 'e' {
+		c := codes[len(codes)-1]
+		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+		codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)}
+	}
+	nn := n + n
+	groups := [][]OpCode{}
+	group := []OpCode{}
+	for _, c := range codes {
+		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+		// End the current group and start a new one whenever
+		// there is a large range with no changes.
+		if c.Tag == 'e' && i2-i1 > nn {
+			group = append(group, OpCode{c.Tag, i1, min(i2, i1+n),
+				j1, min(j2, j1+n)})
+			groups = append(groups, group)
+			group = []OpCode{}
+			i1, j1 = max(i1, i2-n), max(j1, j2-n)
+		}
+		group = append(group, OpCode{c.Tag, i1, i2, j1, j2})
+	}
+	if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') {
+		groups = append(groups, group)
+	}
+	return groups
+}
+
+// Return a measure of the sequences' similarity (float in [0,1]).
+//
+// Where T is the total number of elements in both sequences, and
+// M is the number of matches, this is 2.0*M / T.
+// Note that this is 1 if the sequences are identical, and 0 if
+// they have nothing in common.
+//
+// .Ratio() is expensive to compute if you haven't already computed
+// .GetMatchingBlocks() or .GetOpCodes(), in which case you may
+// want to try .QuickRatio() or .RealQuickRation() first to get an
+// upper bound.
+func (m *SequenceMatcher) Ratio() float64 {
+	matches := 0
+	for _, m := range m.GetMatchingBlocks() {
+		matches += m.Size
+	}
+	return calculateRatio(matches, len(m.a)+len(m.b))
+}
+
+// Return an upper bound on ratio() relatively quickly.
+//
+// This isn't defined beyond that it is an upper bound on .Ratio(), and
+// is faster to compute.
+func (m *SequenceMatcher) QuickRatio() float64 {
+	// viewing a and b as multisets, set matches to the cardinality
+	// of their intersection; this counts the number of matches
+	// without regard to order, so is clearly an upper bound
+	if m.fullBCount == nil {
+		m.fullBCount = map[string]int{}
+		for _, s := range m.b {
+			m.fullBCount[s] = m.fullBCount[s] + 1
+		}
+	}
+
+	// avail[x] is the number of times x appears in 'b' less the
+	// number of times we've seen it in 'a' so far ... kinda
+	avail := map[string]int{}
+	matches := 0
+	for _, s := range m.a {
+		n, ok := avail[s]
+		if !ok {
+			n = m.fullBCount[s]
+		}
+		avail[s] = n - 1
+		if n > 0 {
+			matches += 1
+		}
+	}
+	return calculateRatio(matches, len(m.a)+len(m.b))
+}
+
+// Return an upper bound on ratio() very quickly.
+//
+// This isn't defined beyond that it is an upper bound on .Ratio(), and
+// is faster to compute than either .Ratio() or .QuickRatio().
+func (m *SequenceMatcher) RealQuickRatio() float64 {
+	la, lb := len(m.a), len(m.b)
+	return calculateRatio(min(la, lb), la+lb)
+}
+
+// Convert range to the "ed" format
+func formatRangeUnified(start, stop int) string {
+	// Per the diff spec at http://www.unix.org/single_unix_specification/
+	beginning := start + 1 // lines start numbering with one
+	length := stop - start
+	if length == 1 {
+		return fmt.Sprintf("%d", beginning)
+	}
+	if length == 0 {
+		beginning -= 1 // empty ranges begin at line just before the range
+	}
+	return fmt.Sprintf("%d,%d", beginning, length)
+}
+
+// Unified diff parameters
+type UnifiedDiff struct {
+	A        []string // First sequence lines
+	FromFile string   // First file name
+	FromDate string   // First file time
+	B        []string // Second sequence lines
+	ToFile   string   // Second file name
+	ToDate   string   // Second file time
+	Eol      string   // Headers end of line, defaults to LF
+	Context  int      // Number of context lines
+}
+
+// Compare two sequences of lines; generate the delta as a unified diff.
+//
+// Unified diffs are a compact way of showing line changes and a few
+// lines of context.  The number of context lines is set by 'n' which
+// defaults to three.
+//
+// By default, the diff control lines (those with ---, +++, or @@) are
+// created with a trailing newline.  This is helpful so that inputs
+// created from file.readlines() result in diffs that are suitable for
+// file.writelines() since both the inputs and outputs have trailing
+// newlines.
+//
+// For inputs that do not have trailing newlines, set the lineterm
+// argument to "" so that the output will be uniformly newline free.
+//
+// The unidiff format normally has a header for filenames and modification
+// times.  Any or all of these may be specified using strings for
+// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
+// The modification times are normally expressed in the ISO 8601 format.
+func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error {
+	buf := bufio.NewWriter(writer)
+	defer buf.Flush()
+	w := func(format string, args ...interface{}) error {
+		_, err := buf.WriteString(fmt.Sprintf(format, args...))
+		return err
+	}
+
+	if len(diff.Eol) == 0 {
+		diff.Eol = "\n"
+	}
+
+	started := false
+	m := NewMatcher(diff.A, diff.B)
+	for _, g := range m.GetGroupedOpCodes(diff.Context) {
+		if !started {
+			started = true
+			fromDate := ""
+			if len(diff.FromDate) > 0 {
+				fromDate = "\t" + diff.FromDate
+			}
+			toDate := ""
+			if len(diff.ToDate) > 0 {
+				toDate = "\t" + diff.ToDate
+			}
+			err := w("--- %s%s%s", diff.FromFile, fromDate, diff.Eol)
+			if err != nil {
+				return err
+			}
+			err = w("+++ %s%s%s", diff.ToFile, toDate, diff.Eol)
+			if err != nil {
+				return err
+			}
+		}
+		first, last := g[0], g[len(g)-1]
+		range1 := formatRangeUnified(first.I1, last.I2)
+		range2 := formatRangeUnified(first.J1, last.J2)
+		if err := w("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil {
+			return err
+		}
+		for _, c := range g {
+			i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+			if c.Tag == 'e' {
+				for _, line := range diff.A[i1:i2] {
+					if err := w(" " + line); err != nil {
+						return err
+					}
+				}
+				continue
+			}
+			if c.Tag == 'r' || c.Tag == 'd' {
+				for _, line := range diff.A[i1:i2] {
+					if err := w("-" + line); err != nil {
+						return err
+					}
+				}
+			}
+			if c.Tag == 'r' || c.Tag == 'i' {
+				for _, line := range diff.B[j1:j2] {
+					if err := w("+" + line); err != nil {
+						return err
+					}
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// Like WriteUnifiedDiff but returns the diff a string.
+func GetUnifiedDiffString(diff UnifiedDiff) (string, error) {
+	w := &bytes.Buffer{}
+	err := WriteUnifiedDiff(w, diff)
+	return string(w.Bytes()), err
+}
+
+// Convert range to the "ed" format.
+func formatRangeContext(start, stop int) string {
+	// Per the diff spec at http://www.unix.org/single_unix_specification/
+	beginning := start + 1 // lines start numbering with one
+	length := stop - start
+	if length == 0 {
+		beginning -= 1 // empty ranges begin at line just before the range
+	}
+	if length <= 1 {
+		return fmt.Sprintf("%d", beginning)
+	}
+	return fmt.Sprintf("%d,%d", beginning, beginning+length-1)
+}
+
+type ContextDiff UnifiedDiff
+
+// Compare two sequences of lines; generate the delta as a context diff.
+//
+// Context diffs are a compact way of showing line changes and a few
+// lines of context. The number of context lines is set by diff.Context
+// which defaults to three.
+//
+// By default, the diff control lines (those with *** or ---) are
+// created with a trailing newline.
+//
+// For inputs that do not have trailing newlines, set the diff.Eol
+// argument to "" so that the output will be uniformly newline free.
+//
+// The context diff format normally has a header for filenames and
+// modification times.  Any or all of these may be specified using
+// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate.
+// The modification times are normally expressed in the ISO 8601 format.
+// If not specified, the strings default to blanks.
+func WriteContextDiff(writer io.Writer, diff ContextDiff) error {
+	buf := bufio.NewWriter(writer)
+	defer buf.Flush()
+	var diffErr error
+	w := func(format string, args ...interface{}) {
+		_, err := buf.WriteString(fmt.Sprintf(format, args...))
+		if diffErr == nil && err != nil {
+			diffErr = err
+		}
+	}
+
+	if len(diff.Eol) == 0 {
+		diff.Eol = "\n"
+	}
+
+	prefix := map[byte]string{
+		'i': "+ ",
+		'd': "- ",
+		'r': "! ",
+		'e': "  ",
+	}
+
+	started := false
+	m := NewMatcher(diff.A, diff.B)
+	for _, g := range m.GetGroupedOpCodes(diff.Context) {
+		if !started {
+			started = true
+			fromDate := ""
+			if len(diff.FromDate) > 0 {
+				fromDate = "\t" + diff.FromDate
+			}
+			toDate := ""
+			if len(diff.ToDate) > 0 {
+				toDate = "\t" + diff.ToDate
+			}
+			w("*** %s%s%s", diff.FromFile, fromDate, diff.Eol)
+			w("--- %s%s%s", diff.ToFile, toDate, diff.Eol)
+		}
+
+		first, last := g[0], g[len(g)-1]
+		w("***************" + diff.Eol)
+
+		range1 := formatRangeContext(first.I1, last.I2)
+		w("*** %s ****%s", range1, diff.Eol)
+		for _, c := range g {
+			if c.Tag == 'r' || c.Tag == 'd' {
+				for _, cc := range g {
+					if cc.Tag == 'i' {
+						continue
+					}
+					for _, line := range diff.A[cc.I1:cc.I2] {
+						w(prefix[cc.Tag] + line)
+					}
+				}
+				break
+			}
+		}
+
+		range2 := formatRangeContext(first.J1, last.J2)
+		w("--- %s ----%s", range2, diff.Eol)
+		for _, c := range g {
+			if c.Tag == 'r' || c.Tag == 'i' {
+				for _, cc := range g {
+					if cc.Tag == 'd' {
+						continue
+					}
+					for _, line := range diff.B[cc.J1:cc.J2] {
+						w(prefix[cc.Tag] + line)
+					}
+				}
+				break
+			}
+		}
+	}
+	return diffErr
+}
+
+// Like WriteContextDiff but returns the diff a string.
+func GetContextDiffString(diff ContextDiff) (string, error) {
+	w := &bytes.Buffer{}
+	err := WriteContextDiff(w, diff)
+	return string(w.Bytes()), err
+}
+
+// Split a string on "\n" while preserving them. The output can be used
+// as input for UnifiedDiff and ContextDiff structures.
+func SplitLines(s string) []string {
+	lines := strings.SplitAfter(s, "\n")
+	lines[len(lines)-1] += "\n"
+	return lines
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/.gitignore b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/.gitignore
new file mode 100644
index 0000000..0026861
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/.gitignore
@@ -0,0 +1,22 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/LICENSE.md b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/LICENSE.md
new file mode 100644
index 0000000..2199945
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/LICENSE.md
@@ -0,0 +1,23 @@
+objx - by Mat Ryer and Tyler Bunnell
+
+The MIT License (MIT)
+
+Copyright (c) 2014 Stretchr, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/README.md b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/README.md
new file mode 100644
index 0000000..4aa1806
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/README.md
@@ -0,0 +1,3 @@
+# objx
+
+  * Jump into the [API Documentation](http://godoc.org/github.com/stretchr/objx)
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/accessors.go b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/accessors.go
new file mode 100644
index 0000000..721bcac
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/accessors.go
@@ -0,0 +1,179 @@
+package objx
+
+import (
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+// arrayAccesRegexString is the regex used to extract the array number
+// from the access path
+const arrayAccesRegexString = `^(.+)\[([0-9]+)\]$`
+
+// arrayAccesRegex is the compiled arrayAccesRegexString
+var arrayAccesRegex = regexp.MustCompile(arrayAccesRegexString)
+
+// Get gets the value using the specified selector and
+// returns it inside a new Obj object.
+//
+// If it cannot find the value, Get will return a nil
+// value inside an instance of Obj.
+//
+// Get can only operate directly on map[string]interface{} and []interface.
+//
+// Example
+//
+// To access the title of the third chapter of the second book, do:
+//
+//    o.Get("books[1].chapters[2].title")
+func (m Map) Get(selector string) *Value {
+	rawObj := access(m, selector, nil, false, false)
+	return &Value{data: rawObj}
+}
+
+// Set sets the value using the specified selector and
+// returns the object on which Set was called.
+//
+// Set can only operate directly on map[string]interface{} and []interface
+//
+// Example
+//
+// To set the title of the third chapter of the second book, do:
+//
+//    o.Set("books[1].chapters[2].title","Time to Go")
+func (m Map) Set(selector string, value interface{}) Map {
+	access(m, selector, value, true, false)
+	return m
+}
+
+// access accesses the object using the selector and performs the
+// appropriate action.
+func access(current, selector, value interface{}, isSet, panics bool) interface{} {
+
+	switch selector.(type) {
+	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
+
+		if array, ok := current.([]interface{}); ok {
+			index := intFromInterface(selector)
+
+			if index >= len(array) {
+				if panics {
+					panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array)))
+				}
+				return nil
+			}
+
+			return array[index]
+		}
+
+		return nil
+
+	case string:
+
+		selStr := selector.(string)
+		selSegs := strings.SplitN(selStr, PathSeparator, 2)
+		thisSel := selSegs[0]
+		index := -1
+		var err error
+
+		// https://github.com/stretchr/objx/issues/12
+		if strings.Contains(thisSel, "[") {
+
+			arrayMatches := arrayAccesRegex.FindStringSubmatch(thisSel)
+
+			if len(arrayMatches) > 0 {
+
+				// Get the key into the map
+				thisSel = arrayMatches[1]
+
+				// Get the index into the array at the key
+				index, err = strconv.Atoi(arrayMatches[2])
+
+				if err != nil {
+					// This should never happen. If it does, something has gone
+					// seriously wrong. Panic.
+					panic("objx: Array index is not an integer.  Must use array[int].")
+				}
+
+			}
+		}
+
+		if curMap, ok := current.(Map); ok {
+			current = map[string]interface{}(curMap)
+		}
+
+		// get the object in question
+		switch current.(type) {
+		case map[string]interface{}:
+			curMSI := current.(map[string]interface{})
+			if len(selSegs) <= 1 && isSet {
+				curMSI[thisSel] = value
+				return nil
+			} else {
+				current = curMSI[thisSel]
+			}
+		default:
+			current = nil
+		}
+
+		if current == nil && panics {
+			panic(fmt.Sprintf("objx: '%v' invalid on object.", selector))
+		}
+
+		// do we need to access the item of an array?
+		if index > -1 {
+			if array, ok := current.([]interface{}); ok {
+				if index < len(array) {
+					current = array[index]
+				} else {
+					if panics {
+						panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array)))
+					}
+					current = nil
+				}
+			}
+		}
+
+		if len(selSegs) > 1 {
+			current = access(current, selSegs[1], value, isSet, panics)
+		}
+
+	}
+
+	return current
+
+}
+
+// intFromInterface converts an interface object to the largest
+// representation of an unsigned integer using a type switch and
+// assertions
+func intFromInterface(selector interface{}) int {
+	var value int
+	switch selector.(type) {
+	case int:
+		value = selector.(int)
+	case int8:
+		value = int(selector.(int8))
+	case int16:
+		value = int(selector.(int16))
+	case int32:
+		value = int(selector.(int32))
+	case int64:
+		value = int(selector.(int64))
+	case uint:
+		value = int(selector.(uint))
+	case uint8:
+		value = int(selector.(uint8))
+	case uint16:
+		value = int(selector.(uint16))
+	case uint32:
+		value = int(selector.(uint32))
+	case uint64:
+		value = int(selector.(uint64))
+	default:
+		panic("objx: array access argument is not an integer type (this should never happen)")
+	}
+
+	return value
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/array-access.txt b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/array-access.txt
new file mode 100644
index 0000000..3060234
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/array-access.txt
@@ -0,0 +1,14 @@
+  case []{1}:
+    a := object.([]{1})
+    if isSet {
+      a[index] = value.({1})
+    } else {
+      if index >= len(a) {
+        if panics {
+          panic(fmt.Sprintf("objx: Index %d is out of range because the []{1} only contains %d items.", index, len(a)))
+        }
+        return nil
+      } else {
+        return a[index]
+      }
+    }
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/index.html b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/index.html
new file mode 100644
index 0000000..379ffc3
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/index.html
@@ -0,0 +1,86 @@
+<html>
+	<head>
+	<title>
+		Codegen
+	</title>
+	<style>
+		body {
+			width: 800px;
+			margin: auto;
+		}
+		textarea {
+			width: 100%;
+			min-height: 100px;
+			font-family: Courier;
+		}
+	</style>
+	</head>
+	<body>
+
+		<h2>
+			Template
+		</h2>
+		<p>
+			Use <code>{x}</code> as a placeholder for each argument.
+		</p>
+		<textarea id="template"></textarea>
+
+		<h2>
+			Arguments (comma separated)
+		</h2>
+		<p>
+			One block per line
+		</p>
+		<textarea id="args"></textarea>
+
+		<h2>
+			Output
+		</h2>
+		<input id="go" type="button" value="Generate code" />
+
+		<textarea id="output"></textarea>
+
+		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
+		<script>
+
+			$(function(){
+
+				$("#go").click(function(){
+
+					var output = ""
+					var template = $("#template").val()
+					var args = $("#args").val()
+
+					// collect the args
+					var argLines = args.split("\n")
+					for (var line in argLines) {
+
+						var argLine = argLines[line];
+						var thisTemp = template
+
+						// get individual args
+						var args = argLine.split(",")
+
+						for (var argI in args) {
+							var argText = args[argI];
+							var argPlaceholder = "{" + argI + "}";
+
+							while (thisTemp.indexOf(argPlaceholder) > -1) {
+								thisTemp = thisTemp.replace(argPlaceholder, argText);
+							}
+
+						}
+
+						output += thisTemp
+
+					}
+
+					$("#output").val(output);
+
+				});
+
+			});
+
+		</script>
+	</body>
+</html>
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/template.txt b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/template.txt
new file mode 100644
index 0000000..b396900
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/template.txt
@@ -0,0 +1,286 @@
+/*
+	{4} ({1} and []{1})
+	--------------------------------------------------
+*/
+
+// {4} gets the value as a {1}, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) {4}(optionalDefault ...{1}) {1} {
+	if s, ok := v.data.({1}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return {3}
+}
+
+// Must{4} gets the value as a {1}.
+//
+// Panics if the object is not a {1}.
+func (v *Value) Must{4}() {1} {
+	return v.data.({1})
+}
+
+// {4}Slice gets the value as a []{1}, returns the optionalDefault
+// value or nil if the value is not a []{1}.
+func (v *Value) {4}Slice(optionalDefault ...[]{1}) []{1} {
+	if s, ok := v.data.([]{1}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// Must{4}Slice gets the value as a []{1}.
+//
+// Panics if the object is not a []{1}.
+func (v *Value) Must{4}Slice() []{1} {
+	return v.data.([]{1})
+}
+
+// Is{4} gets whether the object contained is a {1} or not.
+func (v *Value) Is{4}() bool {
+  _, ok := v.data.({1})
+  return ok
+}
+
+// Is{4}Slice gets whether the object contained is a []{1} or not.
+func (v *Value) Is{4}Slice() bool {
+	_, ok := v.data.([]{1})
+	return ok
+}
+
+// Each{4} calls the specified callback for each object
+// in the []{1}.
+//
+// Panics if the object is the wrong type.
+func (v *Value) Each{4}(callback func(int, {1}) bool) *Value {
+
+	for index, val := range v.Must{4}Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// Where{4} uses the specified decider function to select items
+// from the []{1}.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) Where{4}(decider func(int, {1}) bool) *Value {
+
+	var selected []{1}
+
+	v.Each{4}(func(index int, val {1}) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data:selected}
+
+}
+
+// Group{4} uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]{1}.
+func (v *Value) Group{4}(grouper func(int, {1}) string) *Value {
+
+	groups := make(map[string][]{1})
+
+	v.Each{4}(func(index int, val {1}) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]{1}, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data:groups}
+
+}
+
+// Replace{4} uses the specified function to replace each {1}s
+// by iterating each item.  The data in the returned result will be a
+// []{1} containing the replaced items.
+func (v *Value) Replace{4}(replacer func(int, {1}) {1}) *Value {
+
+	arr := v.Must{4}Slice()
+	replaced := make([]{1}, len(arr))
+
+	v.Each{4}(func(index int, val {1}) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data:replaced}
+
+}
+
+// Collect{4} uses the specified collector function to collect a value
+// for each of the {1}s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) Collect{4}(collector func(int, {1}) interface{}) *Value {
+
+	arr := v.Must{4}Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.Each{4}(func(index int, val {1}) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data:collected}
+}
+
+// ************************************************************
+// TESTS
+// ************************************************************
+
+func Test{4}(t *testing.T) {
+
+  val := {1}( {2} )
+	m := map[string]interface{}{"value": val, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").{4}())
+	assert.Equal(t, val, New(m).Get("value").Must{4}())
+	assert.Equal(t, {1}({3}), New(m).Get("nothing").{4}())
+	assert.Equal(t, val, New(m).Get("nothing").{4}({2}))
+
+	assert.Panics(t, func() {
+		New(m).Get("age").Must{4}()
+	})
+
+}
+
+func Test{4}Slice(t *testing.T) {
+
+  val := {1}( {2} )
+	m := map[string]interface{}{"value": []{1}{ val }, "nothing": nil}
+	assert.Equal(t, val, New(m).Get("value").{4}Slice()[0])
+	assert.Equal(t, val, New(m).Get("value").Must{4}Slice()[0])
+	assert.Equal(t, []{1}(nil), New(m).Get("nothing").{4}Slice())
+	assert.Equal(t, val, New(m).Get("nothing").{4}Slice( []{1}{ {1}({2}) } )[0])
+
+	assert.Panics(t, func() {
+		New(m).Get("nothing").Must{4}Slice()
+	})
+
+}
+
+func TestIs{4}(t *testing.T) {
+
+	var v *Value
+
+	v = &Value{data: {1}({2})}
+	assert.True(t, v.Is{4}())
+
+	v = &Value{data: []{1}{ {1}({2}) }}
+	assert.True(t, v.Is{4}Slice())
+
+}
+
+func TestEach{4}(t *testing.T) {
+
+	v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
+	count := 0
+	replacedVals := make([]{1}, 0)
+	assert.Equal(t, v, v.Each{4}(func(i int, val {1}) bool {
+
+		count++
+		replacedVals = append(replacedVals, val)
+
+		// abort early
+		if i == 2 {
+			return false
+		}
+
+		return true
+
+	}))
+
+	assert.Equal(t, count, 3)
+	assert.Equal(t, replacedVals[0], v.Must{4}Slice()[0])
+	assert.Equal(t, replacedVals[1], v.Must{4}Slice()[1])
+	assert.Equal(t, replacedVals[2], v.Must{4}Slice()[2])
+
+}
+
+func TestWhere{4}(t *testing.T) {
+
+	v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
+
+	selected := v.Where{4}(func(i int, val {1}) bool {
+		return i%2==0
+	}).Must{4}Slice()
+
+	assert.Equal(t, 3, len(selected))
+
+}
+
+func TestGroup{4}(t *testing.T) {
+
+	v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
+
+	grouped := v.Group{4}(func(i int, val {1}) string {
+		return fmt.Sprintf("%v", i%2==0)
+	}).data.(map[string][]{1})
+
+	assert.Equal(t, 2, len(grouped))
+	assert.Equal(t, 3, len(grouped["true"]))
+	assert.Equal(t, 3, len(grouped["false"]))
+
+}
+
+func TestReplace{4}(t *testing.T) {
+
+	v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
+
+	rawArr := v.Must{4}Slice()
+
+	replaced := v.Replace{4}(func(index int, val {1}) {1} {
+		if index < len(rawArr)-1 {
+			return rawArr[index+1]
+		}
+		return rawArr[0]
+	})
+
+	replacedArr := replaced.Must{4}Slice()
+	if assert.Equal(t, 6, len(replacedArr)) {
+		assert.Equal(t, replacedArr[0], rawArr[1])
+		assert.Equal(t, replacedArr[1], rawArr[2])
+		assert.Equal(t, replacedArr[2], rawArr[3])
+		assert.Equal(t, replacedArr[3], rawArr[4])
+		assert.Equal(t, replacedArr[4], rawArr[5])
+		assert.Equal(t, replacedArr[5], rawArr[0])
+	}
+
+}
+
+func TestCollect{4}(t *testing.T) {
+
+	v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
+
+	collected := v.Collect{4}(func(index int, val {1}) interface{} {
+		return index
+	})
+
+	collectedArr := collected.MustInterSlice()
+	if assert.Equal(t, 6, len(collectedArr)) {
+		assert.Equal(t, collectedArr[0], 0)
+		assert.Equal(t, collectedArr[1], 1)
+		assert.Equal(t, collectedArr[2], 2)
+		assert.Equal(t, collectedArr[3], 3)
+		assert.Equal(t, collectedArr[4], 4)
+		assert.Equal(t, collectedArr[5], 5)
+	}
+
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/types_list.txt b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/types_list.txt
new file mode 100644
index 0000000..069d43d
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/codegen/types_list.txt
@@ -0,0 +1,20 @@
+Interface,interface{},"something",nil,Inter
+Map,map[string]interface{},map[string]interface{}{"name":"Tyler"},nil,MSI
+ObjxMap,(Map),New(1),New(nil),ObjxMap
+Bool,bool,true,false,Bool
+String,string,"hello","",Str
+Int,int,1,0,Int
+Int8,int8,1,0,Int8
+Int16,int16,1,0,Int16
+Int32,int32,1,0,Int32
+Int64,int64,1,0,Int64
+Uint,uint,1,0,Uint
+Uint8,uint8,1,0,Uint8
+Uint16,uint16,1,0,Uint16
+Uint32,uint32,1,0,Uint32
+Uint64,uint64,1,0,Uint64
+Uintptr,uintptr,1,0,Uintptr
+Float32,float32,1,0,Float32
+Float64,float64,1,0,Float64
+Complex64,complex64,1,0,Complex64
+Complex128,complex128,1,0,Complex128
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/constants.go b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/constants.go
new file mode 100644
index 0000000..f9eb42a
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/constants.go
@@ -0,0 +1,13 @@
+package objx
+
+const (
+	// PathSeparator is the character used to separate the elements
+	// of the keypath.
+	//
+	// For example, `location.address.city`
+	PathSeparator string = "."
+
+	// SignatureSeparator is the character that is used to
+	// separate the Base64 string from the security signature.
+	SignatureSeparator = "_"
+)
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/conversions.go b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/conversions.go
new file mode 100644
index 0000000..9cdfa9f
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/conversions.go
@@ -0,0 +1,117 @@
+package objx
+
+import (
+	"bytes"
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"net/url"
+)
+
+// JSON converts the contained object to a JSON string
+// representation
+func (m Map) JSON() (string, error) {
+
+	result, err := json.Marshal(m)
+
+	if err != nil {
+		err = errors.New("objx: JSON encode failed with: " + err.Error())
+	}
+
+	return string(result), err
+
+}
+
+// MustJSON converts the contained object to a JSON string
+// representation and panics if there is an error
+func (m Map) MustJSON() string {
+	result, err := m.JSON()
+	if err != nil {
+		panic(err.Error())
+	}
+	return result
+}
+
+// Base64 converts the contained object to a Base64 string
+// representation of the JSON string representation
+func (m Map) Base64() (string, error) {
+
+	var buf bytes.Buffer
+
+	jsonData, err := m.JSON()
+	if err != nil {
+		return "", err
+	}
+
+	encoder := base64.NewEncoder(base64.StdEncoding, &buf)
+	encoder.Write([]byte(jsonData))
+	encoder.Close()
+
+	return buf.String(), nil
+
+}
+
+// MustBase64 converts the contained object to a Base64 string
+// representation of the JSON string representation and panics
+// if there is an error
+func (m Map) MustBase64() string {
+	result, err := m.Base64()
+	if err != nil {
+		panic(err.Error())
+	}
+	return result
+}
+
+// SignedBase64 converts the contained object to a Base64 string
+// representation of the JSON string representation and signs it
+// using the provided key.
+func (m Map) SignedBase64(key string) (string, error) {
+
+	base64, err := m.Base64()
+	if err != nil {
+		return "", err
+	}
+
+	sig := HashWithKey(base64, key)
+
+	return base64 + SignatureSeparator + sig, nil
+
+}
+
+// MustSignedBase64 converts the contained object to a Base64 string
+// representation of the JSON string representation and signs it
+// using the provided key and panics if there is an error
+func (m Map) MustSignedBase64(key string) string {
+	result, err := m.SignedBase64(key)
+	if err != nil {
+		panic(err.Error())
+	}
+	return result
+}
+
+/*
+	URL Query
+	------------------------------------------------
+*/
+
+// URLValues creates a url.Values object from an Obj. This
+// function requires that the wrapped object be a map[string]interface{}
+func (m Map) URLValues() url.Values {
+
+	vals := make(url.Values)
+
+	for k, v := range m {
+		//TODO: can this be done without sprintf?
+		vals.Set(k, fmt.Sprintf("%v", v))
+	}
+
+	return vals
+}
+
+// URLQuery gets an encoded URL query representing the given
+// Obj. This function requires that the wrapped object be a
+// map[string]interface{}
+func (m Map) URLQuery() (string, error) {
+	return m.URLValues().Encode(), nil
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/doc.go b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/doc.go
new file mode 100644
index 0000000..47bf85e
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/doc.go
@@ -0,0 +1,72 @@
+// objx - Go package for dealing with maps, slices, JSON and other data.
+//
+// Overview
+//
+// Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes
+// a powerful `Get` method (among others) that allows you to easily and quickly get
+// access to data within the map, without having to worry too much about type assertions,
+// missing data, default values etc.
+//
+// Pattern
+//
+// Objx uses a preditable pattern to make access data from within `map[string]interface{}'s
+// easy.
+//
+// Call one of the `objx.` functions to create your `objx.Map` to get going:
+//
+//     m, err := objx.FromJSON(json)
+//
+// NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong,
+// the rest will be optimistic and try to figure things out without panicking.
+//
+// Use `Get` to access the value you're interested in.  You can use dot and array
+// notation too:
+//
+//     m.Get("places[0].latlng")
+//
+// Once you have saught the `Value` you're interested in, you can use the `Is*` methods
+// to determine its type.
+//
+//     if m.Get("code").IsStr() { /* ... */ }
+//
+// Or you can just assume the type, and use one of the strong type methods to
+// extract the real value:
+//
+//     m.Get("code").Int()
+//
+// If there's no value there (or if it's the wrong type) then a default value
+// will be returned, or you can be explicit about the default value.
+//
+//     Get("code").Int(-1)
+//
+// If you're dealing with a slice of data as a value, Objx provides many useful
+// methods for iterating, manipulating and selecting that data.  You can find out more
+// by exploring the index below.
+//
+// Reading data
+//
+// A simple example of how to use Objx:
+//
+//     // use MustFromJSON to make an objx.Map from some JSON
+//     m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`)
+//
+//     // get the details
+//     name := m.Get("name").Str()
+//     age := m.Get("age").Int()
+//
+//     // get their nickname (or use their name if they
+//     // don't have one)
+//     nickname := m.Get("nickname").Str(name)
+//
+// Ranging
+//
+// Since `objx.Map` is a `map[string]interface{}` you can treat it as such.  For
+// example, to `range` the data, do what you would expect:
+//
+//     m := objx.MustFromJSON(json)
+//     for key, value := range m {
+//
+//       /* ... do your magic ... */
+//
+//     }
+package objx
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/map.go b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/map.go
new file mode 100644
index 0000000..eb6ed8e
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/map.go
@@ -0,0 +1,222 @@
+package objx
+
+import (
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"io/ioutil"
+	"net/url"
+	"strings"
+)
+
+// MSIConvertable is an interface that defines methods for converting your
+// custom types to a map[string]interface{} representation.
+type MSIConvertable interface {
+	// MSI gets a map[string]interface{} (msi) representing the
+	// object.
+	MSI() map[string]interface{}
+}
+
+// Map provides extended functionality for working with
+// untyped data, in particular map[string]interface (msi).
+type Map map[string]interface{}
+
+// Value returns the internal value instance
+func (m Map) Value() *Value {
+	return &Value{data: m}
+}
+
+// Nil represents a nil Map.
+var Nil Map = New(nil)
+
+// New creates a new Map containing the map[string]interface{} in the data argument.
+// If the data argument is not a map[string]interface, New attempts to call the
+// MSI() method on the MSIConvertable interface to create one.
+func New(data interface{}) Map {
+	if _, ok := data.(map[string]interface{}); !ok {
+		if converter, ok := data.(MSIConvertable); ok {
+			data = converter.MSI()
+		} else {
+			return nil
+		}
+	}
+	return Map(data.(map[string]interface{}))
+}
+
+// MSI creates a map[string]interface{} and puts it inside a new Map.
+//
+// The arguments follow a key, value pattern.
+//
+// Panics
+//
+// Panics if any key arugment is non-string or if there are an odd number of arguments.
+//
+// Example
+//
+// To easily create Maps:
+//
+//     m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true))
+//
+//     // creates an Map equivalent to
+//     m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}})
+func MSI(keyAndValuePairs ...interface{}) Map {
+
+	newMap := make(map[string]interface{})
+	keyAndValuePairsLen := len(keyAndValuePairs)
+
+	if keyAndValuePairsLen%2 != 0 {
+		panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.")
+	}
+
+	for i := 0; i < keyAndValuePairsLen; i = i + 2 {
+
+		key := keyAndValuePairs[i]
+		value := keyAndValuePairs[i+1]
+
+		// make sure the key is a string
+		keyString, keyStringOK := key.(string)
+		if !keyStringOK {
+			panic("objx: MSI must follow 'string, interface{}' pattern.  " + keyString + " is not a valid key.")
+		}
+
+		newMap[keyString] = value
+
+	}
+
+	return New(newMap)
+}
+
+// ****** Conversion Constructors
+
+// MustFromJSON creates a new Map containing the data specified in the
+// jsonString.
+//
+// Panics if the JSON is invalid.
+func MustFromJSON(jsonString string) Map {
+	o, err := FromJSON(jsonString)
+
+	if err != nil {
+		panic("objx: MustFromJSON failed with error: " + err.Error())
+	}
+
+	return o
+}
+
+// FromJSON creates a new Map containing the data specified in the
+// jsonString.
+//
+// Returns an error if the JSON is invalid.
+func FromJSON(jsonString string) (Map, error) {
+
+	var data interface{}
+	err := json.Unmarshal([]byte(jsonString), &data)
+
+	if err != nil {
+		return Nil, err
+	}
+
+	return New(data), nil
+
+}
+
+// FromBase64 creates a new Obj containing the data specified
+// in the Base64 string.
+//
+// The string is an encoded JSON string returned by Base64
+func FromBase64(base64String string) (Map, error) {
+
+	decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String))
+
+	decoded, err := ioutil.ReadAll(decoder)
+	if err != nil {
+		return nil, err
+	}
+
+	return FromJSON(string(decoded))
+}
+
+// MustFromBase64 creates a new Obj containing the data specified
+// in the Base64 string and panics if there is an error.
+//
+// The string is an encoded JSON string returned by Base64
+func MustFromBase64(base64String string) Map {
+
+	result, err := FromBase64(base64String)
+
+	if err != nil {
+		panic("objx: MustFromBase64 failed with error: " + err.Error())
+	}
+
+	return result
+}
+
+// FromSignedBase64 creates a new Obj containing the data specified
+// in the Base64 string.
+//
+// The string is an encoded JSON string returned by SignedBase64
+func FromSignedBase64(base64String, key string) (Map, error) {
+	parts := strings.Split(base64String, SignatureSeparator)
+	if len(parts) != 2 {
+		return nil, errors.New("objx: Signed base64 string is malformed.")
+	}
+
+	sig := HashWithKey(parts[0], key)
+	if parts[1] != sig {
+		return nil, errors.New("objx: Signature for base64 data does not match.")
+	}
+
+	return FromBase64(parts[0])
+}
+
+// MustFromSignedBase64 creates a new Obj containing the data specified
+// in the Base64 string and panics if there is an error.
+//
+// The string is an encoded JSON string returned by Base64
+func MustFromSignedBase64(base64String, key string) Map {
+
+	result, err := FromSignedBase64(base64String, key)
+
+	if err != nil {
+		panic("objx: MustFromSignedBase64 failed with error: " + err.Error())
+	}
+
+	return result
+}
+
+// FromURLQuery generates a new Obj by parsing the specified
+// query.
+//
+// For queries with multiple values, the first value is selected.
+func FromURLQuery(query string) (Map, error) {
+
+	vals, err := url.ParseQuery(query)
+
+	if err != nil {
+		return nil, err
+	}
+
+	m := make(map[string]interface{})
+	for k, vals := range vals {
+		m[k] = vals[0]
+	}
+
+	return New(m), nil
+}
+
+// MustFromURLQuery generates a new Obj by parsing the specified
+// query.
+//
+// For queries with multiple values, the first value is selected.
+//
+// Panics if it encounters an error
+func MustFromURLQuery(query string) Map {
+
+	o, err := FromURLQuery(query)
+
+	if err != nil {
+		panic("objx: MustFromURLQuery failed with error: " + err.Error())
+	}
+
+	return o
+
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/mutations.go b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/mutations.go
new file mode 100644
index 0000000..b35c863
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/mutations.go
@@ -0,0 +1,81 @@
+package objx
+
+// Exclude returns a new Map with the keys in the specified []string
+// excluded.
+func (d Map) Exclude(exclude []string) Map {
+
+	excluded := make(Map)
+	for k, v := range d {
+		var shouldInclude bool = true
+		for _, toExclude := range exclude {
+			if k == toExclude {
+				shouldInclude = false
+				break
+			}
+		}
+		if shouldInclude {
+			excluded[k] = v
+		}
+	}
+
+	return excluded
+}
+
+// Copy creates a shallow copy of the Obj.
+func (m Map) Copy() Map {
+	copied := make(map[string]interface{})
+	for k, v := range m {
+		copied[k] = v
+	}
+	return New(copied)
+}
+
+// Merge blends the specified map with a copy of this map and returns the result.
+//
+// Keys that appear in both will be selected from the specified map.
+// This method requires that the wrapped object be a map[string]interface{}
+func (m Map) Merge(merge Map) Map {
+	return m.Copy().MergeHere(merge)
+}
+
+// Merge blends the specified map with this map and returns the current map.
+//
+// Keys that appear in both will be selected from the specified map.  The original map
+// will be modified. This method requires that
+// the wrapped object be a map[string]interface{}
+func (m Map) MergeHere(merge Map) Map {
+
+	for k, v := range merge {
+		m[k] = v
+	}
+
+	return m
+
+}
+
+// Transform builds a new Obj giving the transformer a chance
+// to change the keys and values as it goes. This method requires that
+// the wrapped object be a map[string]interface{}
+func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map {
+	newMap := make(map[string]interface{})
+	for k, v := range m {
+		modifiedKey, modifiedVal := transformer(k, v)
+		newMap[modifiedKey] = modifiedVal
+	}
+	return New(newMap)
+}
+
+// TransformKeys builds a new map using the specified key mapping.
+//
+// Unspecified keys will be unaltered.
+// This method requires that the wrapped object be a map[string]interface{}
+func (m Map) TransformKeys(mapping map[string]string) Map {
+	return m.Transform(func(key string, value interface{}) (string, interface{}) {
+
+		if newKey, ok := mapping[key]; ok {
+			return newKey, value
+		}
+
+		return key, value
+	})
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/security.go b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/security.go
new file mode 100644
index 0000000..fdd6be9
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/security.go
@@ -0,0 +1,14 @@
+package objx
+
+import (
+	"crypto/sha1"
+	"encoding/hex"
+)
+
+// HashWithKey hashes the specified string using the security
+// key.
+func HashWithKey(data, key string) string {
+	hash := sha1.New()
+	hash.Write([]byte(data + ":" + key))
+	return hex.EncodeToString(hash.Sum(nil))
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/tests.go b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/tests.go
new file mode 100644
index 0000000..d9e0b47
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/tests.go
@@ -0,0 +1,17 @@
+package objx
+
+// Has gets whether there is something at the specified selector
+// or not.
+//
+// If m is nil, Has will always return false.
+func (m Map) Has(selector string) bool {
+	if m == nil {
+		return false
+	}
+	return !m.Get(selector).IsNil()
+}
+
+// IsNil gets whether the data is nil or not.
+func (v *Value) IsNil() bool {
+	return v == nil || v.data == nil
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/type_specific_codegen.go b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/type_specific_codegen.go
new file mode 100644
index 0000000..f3ecb29
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/type_specific_codegen.go
@@ -0,0 +1,2881 @@
+package objx
+
+/*
+	Inter (interface{} and []interface{})
+	--------------------------------------------------
+*/
+
+// Inter gets the value as a interface{}, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Inter(optionalDefault ...interface{}) interface{} {
+	if s, ok := v.data.(interface{}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInter gets the value as a interface{}.
+//
+// Panics if the object is not a interface{}.
+func (v *Value) MustInter() interface{} {
+	return v.data.(interface{})
+}
+
+// InterSlice gets the value as a []interface{}, returns the optionalDefault
+// value or nil if the value is not a []interface{}.
+func (v *Value) InterSlice(optionalDefault ...[]interface{}) []interface{} {
+	if s, ok := v.data.([]interface{}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInterSlice gets the value as a []interface{}.
+//
+// Panics if the object is not a []interface{}.
+func (v *Value) MustInterSlice() []interface{} {
+	return v.data.([]interface{})
+}
+
+// IsInter gets whether the object contained is a interface{} or not.
+func (v *Value) IsInter() bool {
+	_, ok := v.data.(interface{})
+	return ok
+}
+
+// IsInterSlice gets whether the object contained is a []interface{} or not.
+func (v *Value) IsInterSlice() bool {
+	_, ok := v.data.([]interface{})
+	return ok
+}
+
+// EachInter calls the specified callback for each object
+// in the []interface{}.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInter(callback func(int, interface{}) bool) *Value {
+
+	for index, val := range v.MustInterSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInter uses the specified decider function to select items
+// from the []interface{}.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInter(decider func(int, interface{}) bool) *Value {
+
+	var selected []interface{}
+
+	v.EachInter(func(index int, val interface{}) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInter uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]interface{}.
+func (v *Value) GroupInter(grouper func(int, interface{}) string) *Value {
+
+	groups := make(map[string][]interface{})
+
+	v.EachInter(func(index int, val interface{}) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]interface{}, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInter uses the specified function to replace each interface{}s
+// by iterating each item.  The data in the returned result will be a
+// []interface{} containing the replaced items.
+func (v *Value) ReplaceInter(replacer func(int, interface{}) interface{}) *Value {
+
+	arr := v.MustInterSlice()
+	replaced := make([]interface{}, len(arr))
+
+	v.EachInter(func(index int, val interface{}) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInter uses the specified collector function to collect a value
+// for each of the interface{}s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInter(collector func(int, interface{}) interface{}) *Value {
+
+	arr := v.MustInterSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInter(func(index int, val interface{}) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	MSI (map[string]interface{} and []map[string]interface{})
+	--------------------------------------------------
+*/
+
+// MSI gets the value as a map[string]interface{}, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) MSI(optionalDefault ...map[string]interface{}) map[string]interface{} {
+	if s, ok := v.data.(map[string]interface{}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustMSI gets the value as a map[string]interface{}.
+//
+// Panics if the object is not a map[string]interface{}.
+func (v *Value) MustMSI() map[string]interface{} {
+	return v.data.(map[string]interface{})
+}
+
+// MSISlice gets the value as a []map[string]interface{}, returns the optionalDefault
+// value or nil if the value is not a []map[string]interface{}.
+func (v *Value) MSISlice(optionalDefault ...[]map[string]interface{}) []map[string]interface{} {
+	if s, ok := v.data.([]map[string]interface{}); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustMSISlice gets the value as a []map[string]interface{}.
+//
+// Panics if the object is not a []map[string]interface{}.
+func (v *Value) MustMSISlice() []map[string]interface{} {
+	return v.data.([]map[string]interface{})
+}
+
+// IsMSI gets whether the object contained is a map[string]interface{} or not.
+func (v *Value) IsMSI() bool {
+	_, ok := v.data.(map[string]interface{})
+	return ok
+}
+
+// IsMSISlice gets whether the object contained is a []map[string]interface{} or not.
+func (v *Value) IsMSISlice() bool {
+	_, ok := v.data.([]map[string]interface{})
+	return ok
+}
+
+// EachMSI calls the specified callback for each object
+// in the []map[string]interface{}.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachMSI(callback func(int, map[string]interface{}) bool) *Value {
+
+	for index, val := range v.MustMSISlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereMSI uses the specified decider function to select items
+// from the []map[string]interface{}.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereMSI(decider func(int, map[string]interface{}) bool) *Value {
+
+	var selected []map[string]interface{}
+
+	v.EachMSI(func(index int, val map[string]interface{}) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupMSI uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]map[string]interface{}.
+func (v *Value) GroupMSI(grouper func(int, map[string]interface{}) string) *Value {
+
+	groups := make(map[string][]map[string]interface{})
+
+	v.EachMSI(func(index int, val map[string]interface{}) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]map[string]interface{}, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceMSI uses the specified function to replace each map[string]interface{}s
+// by iterating each item.  The data in the returned result will be a
+// []map[string]interface{} containing the replaced items.
+func (v *Value) ReplaceMSI(replacer func(int, map[string]interface{}) map[string]interface{}) *Value {
+
+	arr := v.MustMSISlice()
+	replaced := make([]map[string]interface{}, len(arr))
+
+	v.EachMSI(func(index int, val map[string]interface{}) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectMSI uses the specified collector function to collect a value
+// for each of the map[string]interface{}s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectMSI(collector func(int, map[string]interface{}) interface{}) *Value {
+
+	arr := v.MustMSISlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachMSI(func(index int, val map[string]interface{}) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	ObjxMap ((Map) and [](Map))
+	--------------------------------------------------
+*/
+
+// ObjxMap gets the value as a (Map), returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) ObjxMap(optionalDefault ...(Map)) Map {
+	if s, ok := v.data.((Map)); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return New(nil)
+}
+
+// MustObjxMap gets the value as a (Map).
+//
+// Panics if the object is not a (Map).
+func (v *Value) MustObjxMap() Map {
+	return v.data.((Map))
+}
+
+// ObjxMapSlice gets the value as a [](Map), returns the optionalDefault
+// value or nil if the value is not a [](Map).
+func (v *Value) ObjxMapSlice(optionalDefault ...[](Map)) [](Map) {
+	if s, ok := v.data.([](Map)); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustObjxMapSlice gets the value as a [](Map).
+//
+// Panics if the object is not a [](Map).
+func (v *Value) MustObjxMapSlice() [](Map) {
+	return v.data.([](Map))
+}
+
+// IsObjxMap gets whether the object contained is a (Map) or not.
+func (v *Value) IsObjxMap() bool {
+	_, ok := v.data.((Map))
+	return ok
+}
+
+// IsObjxMapSlice gets whether the object contained is a [](Map) or not.
+func (v *Value) IsObjxMapSlice() bool {
+	_, ok := v.data.([](Map))
+	return ok
+}
+
+// EachObjxMap calls the specified callback for each object
+// in the [](Map).
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachObjxMap(callback func(int, Map) bool) *Value {
+
+	for index, val := range v.MustObjxMapSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereObjxMap uses the specified decider function to select items
+// from the [](Map).  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereObjxMap(decider func(int, Map) bool) *Value {
+
+	var selected [](Map)
+
+	v.EachObjxMap(func(index int, val Map) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupObjxMap uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][](Map).
+func (v *Value) GroupObjxMap(grouper func(int, Map) string) *Value {
+
+	groups := make(map[string][](Map))
+
+	v.EachObjxMap(func(index int, val Map) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([](Map), 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceObjxMap uses the specified function to replace each (Map)s
+// by iterating each item.  The data in the returned result will be a
+// [](Map) containing the replaced items.
+func (v *Value) ReplaceObjxMap(replacer func(int, Map) Map) *Value {
+
+	arr := v.MustObjxMapSlice()
+	replaced := make([](Map), len(arr))
+
+	v.EachObjxMap(func(index int, val Map) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectObjxMap uses the specified collector function to collect a value
+// for each of the (Map)s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectObjxMap(collector func(int, Map) interface{}) *Value {
+
+	arr := v.MustObjxMapSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachObjxMap(func(index int, val Map) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Bool (bool and []bool)
+	--------------------------------------------------
+*/
+
+// Bool gets the value as a bool, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Bool(optionalDefault ...bool) bool {
+	if s, ok := v.data.(bool); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return false
+}
+
+// MustBool gets the value as a bool.
+//
+// Panics if the object is not a bool.
+func (v *Value) MustBool() bool {
+	return v.data.(bool)
+}
+
+// BoolSlice gets the value as a []bool, returns the optionalDefault
+// value or nil if the value is not a []bool.
+func (v *Value) BoolSlice(optionalDefault ...[]bool) []bool {
+	if s, ok := v.data.([]bool); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustBoolSlice gets the value as a []bool.
+//
+// Panics if the object is not a []bool.
+func (v *Value) MustBoolSlice() []bool {
+	return v.data.([]bool)
+}
+
+// IsBool gets whether the object contained is a bool or not.
+func (v *Value) IsBool() bool {
+	_, ok := v.data.(bool)
+	return ok
+}
+
+// IsBoolSlice gets whether the object contained is a []bool or not.
+func (v *Value) IsBoolSlice() bool {
+	_, ok := v.data.([]bool)
+	return ok
+}
+
+// EachBool calls the specified callback for each object
+// in the []bool.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachBool(callback func(int, bool) bool) *Value {
+
+	for index, val := range v.MustBoolSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereBool uses the specified decider function to select items
+// from the []bool.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereBool(decider func(int, bool) bool) *Value {
+
+	var selected []bool
+
+	v.EachBool(func(index int, val bool) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupBool uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]bool.
+func (v *Value) GroupBool(grouper func(int, bool) string) *Value {
+
+	groups := make(map[string][]bool)
+
+	v.EachBool(func(index int, val bool) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]bool, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceBool uses the specified function to replace each bools
+// by iterating each item.  The data in the returned result will be a
+// []bool containing the replaced items.
+func (v *Value) ReplaceBool(replacer func(int, bool) bool) *Value {
+
+	arr := v.MustBoolSlice()
+	replaced := make([]bool, len(arr))
+
+	v.EachBool(func(index int, val bool) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectBool uses the specified collector function to collect a value
+// for each of the bools in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectBool(collector func(int, bool) interface{}) *Value {
+
+	arr := v.MustBoolSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachBool(func(index int, val bool) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Str (string and []string)
+	--------------------------------------------------
+*/
+
+// Str gets the value as a string, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Str(optionalDefault ...string) string {
+	if s, ok := v.data.(string); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return ""
+}
+
+// MustStr gets the value as a string.
+//
+// Panics if the object is not a string.
+func (v *Value) MustStr() string {
+	return v.data.(string)
+}
+
+// StrSlice gets the value as a []string, returns the optionalDefault
+// value or nil if the value is not a []string.
+func (v *Value) StrSlice(optionalDefault ...[]string) []string {
+	if s, ok := v.data.([]string); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustStrSlice gets the value as a []string.
+//
+// Panics if the object is not a []string.
+func (v *Value) MustStrSlice() []string {
+	return v.data.([]string)
+}
+
+// IsStr gets whether the object contained is a string or not.
+func (v *Value) IsStr() bool {
+	_, ok := v.data.(string)
+	return ok
+}
+
+// IsStrSlice gets whether the object contained is a []string or not.
+func (v *Value) IsStrSlice() bool {
+	_, ok := v.data.([]string)
+	return ok
+}
+
+// EachStr calls the specified callback for each object
+// in the []string.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachStr(callback func(int, string) bool) *Value {
+
+	for index, val := range v.MustStrSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereStr uses the specified decider function to select items
+// from the []string.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereStr(decider func(int, string) bool) *Value {
+
+	var selected []string
+
+	v.EachStr(func(index int, val string) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupStr uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]string.
+func (v *Value) GroupStr(grouper func(int, string) string) *Value {
+
+	groups := make(map[string][]string)
+
+	v.EachStr(func(index int, val string) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]string, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceStr uses the specified function to replace each strings
+// by iterating each item.  The data in the returned result will be a
+// []string containing the replaced items.
+func (v *Value) ReplaceStr(replacer func(int, string) string) *Value {
+
+	arr := v.MustStrSlice()
+	replaced := make([]string, len(arr))
+
+	v.EachStr(func(index int, val string) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectStr uses the specified collector function to collect a value
+// for each of the strings in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectStr(collector func(int, string) interface{}) *Value {
+
+	arr := v.MustStrSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachStr(func(index int, val string) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Int (int and []int)
+	--------------------------------------------------
+*/
+
+// Int gets the value as a int, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Int(optionalDefault ...int) int {
+	if s, ok := v.data.(int); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustInt gets the value as a int.
+//
+// Panics if the object is not a int.
+func (v *Value) MustInt() int {
+	return v.data.(int)
+}
+
+// IntSlice gets the value as a []int, returns the optionalDefault
+// value or nil if the value is not a []int.
+func (v *Value) IntSlice(optionalDefault ...[]int) []int {
+	if s, ok := v.data.([]int); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustIntSlice gets the value as a []int.
+//
+// Panics if the object is not a []int.
+func (v *Value) MustIntSlice() []int {
+	return v.data.([]int)
+}
+
+// IsInt gets whether the object contained is a int or not.
+func (v *Value) IsInt() bool {
+	_, ok := v.data.(int)
+	return ok
+}
+
+// IsIntSlice gets whether the object contained is a []int or not.
+func (v *Value) IsIntSlice() bool {
+	_, ok := v.data.([]int)
+	return ok
+}
+
+// EachInt calls the specified callback for each object
+// in the []int.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInt(callback func(int, int) bool) *Value {
+
+	for index, val := range v.MustIntSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInt uses the specified decider function to select items
+// from the []int.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInt(decider func(int, int) bool) *Value {
+
+	var selected []int
+
+	v.EachInt(func(index int, val int) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInt uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]int.
+func (v *Value) GroupInt(grouper func(int, int) string) *Value {
+
+	groups := make(map[string][]int)
+
+	v.EachInt(func(index int, val int) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]int, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInt uses the specified function to replace each ints
+// by iterating each item.  The data in the returned result will be a
+// []int containing the replaced items.
+func (v *Value) ReplaceInt(replacer func(int, int) int) *Value {
+
+	arr := v.MustIntSlice()
+	replaced := make([]int, len(arr))
+
+	v.EachInt(func(index int, val int) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInt uses the specified collector function to collect a value
+// for each of the ints in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInt(collector func(int, int) interface{}) *Value {
+
+	arr := v.MustIntSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInt(func(index int, val int) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Int8 (int8 and []int8)
+	--------------------------------------------------
+*/
+
+// Int8 gets the value as a int8, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Int8(optionalDefault ...int8) int8 {
+	if s, ok := v.data.(int8); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustInt8 gets the value as a int8.
+//
+// Panics if the object is not a int8.
+func (v *Value) MustInt8() int8 {
+	return v.data.(int8)
+}
+
+// Int8Slice gets the value as a []int8, returns the optionalDefault
+// value or nil if the value is not a []int8.
+func (v *Value) Int8Slice(optionalDefault ...[]int8) []int8 {
+	if s, ok := v.data.([]int8); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInt8Slice gets the value as a []int8.
+//
+// Panics if the object is not a []int8.
+func (v *Value) MustInt8Slice() []int8 {
+	return v.data.([]int8)
+}
+
+// IsInt8 gets whether the object contained is a int8 or not.
+func (v *Value) IsInt8() bool {
+	_, ok := v.data.(int8)
+	return ok
+}
+
+// IsInt8Slice gets whether the object contained is a []int8 or not.
+func (v *Value) IsInt8Slice() bool {
+	_, ok := v.data.([]int8)
+	return ok
+}
+
+// EachInt8 calls the specified callback for each object
+// in the []int8.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInt8(callback func(int, int8) bool) *Value {
+
+	for index, val := range v.MustInt8Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInt8 uses the specified decider function to select items
+// from the []int8.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInt8(decider func(int, int8) bool) *Value {
+
+	var selected []int8
+
+	v.EachInt8(func(index int, val int8) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInt8 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]int8.
+func (v *Value) GroupInt8(grouper func(int, int8) string) *Value {
+
+	groups := make(map[string][]int8)
+
+	v.EachInt8(func(index int, val int8) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]int8, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInt8 uses the specified function to replace each int8s
+// by iterating each item.  The data in the returned result will be a
+// []int8 containing the replaced items.
+func (v *Value) ReplaceInt8(replacer func(int, int8) int8) *Value {
+
+	arr := v.MustInt8Slice()
+	replaced := make([]int8, len(arr))
+
+	v.EachInt8(func(index int, val int8) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInt8 uses the specified collector function to collect a value
+// for each of the int8s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInt8(collector func(int, int8) interface{}) *Value {
+
+	arr := v.MustInt8Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInt8(func(index int, val int8) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Int16 (int16 and []int16)
+	--------------------------------------------------
+*/
+
+// Int16 gets the value as a int16, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Int16(optionalDefault ...int16) int16 {
+	if s, ok := v.data.(int16); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustInt16 gets the value as a int16.
+//
+// Panics if the object is not a int16.
+func (v *Value) MustInt16() int16 {
+	return v.data.(int16)
+}
+
+// Int16Slice gets the value as a []int16, returns the optionalDefault
+// value or nil if the value is not a []int16.
+func (v *Value) Int16Slice(optionalDefault ...[]int16) []int16 {
+	if s, ok := v.data.([]int16); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInt16Slice gets the value as a []int16.
+//
+// Panics if the object is not a []int16.
+func (v *Value) MustInt16Slice() []int16 {
+	return v.data.([]int16)
+}
+
+// IsInt16 gets whether the object contained is a int16 or not.
+func (v *Value) IsInt16() bool {
+	_, ok := v.data.(int16)
+	return ok
+}
+
+// IsInt16Slice gets whether the object contained is a []int16 or not.
+func (v *Value) IsInt16Slice() bool {
+	_, ok := v.data.([]int16)
+	return ok
+}
+
+// EachInt16 calls the specified callback for each object
+// in the []int16.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInt16(callback func(int, int16) bool) *Value {
+
+	for index, val := range v.MustInt16Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInt16 uses the specified decider function to select items
+// from the []int16.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInt16(decider func(int, int16) bool) *Value {
+
+	var selected []int16
+
+	v.EachInt16(func(index int, val int16) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInt16 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]int16.
+func (v *Value) GroupInt16(grouper func(int, int16) string) *Value {
+
+	groups := make(map[string][]int16)
+
+	v.EachInt16(func(index int, val int16) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]int16, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInt16 uses the specified function to replace each int16s
+// by iterating each item.  The data in the returned result will be a
+// []int16 containing the replaced items.
+func (v *Value) ReplaceInt16(replacer func(int, int16) int16) *Value {
+
+	arr := v.MustInt16Slice()
+	replaced := make([]int16, len(arr))
+
+	v.EachInt16(func(index int, val int16) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInt16 uses the specified collector function to collect a value
+// for each of the int16s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInt16(collector func(int, int16) interface{}) *Value {
+
+	arr := v.MustInt16Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInt16(func(index int, val int16) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Int32 (int32 and []int32)
+	--------------------------------------------------
+*/
+
+// Int32 gets the value as a int32, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Int32(optionalDefault ...int32) int32 {
+	if s, ok := v.data.(int32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustInt32 gets the value as a int32.
+//
+// Panics if the object is not a int32.
+func (v *Value) MustInt32() int32 {
+	return v.data.(int32)
+}
+
+// Int32Slice gets the value as a []int32, returns the optionalDefault
+// value or nil if the value is not a []int32.
+func (v *Value) Int32Slice(optionalDefault ...[]int32) []int32 {
+	if s, ok := v.data.([]int32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInt32Slice gets the value as a []int32.
+//
+// Panics if the object is not a []int32.
+func (v *Value) MustInt32Slice() []int32 {
+	return v.data.([]int32)
+}
+
+// IsInt32 gets whether the object contained is a int32 or not.
+func (v *Value) IsInt32() bool {
+	_, ok := v.data.(int32)
+	return ok
+}
+
+// IsInt32Slice gets whether the object contained is a []int32 or not.
+func (v *Value) IsInt32Slice() bool {
+	_, ok := v.data.([]int32)
+	return ok
+}
+
+// EachInt32 calls the specified callback for each object
+// in the []int32.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInt32(callback func(int, int32) bool) *Value {
+
+	for index, val := range v.MustInt32Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInt32 uses the specified decider function to select items
+// from the []int32.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInt32(decider func(int, int32) bool) *Value {
+
+	var selected []int32
+
+	v.EachInt32(func(index int, val int32) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInt32 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]int32.
+func (v *Value) GroupInt32(grouper func(int, int32) string) *Value {
+
+	groups := make(map[string][]int32)
+
+	v.EachInt32(func(index int, val int32) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]int32, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInt32 uses the specified function to replace each int32s
+// by iterating each item.  The data in the returned result will be a
+// []int32 containing the replaced items.
+func (v *Value) ReplaceInt32(replacer func(int, int32) int32) *Value {
+
+	arr := v.MustInt32Slice()
+	replaced := make([]int32, len(arr))
+
+	v.EachInt32(func(index int, val int32) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInt32 uses the specified collector function to collect a value
+// for each of the int32s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInt32(collector func(int, int32) interface{}) *Value {
+
+	arr := v.MustInt32Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInt32(func(index int, val int32) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Int64 (int64 and []int64)
+	--------------------------------------------------
+*/
+
+// Int64 gets the value as a int64, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Int64(optionalDefault ...int64) int64 {
+	if s, ok := v.data.(int64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustInt64 gets the value as a int64.
+//
+// Panics if the object is not a int64.
+func (v *Value) MustInt64() int64 {
+	return v.data.(int64)
+}
+
+// Int64Slice gets the value as a []int64, returns the optionalDefault
+// value or nil if the value is not a []int64.
+func (v *Value) Int64Slice(optionalDefault ...[]int64) []int64 {
+	if s, ok := v.data.([]int64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustInt64Slice gets the value as a []int64.
+//
+// Panics if the object is not a []int64.
+func (v *Value) MustInt64Slice() []int64 {
+	return v.data.([]int64)
+}
+
+// IsInt64 gets whether the object contained is a int64 or not.
+func (v *Value) IsInt64() bool {
+	_, ok := v.data.(int64)
+	return ok
+}
+
+// IsInt64Slice gets whether the object contained is a []int64 or not.
+func (v *Value) IsInt64Slice() bool {
+	_, ok := v.data.([]int64)
+	return ok
+}
+
+// EachInt64 calls the specified callback for each object
+// in the []int64.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachInt64(callback func(int, int64) bool) *Value {
+
+	for index, val := range v.MustInt64Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereInt64 uses the specified decider function to select items
+// from the []int64.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereInt64(decider func(int, int64) bool) *Value {
+
+	var selected []int64
+
+	v.EachInt64(func(index int, val int64) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupInt64 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]int64.
+func (v *Value) GroupInt64(grouper func(int, int64) string) *Value {
+
+	groups := make(map[string][]int64)
+
+	v.EachInt64(func(index int, val int64) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]int64, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceInt64 uses the specified function to replace each int64s
+// by iterating each item.  The data in the returned result will be a
+// []int64 containing the replaced items.
+func (v *Value) ReplaceInt64(replacer func(int, int64) int64) *Value {
+
+	arr := v.MustInt64Slice()
+	replaced := make([]int64, len(arr))
+
+	v.EachInt64(func(index int, val int64) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectInt64 uses the specified collector function to collect a value
+// for each of the int64s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectInt64(collector func(int, int64) interface{}) *Value {
+
+	arr := v.MustInt64Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachInt64(func(index int, val int64) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uint (uint and []uint)
+	--------------------------------------------------
+*/
+
+// Uint gets the value as a uint, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uint(optionalDefault ...uint) uint {
+	if s, ok := v.data.(uint); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUint gets the value as a uint.
+//
+// Panics if the object is not a uint.
+func (v *Value) MustUint() uint {
+	return v.data.(uint)
+}
+
+// UintSlice gets the value as a []uint, returns the optionalDefault
+// value or nil if the value is not a []uint.
+func (v *Value) UintSlice(optionalDefault ...[]uint) []uint {
+	if s, ok := v.data.([]uint); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUintSlice gets the value as a []uint.
+//
+// Panics if the object is not a []uint.
+func (v *Value) MustUintSlice() []uint {
+	return v.data.([]uint)
+}
+
+// IsUint gets whether the object contained is a uint or not.
+func (v *Value) IsUint() bool {
+	_, ok := v.data.(uint)
+	return ok
+}
+
+// IsUintSlice gets whether the object contained is a []uint or not.
+func (v *Value) IsUintSlice() bool {
+	_, ok := v.data.([]uint)
+	return ok
+}
+
+// EachUint calls the specified callback for each object
+// in the []uint.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUint(callback func(int, uint) bool) *Value {
+
+	for index, val := range v.MustUintSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUint uses the specified decider function to select items
+// from the []uint.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUint(decider func(int, uint) bool) *Value {
+
+	var selected []uint
+
+	v.EachUint(func(index int, val uint) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUint uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uint.
+func (v *Value) GroupUint(grouper func(int, uint) string) *Value {
+
+	groups := make(map[string][]uint)
+
+	v.EachUint(func(index int, val uint) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uint, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUint uses the specified function to replace each uints
+// by iterating each item.  The data in the returned result will be a
+// []uint containing the replaced items.
+func (v *Value) ReplaceUint(replacer func(int, uint) uint) *Value {
+
+	arr := v.MustUintSlice()
+	replaced := make([]uint, len(arr))
+
+	v.EachUint(func(index int, val uint) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUint uses the specified collector function to collect a value
+// for each of the uints in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUint(collector func(int, uint) interface{}) *Value {
+
+	arr := v.MustUintSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUint(func(index int, val uint) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uint8 (uint8 and []uint8)
+	--------------------------------------------------
+*/
+
+// Uint8 gets the value as a uint8, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uint8(optionalDefault ...uint8) uint8 {
+	if s, ok := v.data.(uint8); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUint8 gets the value as a uint8.
+//
+// Panics if the object is not a uint8.
+func (v *Value) MustUint8() uint8 {
+	return v.data.(uint8)
+}
+
+// Uint8Slice gets the value as a []uint8, returns the optionalDefault
+// value or nil if the value is not a []uint8.
+func (v *Value) Uint8Slice(optionalDefault ...[]uint8) []uint8 {
+	if s, ok := v.data.([]uint8); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUint8Slice gets the value as a []uint8.
+//
+// Panics if the object is not a []uint8.
+func (v *Value) MustUint8Slice() []uint8 {
+	return v.data.([]uint8)
+}
+
+// IsUint8 gets whether the object contained is a uint8 or not.
+func (v *Value) IsUint8() bool {
+	_, ok := v.data.(uint8)
+	return ok
+}
+
+// IsUint8Slice gets whether the object contained is a []uint8 or not.
+func (v *Value) IsUint8Slice() bool {
+	_, ok := v.data.([]uint8)
+	return ok
+}
+
+// EachUint8 calls the specified callback for each object
+// in the []uint8.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUint8(callback func(int, uint8) bool) *Value {
+
+	for index, val := range v.MustUint8Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUint8 uses the specified decider function to select items
+// from the []uint8.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUint8(decider func(int, uint8) bool) *Value {
+
+	var selected []uint8
+
+	v.EachUint8(func(index int, val uint8) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUint8 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uint8.
+func (v *Value) GroupUint8(grouper func(int, uint8) string) *Value {
+
+	groups := make(map[string][]uint8)
+
+	v.EachUint8(func(index int, val uint8) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uint8, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUint8 uses the specified function to replace each uint8s
+// by iterating each item.  The data in the returned result will be a
+// []uint8 containing the replaced items.
+func (v *Value) ReplaceUint8(replacer func(int, uint8) uint8) *Value {
+
+	arr := v.MustUint8Slice()
+	replaced := make([]uint8, len(arr))
+
+	v.EachUint8(func(index int, val uint8) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUint8 uses the specified collector function to collect a value
+// for each of the uint8s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUint8(collector func(int, uint8) interface{}) *Value {
+
+	arr := v.MustUint8Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUint8(func(index int, val uint8) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uint16 (uint16 and []uint16)
+	--------------------------------------------------
+*/
+
+// Uint16 gets the value as a uint16, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uint16(optionalDefault ...uint16) uint16 {
+	if s, ok := v.data.(uint16); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUint16 gets the value as a uint16.
+//
+// Panics if the object is not a uint16.
+func (v *Value) MustUint16() uint16 {
+	return v.data.(uint16)
+}
+
+// Uint16Slice gets the value as a []uint16, returns the optionalDefault
+// value or nil if the value is not a []uint16.
+func (v *Value) Uint16Slice(optionalDefault ...[]uint16) []uint16 {
+	if s, ok := v.data.([]uint16); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUint16Slice gets the value as a []uint16.
+//
+// Panics if the object is not a []uint16.
+func (v *Value) MustUint16Slice() []uint16 {
+	return v.data.([]uint16)
+}
+
+// IsUint16 gets whether the object contained is a uint16 or not.
+func (v *Value) IsUint16() bool {
+	_, ok := v.data.(uint16)
+	return ok
+}
+
+// IsUint16Slice gets whether the object contained is a []uint16 or not.
+func (v *Value) IsUint16Slice() bool {
+	_, ok := v.data.([]uint16)
+	return ok
+}
+
+// EachUint16 calls the specified callback for each object
+// in the []uint16.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUint16(callback func(int, uint16) bool) *Value {
+
+	for index, val := range v.MustUint16Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUint16 uses the specified decider function to select items
+// from the []uint16.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUint16(decider func(int, uint16) bool) *Value {
+
+	var selected []uint16
+
+	v.EachUint16(func(index int, val uint16) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUint16 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uint16.
+func (v *Value) GroupUint16(grouper func(int, uint16) string) *Value {
+
+	groups := make(map[string][]uint16)
+
+	v.EachUint16(func(index int, val uint16) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uint16, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUint16 uses the specified function to replace each uint16s
+// by iterating each item.  The data in the returned result will be a
+// []uint16 containing the replaced items.
+func (v *Value) ReplaceUint16(replacer func(int, uint16) uint16) *Value {
+
+	arr := v.MustUint16Slice()
+	replaced := make([]uint16, len(arr))
+
+	v.EachUint16(func(index int, val uint16) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUint16 uses the specified collector function to collect a value
+// for each of the uint16s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUint16(collector func(int, uint16) interface{}) *Value {
+
+	arr := v.MustUint16Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUint16(func(index int, val uint16) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uint32 (uint32 and []uint32)
+	--------------------------------------------------
+*/
+
+// Uint32 gets the value as a uint32, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uint32(optionalDefault ...uint32) uint32 {
+	if s, ok := v.data.(uint32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUint32 gets the value as a uint32.
+//
+// Panics if the object is not a uint32.
+func (v *Value) MustUint32() uint32 {
+	return v.data.(uint32)
+}
+
+// Uint32Slice gets the value as a []uint32, returns the optionalDefault
+// value or nil if the value is not a []uint32.
+func (v *Value) Uint32Slice(optionalDefault ...[]uint32) []uint32 {
+	if s, ok := v.data.([]uint32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUint32Slice gets the value as a []uint32.
+//
+// Panics if the object is not a []uint32.
+func (v *Value) MustUint32Slice() []uint32 {
+	return v.data.([]uint32)
+}
+
+// IsUint32 gets whether the object contained is a uint32 or not.
+func (v *Value) IsUint32() bool {
+	_, ok := v.data.(uint32)
+	return ok
+}
+
+// IsUint32Slice gets whether the object contained is a []uint32 or not.
+func (v *Value) IsUint32Slice() bool {
+	_, ok := v.data.([]uint32)
+	return ok
+}
+
+// EachUint32 calls the specified callback for each object
+// in the []uint32.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUint32(callback func(int, uint32) bool) *Value {
+
+	for index, val := range v.MustUint32Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUint32 uses the specified decider function to select items
+// from the []uint32.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUint32(decider func(int, uint32) bool) *Value {
+
+	var selected []uint32
+
+	v.EachUint32(func(index int, val uint32) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUint32 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uint32.
+func (v *Value) GroupUint32(grouper func(int, uint32) string) *Value {
+
+	groups := make(map[string][]uint32)
+
+	v.EachUint32(func(index int, val uint32) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uint32, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUint32 uses the specified function to replace each uint32s
+// by iterating each item.  The data in the returned result will be a
+// []uint32 containing the replaced items.
+func (v *Value) ReplaceUint32(replacer func(int, uint32) uint32) *Value {
+
+	arr := v.MustUint32Slice()
+	replaced := make([]uint32, len(arr))
+
+	v.EachUint32(func(index int, val uint32) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUint32 uses the specified collector function to collect a value
+// for each of the uint32s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUint32(collector func(int, uint32) interface{}) *Value {
+
+	arr := v.MustUint32Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUint32(func(index int, val uint32) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uint64 (uint64 and []uint64)
+	--------------------------------------------------
+*/
+
+// Uint64 gets the value as a uint64, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uint64(optionalDefault ...uint64) uint64 {
+	if s, ok := v.data.(uint64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUint64 gets the value as a uint64.
+//
+// Panics if the object is not a uint64.
+func (v *Value) MustUint64() uint64 {
+	return v.data.(uint64)
+}
+
+// Uint64Slice gets the value as a []uint64, returns the optionalDefault
+// value or nil if the value is not a []uint64.
+func (v *Value) Uint64Slice(optionalDefault ...[]uint64) []uint64 {
+	if s, ok := v.data.([]uint64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUint64Slice gets the value as a []uint64.
+//
+// Panics if the object is not a []uint64.
+func (v *Value) MustUint64Slice() []uint64 {
+	return v.data.([]uint64)
+}
+
+// IsUint64 gets whether the object contained is a uint64 or not.
+func (v *Value) IsUint64() bool {
+	_, ok := v.data.(uint64)
+	return ok
+}
+
+// IsUint64Slice gets whether the object contained is a []uint64 or not.
+func (v *Value) IsUint64Slice() bool {
+	_, ok := v.data.([]uint64)
+	return ok
+}
+
+// EachUint64 calls the specified callback for each object
+// in the []uint64.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUint64(callback func(int, uint64) bool) *Value {
+
+	for index, val := range v.MustUint64Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUint64 uses the specified decider function to select items
+// from the []uint64.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUint64(decider func(int, uint64) bool) *Value {
+
+	var selected []uint64
+
+	v.EachUint64(func(index int, val uint64) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUint64 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uint64.
+func (v *Value) GroupUint64(grouper func(int, uint64) string) *Value {
+
+	groups := make(map[string][]uint64)
+
+	v.EachUint64(func(index int, val uint64) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uint64, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUint64 uses the specified function to replace each uint64s
+// by iterating each item.  The data in the returned result will be a
+// []uint64 containing the replaced items.
+func (v *Value) ReplaceUint64(replacer func(int, uint64) uint64) *Value {
+
+	arr := v.MustUint64Slice()
+	replaced := make([]uint64, len(arr))
+
+	v.EachUint64(func(index int, val uint64) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUint64 uses the specified collector function to collect a value
+// for each of the uint64s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUint64(collector func(int, uint64) interface{}) *Value {
+
+	arr := v.MustUint64Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUint64(func(index int, val uint64) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Uintptr (uintptr and []uintptr)
+	--------------------------------------------------
+*/
+
+// Uintptr gets the value as a uintptr, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Uintptr(optionalDefault ...uintptr) uintptr {
+	if s, ok := v.data.(uintptr); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustUintptr gets the value as a uintptr.
+//
+// Panics if the object is not a uintptr.
+func (v *Value) MustUintptr() uintptr {
+	return v.data.(uintptr)
+}
+
+// UintptrSlice gets the value as a []uintptr, returns the optionalDefault
+// value or nil if the value is not a []uintptr.
+func (v *Value) UintptrSlice(optionalDefault ...[]uintptr) []uintptr {
+	if s, ok := v.data.([]uintptr); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustUintptrSlice gets the value as a []uintptr.
+//
+// Panics if the object is not a []uintptr.
+func (v *Value) MustUintptrSlice() []uintptr {
+	return v.data.([]uintptr)
+}
+
+// IsUintptr gets whether the object contained is a uintptr or not.
+func (v *Value) IsUintptr() bool {
+	_, ok := v.data.(uintptr)
+	return ok
+}
+
+// IsUintptrSlice gets whether the object contained is a []uintptr or not.
+func (v *Value) IsUintptrSlice() bool {
+	_, ok := v.data.([]uintptr)
+	return ok
+}
+
+// EachUintptr calls the specified callback for each object
+// in the []uintptr.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachUintptr(callback func(int, uintptr) bool) *Value {
+
+	for index, val := range v.MustUintptrSlice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereUintptr uses the specified decider function to select items
+// from the []uintptr.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereUintptr(decider func(int, uintptr) bool) *Value {
+
+	var selected []uintptr
+
+	v.EachUintptr(func(index int, val uintptr) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupUintptr uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]uintptr.
+func (v *Value) GroupUintptr(grouper func(int, uintptr) string) *Value {
+
+	groups := make(map[string][]uintptr)
+
+	v.EachUintptr(func(index int, val uintptr) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]uintptr, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceUintptr uses the specified function to replace each uintptrs
+// by iterating each item.  The data in the returned result will be a
+// []uintptr containing the replaced items.
+func (v *Value) ReplaceUintptr(replacer func(int, uintptr) uintptr) *Value {
+
+	arr := v.MustUintptrSlice()
+	replaced := make([]uintptr, len(arr))
+
+	v.EachUintptr(func(index int, val uintptr) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectUintptr uses the specified collector function to collect a value
+// for each of the uintptrs in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectUintptr(collector func(int, uintptr) interface{}) *Value {
+
+	arr := v.MustUintptrSlice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachUintptr(func(index int, val uintptr) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Float32 (float32 and []float32)
+	--------------------------------------------------
+*/
+
+// Float32 gets the value as a float32, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Float32(optionalDefault ...float32) float32 {
+	if s, ok := v.data.(float32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustFloat32 gets the value as a float32.
+//
+// Panics if the object is not a float32.
+func (v *Value) MustFloat32() float32 {
+	return v.data.(float32)
+}
+
+// Float32Slice gets the value as a []float32, returns the optionalDefault
+// value or nil if the value is not a []float32.
+func (v *Value) Float32Slice(optionalDefault ...[]float32) []float32 {
+	if s, ok := v.data.([]float32); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustFloat32Slice gets the value as a []float32.
+//
+// Panics if the object is not a []float32.
+func (v *Value) MustFloat32Slice() []float32 {
+	return v.data.([]float32)
+}
+
+// IsFloat32 gets whether the object contained is a float32 or not.
+func (v *Value) IsFloat32() bool {
+	_, ok := v.data.(float32)
+	return ok
+}
+
+// IsFloat32Slice gets whether the object contained is a []float32 or not.
+func (v *Value) IsFloat32Slice() bool {
+	_, ok := v.data.([]float32)
+	return ok
+}
+
+// EachFloat32 calls the specified callback for each object
+// in the []float32.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachFloat32(callback func(int, float32) bool) *Value {
+
+	for index, val := range v.MustFloat32Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereFloat32 uses the specified decider function to select items
+// from the []float32.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereFloat32(decider func(int, float32) bool) *Value {
+
+	var selected []float32
+
+	v.EachFloat32(func(index int, val float32) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupFloat32 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]float32.
+func (v *Value) GroupFloat32(grouper func(int, float32) string) *Value {
+
+	groups := make(map[string][]float32)
+
+	v.EachFloat32(func(index int, val float32) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]float32, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceFloat32 uses the specified function to replace each float32s
+// by iterating each item.  The data in the returned result will be a
+// []float32 containing the replaced items.
+func (v *Value) ReplaceFloat32(replacer func(int, float32) float32) *Value {
+
+	arr := v.MustFloat32Slice()
+	replaced := make([]float32, len(arr))
+
+	v.EachFloat32(func(index int, val float32) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectFloat32 uses the specified collector function to collect a value
+// for each of the float32s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectFloat32(collector func(int, float32) interface{}) *Value {
+
+	arr := v.MustFloat32Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachFloat32(func(index int, val float32) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Float64 (float64 and []float64)
+	--------------------------------------------------
+*/
+
+// Float64 gets the value as a float64, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Float64(optionalDefault ...float64) float64 {
+	if s, ok := v.data.(float64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustFloat64 gets the value as a float64.
+//
+// Panics if the object is not a float64.
+func (v *Value) MustFloat64() float64 {
+	return v.data.(float64)
+}
+
+// Float64Slice gets the value as a []float64, returns the optionalDefault
+// value or nil if the value is not a []float64.
+func (v *Value) Float64Slice(optionalDefault ...[]float64) []float64 {
+	if s, ok := v.data.([]float64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustFloat64Slice gets the value as a []float64.
+//
+// Panics if the object is not a []float64.
+func (v *Value) MustFloat64Slice() []float64 {
+	return v.data.([]float64)
+}
+
+// IsFloat64 gets whether the object contained is a float64 or not.
+func (v *Value) IsFloat64() bool {
+	_, ok := v.data.(float64)
+	return ok
+}
+
+// IsFloat64Slice gets whether the object contained is a []float64 or not.
+func (v *Value) IsFloat64Slice() bool {
+	_, ok := v.data.([]float64)
+	return ok
+}
+
+// EachFloat64 calls the specified callback for each object
+// in the []float64.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachFloat64(callback func(int, float64) bool) *Value {
+
+	for index, val := range v.MustFloat64Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereFloat64 uses the specified decider function to select items
+// from the []float64.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereFloat64(decider func(int, float64) bool) *Value {
+
+	var selected []float64
+
+	v.EachFloat64(func(index int, val float64) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupFloat64 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]float64.
+func (v *Value) GroupFloat64(grouper func(int, float64) string) *Value {
+
+	groups := make(map[string][]float64)
+
+	v.EachFloat64(func(index int, val float64) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]float64, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceFloat64 uses the specified function to replace each float64s
+// by iterating each item.  The data in the returned result will be a
+// []float64 containing the replaced items.
+func (v *Value) ReplaceFloat64(replacer func(int, float64) float64) *Value {
+
+	arr := v.MustFloat64Slice()
+	replaced := make([]float64, len(arr))
+
+	v.EachFloat64(func(index int, val float64) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectFloat64 uses the specified collector function to collect a value
+// for each of the float64s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectFloat64(collector func(int, float64) interface{}) *Value {
+
+	arr := v.MustFloat64Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachFloat64(func(index int, val float64) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Complex64 (complex64 and []complex64)
+	--------------------------------------------------
+*/
+
+// Complex64 gets the value as a complex64, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Complex64(optionalDefault ...complex64) complex64 {
+	if s, ok := v.data.(complex64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustComplex64 gets the value as a complex64.
+//
+// Panics if the object is not a complex64.
+func (v *Value) MustComplex64() complex64 {
+	return v.data.(complex64)
+}
+
+// Complex64Slice gets the value as a []complex64, returns the optionalDefault
+// value or nil if the value is not a []complex64.
+func (v *Value) Complex64Slice(optionalDefault ...[]complex64) []complex64 {
+	if s, ok := v.data.([]complex64); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustComplex64Slice gets the value as a []complex64.
+//
+// Panics if the object is not a []complex64.
+func (v *Value) MustComplex64Slice() []complex64 {
+	return v.data.([]complex64)
+}
+
+// IsComplex64 gets whether the object contained is a complex64 or not.
+func (v *Value) IsComplex64() bool {
+	_, ok := v.data.(complex64)
+	return ok
+}
+
+// IsComplex64Slice gets whether the object contained is a []complex64 or not.
+func (v *Value) IsComplex64Slice() bool {
+	_, ok := v.data.([]complex64)
+	return ok
+}
+
+// EachComplex64 calls the specified callback for each object
+// in the []complex64.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachComplex64(callback func(int, complex64) bool) *Value {
+
+	for index, val := range v.MustComplex64Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereComplex64 uses the specified decider function to select items
+// from the []complex64.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereComplex64(decider func(int, complex64) bool) *Value {
+
+	var selected []complex64
+
+	v.EachComplex64(func(index int, val complex64) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupComplex64 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]complex64.
+func (v *Value) GroupComplex64(grouper func(int, complex64) string) *Value {
+
+	groups := make(map[string][]complex64)
+
+	v.EachComplex64(func(index int, val complex64) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]complex64, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceComplex64 uses the specified function to replace each complex64s
+// by iterating each item.  The data in the returned result will be a
+// []complex64 containing the replaced items.
+func (v *Value) ReplaceComplex64(replacer func(int, complex64) complex64) *Value {
+
+	arr := v.MustComplex64Slice()
+	replaced := make([]complex64, len(arr))
+
+	v.EachComplex64(func(index int, val complex64) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectComplex64 uses the specified collector function to collect a value
+// for each of the complex64s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectComplex64(collector func(int, complex64) interface{}) *Value {
+
+	arr := v.MustComplex64Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachComplex64(func(index int, val complex64) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
+
+/*
+	Complex128 (complex128 and []complex128)
+	--------------------------------------------------
+*/
+
+// Complex128 gets the value as a complex128, returns the optionalDefault
+// value or a system default object if the value is the wrong type.
+func (v *Value) Complex128(optionalDefault ...complex128) complex128 {
+	if s, ok := v.data.(complex128); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return 0
+}
+
+// MustComplex128 gets the value as a complex128.
+//
+// Panics if the object is not a complex128.
+func (v *Value) MustComplex128() complex128 {
+	return v.data.(complex128)
+}
+
+// Complex128Slice gets the value as a []complex128, returns the optionalDefault
+// value or nil if the value is not a []complex128.
+func (v *Value) Complex128Slice(optionalDefault ...[]complex128) []complex128 {
+	if s, ok := v.data.([]complex128); ok {
+		return s
+	}
+	if len(optionalDefault) == 1 {
+		return optionalDefault[0]
+	}
+	return nil
+}
+
+// MustComplex128Slice gets the value as a []complex128.
+//
+// Panics if the object is not a []complex128.
+func (v *Value) MustComplex128Slice() []complex128 {
+	return v.data.([]complex128)
+}
+
+// IsComplex128 gets whether the object contained is a complex128 or not.
+func (v *Value) IsComplex128() bool {
+	_, ok := v.data.(complex128)
+	return ok
+}
+
+// IsComplex128Slice gets whether the object contained is a []complex128 or not.
+func (v *Value) IsComplex128Slice() bool {
+	_, ok := v.data.([]complex128)
+	return ok
+}
+
+// EachComplex128 calls the specified callback for each object
+// in the []complex128.
+//
+// Panics if the object is the wrong type.
+func (v *Value) EachComplex128(callback func(int, complex128) bool) *Value {
+
+	for index, val := range v.MustComplex128Slice() {
+		carryon := callback(index, val)
+		if carryon == false {
+			break
+		}
+	}
+
+	return v
+
+}
+
+// WhereComplex128 uses the specified decider function to select items
+// from the []complex128.  The object contained in the result will contain
+// only the selected items.
+func (v *Value) WhereComplex128(decider func(int, complex128) bool) *Value {
+
+	var selected []complex128
+
+	v.EachComplex128(func(index int, val complex128) bool {
+		shouldSelect := decider(index, val)
+		if shouldSelect == false {
+			selected = append(selected, val)
+		}
+		return true
+	})
+
+	return &Value{data: selected}
+
+}
+
+// GroupComplex128 uses the specified grouper function to group the items
+// keyed by the return of the grouper.  The object contained in the
+// result will contain a map[string][]complex128.
+func (v *Value) GroupComplex128(grouper func(int, complex128) string) *Value {
+
+	groups := make(map[string][]complex128)
+
+	v.EachComplex128(func(index int, val complex128) bool {
+		group := grouper(index, val)
+		if _, ok := groups[group]; !ok {
+			groups[group] = make([]complex128, 0)
+		}
+		groups[group] = append(groups[group], val)
+		return true
+	})
+
+	return &Value{data: groups}
+
+}
+
+// ReplaceComplex128 uses the specified function to replace each complex128s
+// by iterating each item.  The data in the returned result will be a
+// []complex128 containing the replaced items.
+func (v *Value) ReplaceComplex128(replacer func(int, complex128) complex128) *Value {
+
+	arr := v.MustComplex128Slice()
+	replaced := make([]complex128, len(arr))
+
+	v.EachComplex128(func(index int, val complex128) bool {
+		replaced[index] = replacer(index, val)
+		return true
+	})
+
+	return &Value{data: replaced}
+
+}
+
+// CollectComplex128 uses the specified collector function to collect a value
+// for each of the complex128s in the slice.  The data returned will be a
+// []interface{}.
+func (v *Value) CollectComplex128(collector func(int, complex128) interface{}) *Value {
+
+	arr := v.MustComplex128Slice()
+	collected := make([]interface{}, len(arr))
+
+	v.EachComplex128(func(index int, val complex128) bool {
+		collected[index] = collector(index, val)
+		return true
+	})
+
+	return &Value{data: collected}
+}
diff --git a/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/value.go b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/value.go
new file mode 100644
index 0000000..7aaef06
--- /dev/null
+++ b/go/src/github.com/stretchr/testify/vendor/github.com/stretchr/objx/value.go
@@ -0,0 +1,13 @@
+package objx
+
+// Value provides methods for extracting interface{} data in various
+// types.
+type Value struct {
+	// data contains the raw data being managed by this Value
+	data interface{}
+}
+
+// Data returns the raw data contained by this Value
+func (v *Value) Data() interface{} {
+	return v.data
+}