diff --git a/vendor/github.com/google/go-cmp/LICENSE b/vendor/github.com/google/go-cmp/LICENSE
new file mode 100644
index 0000000..32017f8
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2017 The Go Authors. 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 Google Inc. 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/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go
new file mode 100644
index 0000000..c9a63ce
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/compare.go
@@ -0,0 +1,655 @@
+// Copyright 2017, 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.md file.
+
+// Package cmp determines equality of values.
+//
+// This package is intended to be a more powerful and safer alternative to
+// reflect.DeepEqual for comparing whether two values are semantically equal.
+//
+// The primary features of cmp are:
+//
+// • When the default behavior of equality does not suit the needs of the test,
+// custom equality functions can override the equality operation.
+// For example, an equality function may report floats as equal so long as they
+// are within some tolerance of each other.
+//
+// • Types that have an Equal method may use that method to determine equality.
+// This allows package authors to determine the equality operation for the types
+// that they define.
+//
+// • If no custom equality functions are used and no Equal method is defined,
+// equality is determined by recursively comparing the primitive kinds on both
+// values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported
+// fields are not compared by default; they result in panics unless suppressed
+// by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly
+// compared using the Exporter option.
+package cmp
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+
+	"github.com/google/go-cmp/cmp/internal/diff"
+	"github.com/google/go-cmp/cmp/internal/flags"
+	"github.com/google/go-cmp/cmp/internal/function"
+	"github.com/google/go-cmp/cmp/internal/value"
+)
+
+// Equal reports whether x and y are equal by recursively applying the
+// following rules in the given order to x and y and all of their sub-values:
+//
+// • Let S be the set of all Ignore, Transformer, and Comparer options that
+// remain after applying all path filters, value filters, and type filters.
+// If at least one Ignore exists in S, then the comparison is ignored.
+// If the number of Transformer and Comparer options in S is greater than one,
+// then Equal panics because it is ambiguous which option to use.
+// If S contains a single Transformer, then use that to transform the current
+// values and recursively call Equal on the output values.
+// If S contains a single Comparer, then use that to compare the current values.
+// Otherwise, evaluation proceeds to the next rule.
+//
+// • If the values have an Equal method of the form "(T) Equal(T) bool" or
+// "(T) Equal(I) bool" where T is assignable to I, then use the result of
+// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and
+// evaluation proceeds to the next rule.
+//
+// • Lastly, try to compare x and y based on their basic kinds.
+// Simple kinds like booleans, integers, floats, complex numbers, strings, and
+// channels are compared using the equivalent of the == operator in Go.
+// Functions are only equal if they are both nil, otherwise they are unequal.
+//
+// Structs are equal if recursively calling Equal on all fields report equal.
+// If a struct contains unexported fields, Equal panics unless an Ignore option
+// (e.g., cmpopts.IgnoreUnexported) ignores that field or the Exporter option
+// explicitly permits comparing the unexported field.
+//
+// Slices are equal if they are both nil or both non-nil, where recursively
+// calling Equal on all non-ignored slice or array elements report equal.
+// Empty non-nil slices and nil slices are not equal; to equate empty slices,
+// consider using cmpopts.EquateEmpty.
+//
+// Maps are equal if they are both nil or both non-nil, where recursively
+// calling Equal on all non-ignored map entries report equal.
+// Map keys are equal according to the == operator.
+// To use custom comparisons for map keys, consider using cmpopts.SortMaps.
+// Empty non-nil maps and nil maps are not equal; to equate empty maps,
+// consider using cmpopts.EquateEmpty.
+//
+// Pointers and interfaces are equal if they are both nil or both non-nil,
+// where they have the same underlying concrete type and recursively
+// calling Equal on the underlying values reports equal.
+//
+// Before recursing into a pointer, slice element, or map, the current path
+// is checked to detect whether the address has already been visited.
+// If there is a cycle, then the pointed at values are considered equal
+// only if both addresses were previously visited in the same path step.
+func Equal(x, y interface{}, opts ...Option) bool {
+	vx := reflect.ValueOf(x)
+	vy := reflect.ValueOf(y)
+
+	// If the inputs are different types, auto-wrap them in an empty interface
+	// so that they have the same parent type.
+	var t reflect.Type
+	if !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() {
+		t = reflect.TypeOf((*interface{})(nil)).Elem()
+		if vx.IsValid() {
+			vvx := reflect.New(t).Elem()
+			vvx.Set(vx)
+			vx = vvx
+		}
+		if vy.IsValid() {
+			vvy := reflect.New(t).Elem()
+			vvy.Set(vy)
+			vy = vvy
+		}
+	} else {
+		t = vx.Type()
+	}
+
+	s := newState(opts)
+	s.compareAny(&pathStep{t, vx, vy})
+	return s.result.Equal()
+}
+
+// Diff returns a human-readable report of the differences between two values.
+// It returns an empty string if and only if Equal returns true for the same
+// input values and options.
+//
+// The output is displayed as a literal in pseudo-Go syntax.
+// At the start of each line, a "-" prefix indicates an element removed from x,
+// a "+" prefix to indicates an element added to y, and the lack of a prefix
+// indicates an element common to both x and y. If possible, the output
+// uses fmt.Stringer.String or error.Error methods to produce more humanly
+// readable outputs. In such cases, the string is prefixed with either an
+// 's' or 'e' character, respectively, to indicate that the method was called.
+//
+// Do not depend on this output being stable. If you need the ability to
+// programmatically interpret the difference, consider using a custom Reporter.
+func Diff(x, y interface{}, opts ...Option) string {
+	r := new(defaultReporter)
+	eq := Equal(x, y, Options(opts), Reporter(r))
+	d := r.String()
+	if (d == "") != eq {
+		panic("inconsistent difference and equality results")
+	}
+	return d
+}
+
+type state struct {
+	// These fields represent the "comparison state".
+	// Calling statelessCompare must not result in observable changes to these.
+	result    diff.Result // The current result of comparison
+	curPath   Path        // The current path in the value tree
+	curPtrs   pointerPath // The current set of visited pointers
+	reporters []reporter  // Optional reporters
+
+	// recChecker checks for infinite cycles applying the same set of
+	// transformers upon the output of itself.
+	recChecker recChecker
+
+	// dynChecker triggers pseudo-random checks for option correctness.
+	// It is safe for statelessCompare to mutate this value.
+	dynChecker dynChecker
+
+	// These fields, once set by processOption, will not change.
+	exporters []exporter // List of exporters for structs with unexported fields
+	opts      Options    // List of all fundamental and filter options
+}
+
+func newState(opts []Option) *state {
+	// Always ensure a validator option exists to validate the inputs.
+	s := &state{opts: Options{validator{}}}
+	s.curPtrs.Init()
+	s.processOption(Options(opts))
+	return s
+}
+
+func (s *state) processOption(opt Option) {
+	switch opt := opt.(type) {
+	case nil:
+	case Options:
+		for _, o := range opt {
+			s.processOption(o)
+		}
+	case coreOption:
+		type filtered interface {
+			isFiltered() bool
+		}
+		if fopt, ok := opt.(filtered); ok && !fopt.isFiltered() {
+			panic(fmt.Sprintf("cannot use an unfiltered option: %v", opt))
+		}
+		s.opts = append(s.opts, opt)
+	case exporter:
+		s.exporters = append(s.exporters, opt)
+	case reporter:
+		s.reporters = append(s.reporters, opt)
+	default:
+		panic(fmt.Sprintf("unknown option %T", opt))
+	}
+}
+
+// statelessCompare compares two values and returns the result.
+// This function is stateless in that it does not alter the current result,
+// or output to any registered reporters.
+func (s *state) statelessCompare(step PathStep) diff.Result {
+	// We do not save and restore curPath and curPtrs because all of the
+	// compareX methods should properly push and pop from them.
+	// It is an implementation bug if the contents of the paths differ from
+	// when calling this function to when returning from it.
+
+	oldResult, oldReporters := s.result, s.reporters
+	s.result = diff.Result{} // Reset result
+	s.reporters = nil        // Remove reporters to avoid spurious printouts
+	s.compareAny(step)
+	res := s.result
+	s.result, s.reporters = oldResult, oldReporters
+	return res
+}
+
+func (s *state) compareAny(step PathStep) {
+	// Update the path stack.
+	s.curPath.push(step)
+	defer s.curPath.pop()
+	for _, r := range s.reporters {
+		r.PushStep(step)
+		defer r.PopStep()
+	}
+	s.recChecker.Check(s.curPath)
+
+	// Cycle-detection for slice elements (see NOTE in compareSlice).
+	t := step.Type()
+	vx, vy := step.Values()
+	if si, ok := step.(SliceIndex); ok && si.isSlice && vx.IsValid() && vy.IsValid() {
+		px, py := vx.Addr(), vy.Addr()
+		if eq, visited := s.curPtrs.Push(px, py); visited {
+			s.report(eq, reportByCycle)
+			return
+		}
+		defer s.curPtrs.Pop(px, py)
+	}
+
+	// Rule 1: Check whether an option applies on this node in the value tree.
+	if s.tryOptions(t, vx, vy) {
+		return
+	}
+
+	// Rule 2: Check whether the type has a valid Equal method.
+	if s.tryMethod(t, vx, vy) {
+		return
+	}
+
+	// Rule 3: Compare based on the underlying kind.
+	switch t.Kind() {
+	case reflect.Bool:
+		s.report(vx.Bool() == vy.Bool(), 0)
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		s.report(vx.Int() == vy.Int(), 0)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		s.report(vx.Uint() == vy.Uint(), 0)
+	case reflect.Float32, reflect.Float64:
+		s.report(vx.Float() == vy.Float(), 0)
+	case reflect.Complex64, reflect.Complex128:
+		s.report(vx.Complex() == vy.Complex(), 0)
+	case reflect.String:
+		s.report(vx.String() == vy.String(), 0)
+	case reflect.Chan, reflect.UnsafePointer:
+		s.report(vx.Pointer() == vy.Pointer(), 0)
+	case reflect.Func:
+		s.report(vx.IsNil() && vy.IsNil(), 0)
+	case reflect.Struct:
+		s.compareStruct(t, vx, vy)
+	case reflect.Slice, reflect.Array:
+		s.compareSlice(t, vx, vy)
+	case reflect.Map:
+		s.compareMap(t, vx, vy)
+	case reflect.Ptr:
+		s.comparePtr(t, vx, vy)
+	case reflect.Interface:
+		s.compareInterface(t, vx, vy)
+	default:
+		panic(fmt.Sprintf("%v kind not handled", t.Kind()))
+	}
+}
+
+func (s *state) tryOptions(t reflect.Type, vx, vy reflect.Value) bool {
+	// Evaluate all filters and apply the remaining options.
+	if opt := s.opts.filter(s, t, vx, vy); opt != nil {
+		opt.apply(s, vx, vy)
+		return true
+	}
+	return false
+}
+
+func (s *state) tryMethod(t reflect.Type, vx, vy reflect.Value) bool {
+	// Check if this type even has an Equal method.
+	m, ok := t.MethodByName("Equal")
+	if !ok || !function.IsType(m.Type, function.EqualAssignable) {
+		return false
+	}
+
+	eq := s.callTTBFunc(m.Func, vx, vy)
+	s.report(eq, reportByMethod)
+	return true
+}
+
+func (s *state) callTRFunc(f, v reflect.Value, step Transform) reflect.Value {
+	v = sanitizeValue(v, f.Type().In(0))
+	if !s.dynChecker.Next() {
+		return f.Call([]reflect.Value{v})[0]
+	}
+
+	// Run the function twice and ensure that we get the same results back.
+	// We run in goroutines so that the race detector (if enabled) can detect
+	// unsafe mutations to the input.
+	c := make(chan reflect.Value)
+	go detectRaces(c, f, v)
+	got := <-c
+	want := f.Call([]reflect.Value{v})[0]
+	if step.vx, step.vy = got, want; !s.statelessCompare(step).Equal() {
+		// To avoid false-positives with non-reflexive equality operations,
+		// we sanity check whether a value is equal to itself.
+		if step.vx, step.vy = want, want; !s.statelessCompare(step).Equal() {
+			return want
+		}
+		panic(fmt.Sprintf("non-deterministic function detected: %s", function.NameOf(f)))
+	}
+	return want
+}
+
+func (s *state) callTTBFunc(f, x, y reflect.Value) bool {
+	x = sanitizeValue(x, f.Type().In(0))
+	y = sanitizeValue(y, f.Type().In(1))
+	if !s.dynChecker.Next() {
+		return f.Call([]reflect.Value{x, y})[0].Bool()
+	}
+
+	// Swapping the input arguments is sufficient to check that
+	// f is symmetric and deterministic.
+	// We run in goroutines so that the race detector (if enabled) can detect
+	// unsafe mutations to the input.
+	c := make(chan reflect.Value)
+	go detectRaces(c, f, y, x)
+	got := <-c
+	want := f.Call([]reflect.Value{x, y})[0].Bool()
+	if !got.IsValid() || got.Bool() != want {
+		panic(fmt.Sprintf("non-deterministic or non-symmetric function detected: %s", function.NameOf(f)))
+	}
+	return want
+}
+
+func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) {
+	var ret reflect.Value
+	defer func() {
+		recover() // Ignore panics, let the other call to f panic instead
+		c <- ret
+	}()
+	ret = f.Call(vs)[0]
+}
+
+// sanitizeValue converts nil interfaces of type T to those of type R,
+// assuming that T is assignable to R.
+// Otherwise, it returns the input value as is.
+func sanitizeValue(v reflect.Value, t reflect.Type) reflect.Value {
+	// TODO(dsnet): Workaround for reflect bug (https://golang.org/issue/22143).
+	if !flags.AtLeastGo110 {
+		if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t {
+			return reflect.New(t).Elem()
+		}
+	}
+	return v
+}
+
+func (s *state) compareStruct(t reflect.Type, vx, vy reflect.Value) {
+	var vax, vay reflect.Value // Addressable versions of vx and vy
+
+	var mayForce, mayForceInit bool
+	step := StructField{&structField{}}
+	for i := 0; i < t.NumField(); i++ {
+		step.typ = t.Field(i).Type
+		step.vx = vx.Field(i)
+		step.vy = vy.Field(i)
+		step.name = t.Field(i).Name
+		step.idx = i
+		step.unexported = !isExported(step.name)
+		if step.unexported {
+			if step.name == "_" {
+				continue
+			}
+			// Defer checking of unexported fields until later to give an
+			// Ignore a chance to ignore the field.
+			if !vax.IsValid() || !vay.IsValid() {
+				// For retrieveUnexportedField to work, the parent struct must
+				// be addressable. Create a new copy of the values if
+				// necessary to make them addressable.
+				vax = makeAddressable(vx)
+				vay = makeAddressable(vy)
+			}
+			if !mayForceInit {
+				for _, xf := range s.exporters {
+					mayForce = mayForce || xf(t)
+				}
+				mayForceInit = true
+			}
+			step.mayForce = mayForce
+			step.pvx = vax
+			step.pvy = vay
+			step.field = t.Field(i)
+		}
+		s.compareAny(step)
+	}
+}
+
+func (s *state) compareSlice(t reflect.Type, vx, vy reflect.Value) {
+	isSlice := t.Kind() == reflect.Slice
+	if isSlice && (vx.IsNil() || vy.IsNil()) {
+		s.report(vx.IsNil() && vy.IsNil(), 0)
+		return
+	}
+
+	// NOTE: It is incorrect to call curPtrs.Push on the slice header pointer
+	// since slices represents a list of pointers, rather than a single pointer.
+	// The pointer checking logic must be handled on a per-element basis
+	// in compareAny.
+	//
+	// A slice header (see reflect.SliceHeader) in Go is a tuple of a starting
+	// pointer P, a length N, and a capacity C. Supposing each slice element has
+	// a memory size of M, then the slice is equivalent to the list of pointers:
+	//	[P+i*M for i in range(N)]
+	//
+	// For example, v[:0] and v[:1] are slices with the same starting pointer,
+	// but they are clearly different values. Using the slice pointer alone
+	// violates the assumption that equal pointers implies equal values.
+
+	step := SliceIndex{&sliceIndex{pathStep: pathStep{typ: t.Elem()}, isSlice: isSlice}}
+	withIndexes := func(ix, iy int) SliceIndex {
+		if ix >= 0 {
+			step.vx, step.xkey = vx.Index(ix), ix
+		} else {
+			step.vx, step.xkey = reflect.Value{}, -1
+		}
+		if iy >= 0 {
+			step.vy, step.ykey = vy.Index(iy), iy
+		} else {
+			step.vy, step.ykey = reflect.Value{}, -1
+		}
+		return step
+	}
+
+	// Ignore options are able to ignore missing elements in a slice.
+	// However, detecting these reliably requires an optimal differencing
+	// algorithm, for which diff.Difference is not.
+	//
+	// Instead, we first iterate through both slices to detect which elements
+	// would be ignored if standing alone. The index of non-discarded elements
+	// are stored in a separate slice, which diffing is then performed on.
+	var indexesX, indexesY []int
+	var ignoredX, ignoredY []bool
+	for ix := 0; ix < vx.Len(); ix++ {
+		ignored := s.statelessCompare(withIndexes(ix, -1)).NumDiff == 0
+		if !ignored {
+			indexesX = append(indexesX, ix)
+		}
+		ignoredX = append(ignoredX, ignored)
+	}
+	for iy := 0; iy < vy.Len(); iy++ {
+		ignored := s.statelessCompare(withIndexes(-1, iy)).NumDiff == 0
+		if !ignored {
+			indexesY = append(indexesY, iy)
+		}
+		ignoredY = append(ignoredY, ignored)
+	}
+
+	// Compute an edit-script for slices vx and vy (excluding ignored elements).
+	edits := diff.Difference(len(indexesX), len(indexesY), func(ix, iy int) diff.Result {
+		return s.statelessCompare(withIndexes(indexesX[ix], indexesY[iy]))
+	})
+
+	// Replay the ignore-scripts and the edit-script.
+	var ix, iy int
+	for ix < vx.Len() || iy < vy.Len() {
+		var e diff.EditType
+		switch {
+		case ix < len(ignoredX) && ignoredX[ix]:
+			e = diff.UniqueX
+		case iy < len(ignoredY) && ignoredY[iy]:
+			e = diff.UniqueY
+		default:
+			e, edits = edits[0], edits[1:]
+		}
+		switch e {
+		case diff.UniqueX:
+			s.compareAny(withIndexes(ix, -1))
+			ix++
+		case diff.UniqueY:
+			s.compareAny(withIndexes(-1, iy))
+			iy++
+		default:
+			s.compareAny(withIndexes(ix, iy))
+			ix++
+			iy++
+		}
+	}
+}
+
+func (s *state) compareMap(t reflect.Type, vx, vy reflect.Value) {
+	if vx.IsNil() || vy.IsNil() {
+		s.report(vx.IsNil() && vy.IsNil(), 0)
+		return
+	}
+
+	// Cycle-detection for maps.
+	if eq, visited := s.curPtrs.Push(vx, vy); visited {
+		s.report(eq, reportByCycle)
+		return
+	}
+	defer s.curPtrs.Pop(vx, vy)
+
+	// We combine and sort the two map keys so that we can perform the
+	// comparisons in a deterministic order.
+	step := MapIndex{&mapIndex{pathStep: pathStep{typ: t.Elem()}}}
+	for _, k := range value.SortKeys(append(vx.MapKeys(), vy.MapKeys()...)) {
+		step.vx = vx.MapIndex(k)
+		step.vy = vy.MapIndex(k)
+		step.key = k
+		if !step.vx.IsValid() && !step.vy.IsValid() {
+			// It is possible for both vx and vy to be invalid if the
+			// key contained a NaN value in it.
+			//
+			// Even with the ability to retrieve NaN keys in Go 1.12,
+			// there still isn't a sensible way to compare the values since
+			// a NaN key may map to multiple unordered values.
+			// The most reasonable way to compare NaNs would be to compare the
+			// set of values. However, this is impossible to do efficiently
+			// since set equality is provably an O(n^2) operation given only
+			// an Equal function. If we had a Less function or Hash function,
+			// this could be done in O(n*log(n)) or O(n), respectively.
+			//
+			// Rather than adding complex logic to deal with NaNs, make it
+			// the user's responsibility to compare such obscure maps.
+			const help = "consider providing a Comparer to compare the map"
+			panic(fmt.Sprintf("%#v has map key with NaNs\n%s", s.curPath, help))
+		}
+		s.compareAny(step)
+	}
+}
+
+func (s *state) comparePtr(t reflect.Type, vx, vy reflect.Value) {
+	if vx.IsNil() || vy.IsNil() {
+		s.report(vx.IsNil() && vy.IsNil(), 0)
+		return
+	}
+
+	// Cycle-detection for pointers.
+	if eq, visited := s.curPtrs.Push(vx, vy); visited {
+		s.report(eq, reportByCycle)
+		return
+	}
+	defer s.curPtrs.Pop(vx, vy)
+
+	vx, vy = vx.Elem(), vy.Elem()
+	s.compareAny(Indirect{&indirect{pathStep{t.Elem(), vx, vy}}})
+}
+
+func (s *state) compareInterface(t reflect.Type, vx, vy reflect.Value) {
+	if vx.IsNil() || vy.IsNil() {
+		s.report(vx.IsNil() && vy.IsNil(), 0)
+		return
+	}
+	vx, vy = vx.Elem(), vy.Elem()
+	if vx.Type() != vy.Type() {
+		s.report(false, 0)
+		return
+	}
+	s.compareAny(TypeAssertion{&typeAssertion{pathStep{vx.Type(), vx, vy}}})
+}
+
+func (s *state) report(eq bool, rf resultFlags) {
+	if rf&reportByIgnore == 0 {
+		if eq {
+			s.result.NumSame++
+			rf |= reportEqual
+		} else {
+			s.result.NumDiff++
+			rf |= reportUnequal
+		}
+	}
+	for _, r := range s.reporters {
+		r.Report(Result{flags: rf})
+	}
+}
+
+// recChecker tracks the state needed to periodically perform checks that
+// user provided transformers are not stuck in an infinitely recursive cycle.
+type recChecker struct{ next int }
+
+// Check scans the Path for any recursive transformers and panics when any
+// recursive transformers are detected. Note that the presence of a
+// recursive Transformer does not necessarily imply an infinite cycle.
+// As such, this check only activates after some minimal number of path steps.
+func (rc *recChecker) Check(p Path) {
+	const minLen = 1 << 16
+	if rc.next == 0 {
+		rc.next = minLen
+	}
+	if len(p) < rc.next {
+		return
+	}
+	rc.next <<= 1
+
+	// Check whether the same transformer has appeared at least twice.
+	var ss []string
+	m := map[Option]int{}
+	for _, ps := range p {
+		if t, ok := ps.(Transform); ok {
+			t := t.Option()
+			if m[t] == 1 { // Transformer was used exactly once before
+				tf := t.(*transformer).fnc.Type()
+				ss = append(ss, fmt.Sprintf("%v: %v => %v", t, tf.In(0), tf.Out(0)))
+			}
+			m[t]++
+		}
+	}
+	if len(ss) > 0 {
+		const warning = "recursive set of Transformers detected"
+		const help = "consider using cmpopts.AcyclicTransformer"
+		set := strings.Join(ss, "\n\t")
+		panic(fmt.Sprintf("%s:\n\t%s\n%s", warning, set, help))
+	}
+}
+
+// dynChecker tracks the state needed to periodically perform checks that
+// user provided functions are symmetric and deterministic.
+// The zero value is safe for immediate use.
+type dynChecker struct{ curr, next int }
+
+// Next increments the state and reports whether a check should be performed.
+//
+// Checks occur every Nth function call, where N is a triangular number:
+//	0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ...
+// See https://en.wikipedia.org/wiki/Triangular_number
+//
+// This sequence ensures that the cost of checks drops significantly as
+// the number of functions calls grows larger.
+func (dc *dynChecker) Next() bool {
+	ok := dc.curr == dc.next
+	if ok {
+		dc.curr = 0
+		dc.next++
+	}
+	dc.curr++
+	return ok
+}
+
+// makeAddressable returns a value that is always addressable.
+// It returns the input verbatim if it is already addressable,
+// otherwise it creates a new value and returns an addressable copy.
+func makeAddressable(v reflect.Value) reflect.Value {
+	if v.CanAddr() {
+		return v
+	}
+	vc := reflect.New(v.Type()).Elem()
+	vc.Set(v)
+	return vc
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/export_panic.go b/vendor/github.com/google/go-cmp/cmp/export_panic.go
new file mode 100644
index 0000000..dd03235
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/export_panic.go
@@ -0,0 +1,15 @@
+// Copyright 2017, 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.md file.
+
+// +build purego
+
+package cmp
+
+import "reflect"
+
+const supportExporters = false
+
+func retrieveUnexportedField(reflect.Value, reflect.StructField) reflect.Value {
+	panic("no support for forcibly accessing unexported fields")
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/export_unsafe.go b/vendor/github.com/google/go-cmp/cmp/export_unsafe.go
new file mode 100644
index 0000000..57020e2
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/export_unsafe.go
@@ -0,0 +1,25 @@
+// Copyright 2017, 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.md file.
+
+// +build !purego
+
+package cmp
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+const supportExporters = true
+
+// retrieveUnexportedField uses unsafe to forcibly retrieve any field from
+// a struct such that the value has read-write permissions.
+//
+// The parent struct, v, must be addressable, while f must be a StructField
+// describing the field to retrieve.
+func retrieveUnexportedField(v reflect.Value, f reflect.StructField) reflect.Value {
+	// See https://github.com/google/go-cmp/issues/167 for discussion of the
+	// following expression.
+	return reflect.NewAt(f.Type, unsafe.Pointer(uintptr(unsafe.Pointer(v.UnsafeAddr()))+f.Offset)).Elem()
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
new file mode 100644
index 0000000..fe98dcc
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
@@ -0,0 +1,17 @@
+// Copyright 2017, 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.md file.
+
+// +build !cmp_debug
+
+package diff
+
+var debug debugger
+
+type debugger struct{}
+
+func (debugger) Begin(_, _ int, f EqualFunc, _, _ *EditScript) EqualFunc {
+	return f
+}
+func (debugger) Update() {}
+func (debugger) Finish() {}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
new file mode 100644
index 0000000..597b6ae
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
@@ -0,0 +1,122 @@
+// Copyright 2017, 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.md file.
+
+// +build cmp_debug
+
+package diff
+
+import (
+	"fmt"
+	"strings"
+	"sync"
+	"time"
+)
+
+// The algorithm can be seen running in real-time by enabling debugging:
+//	go test -tags=cmp_debug -v
+//
+// Example output:
+//	=== RUN   TestDifference/#34
+//	┌───────────────────────────────┐
+//	│ \ · · · · · · · · · · · · · · │
+//	│ · # · · · · · · · · · · · · · │
+//	│ · \ · · · · · · · · · · · · · │
+//	│ · · \ · · · · · · · · · · · · │
+//	│ · · · X # · · · · · · · · · · │
+//	│ · · · # \ · · · · · · · · · · │
+//	│ · · · · · # # · · · · · · · · │
+//	│ · · · · · # \ · · · · · · · · │
+//	│ · · · · · · · \ · · · · · · · │
+//	│ · · · · · · · · \ · · · · · · │
+//	│ · · · · · · · · · \ · · · · · │
+//	│ · · · · · · · · · · \ · · # · │
+//	│ · · · · · · · · · · · \ # # · │
+//	│ · · · · · · · · · · · # # # · │
+//	│ · · · · · · · · · · # # # # · │
+//	│ · · · · · · · · · # # # # # · │
+//	│ · · · · · · · · · · · · · · \ │
+//	└───────────────────────────────┘
+//	[.Y..M.XY......YXYXY.|]
+//
+// The grid represents the edit-graph where the horizontal axis represents
+// list X and the vertical axis represents list Y. The start of the two lists
+// is the top-left, while the ends are the bottom-right. The '·' represents
+// an unexplored node in the graph. The '\' indicates that the two symbols
+// from list X and Y are equal. The 'X' indicates that two symbols are similar
+// (but not exactly equal) to each other. The '#' indicates that the two symbols
+// are different (and not similar). The algorithm traverses this graph trying to
+// make the paths starting in the top-left and the bottom-right connect.
+//
+// The series of '.', 'X', 'Y', and 'M' characters at the bottom represents
+// the currently established path from the forward and reverse searches,
+// separated by a '|' character.
+
+const (
+	updateDelay  = 100 * time.Millisecond
+	finishDelay  = 500 * time.Millisecond
+	ansiTerminal = true // ANSI escape codes used to move terminal cursor
+)
+
+var debug debugger
+
+type debugger struct {
+	sync.Mutex
+	p1, p2           EditScript
+	fwdPath, revPath *EditScript
+	grid             []byte
+	lines            int
+}
+
+func (dbg *debugger) Begin(nx, ny int, f EqualFunc, p1, p2 *EditScript) EqualFunc {
+	dbg.Lock()
+	dbg.fwdPath, dbg.revPath = p1, p2
+	top := "┌─" + strings.Repeat("──", nx) + "┐\n"
+	row := "│ " + strings.Repeat("· ", nx) + "│\n"
+	btm := "└─" + strings.Repeat("──", nx) + "┘\n"
+	dbg.grid = []byte(top + strings.Repeat(row, ny) + btm)
+	dbg.lines = strings.Count(dbg.String(), "\n")
+	fmt.Print(dbg)
+
+	// Wrap the EqualFunc so that we can intercept each result.
+	return func(ix, iy int) (r Result) {
+		cell := dbg.grid[len(top)+iy*len(row):][len("│ ")+len("· ")*ix:][:len("·")]
+		for i := range cell {
+			cell[i] = 0 // Zero out the multiple bytes of UTF-8 middle-dot
+		}
+		switch r = f(ix, iy); {
+		case r.Equal():
+			cell[0] = '\\'
+		case r.Similar():
+			cell[0] = 'X'
+		default:
+			cell[0] = '#'
+		}
+		return
+	}
+}
+
+func (dbg *debugger) Update() {
+	dbg.print(updateDelay)
+}
+
+func (dbg *debugger) Finish() {
+	dbg.print(finishDelay)
+	dbg.Unlock()
+}
+
+func (dbg *debugger) String() string {
+	dbg.p1, dbg.p2 = *dbg.fwdPath, dbg.p2[:0]
+	for i := len(*dbg.revPath) - 1; i >= 0; i-- {
+		dbg.p2 = append(dbg.p2, (*dbg.revPath)[i])
+	}
+	return fmt.Sprintf("%s[%v|%v]\n\n", dbg.grid, dbg.p1, dbg.p2)
+}
+
+func (dbg *debugger) print(d time.Duration) {
+	if ansiTerminal {
+		fmt.Printf("\x1b[%dA", dbg.lines) // Reset terminal cursor
+	}
+	fmt.Print(dbg)
+	time.Sleep(d)
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
new file mode 100644
index 0000000..3d2e426
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
@@ -0,0 +1,372 @@
+// Copyright 2017, 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.md file.
+
+// Package diff implements an algorithm for producing edit-scripts.
+// The edit-script is a sequence of operations needed to transform one list
+// of symbols into another (or vice-versa). The edits allowed are insertions,
+// deletions, and modifications. The summation of all edits is called the
+// Levenshtein distance as this problem is well-known in computer science.
+//
+// This package prioritizes performance over accuracy. That is, the run time
+// is more important than obtaining a minimal Levenshtein distance.
+package diff
+
+// EditType represents a single operation within an edit-script.
+type EditType uint8
+
+const (
+	// Identity indicates that a symbol pair is identical in both list X and Y.
+	Identity EditType = iota
+	// UniqueX indicates that a symbol only exists in X and not Y.
+	UniqueX
+	// UniqueY indicates that a symbol only exists in Y and not X.
+	UniqueY
+	// Modified indicates that a symbol pair is a modification of each other.
+	Modified
+)
+
+// EditScript represents the series of differences between two lists.
+type EditScript []EditType
+
+// String returns a human-readable string representing the edit-script where
+// Identity, UniqueX, UniqueY, and Modified are represented by the
+// '.', 'X', 'Y', and 'M' characters, respectively.
+func (es EditScript) String() string {
+	b := make([]byte, len(es))
+	for i, e := range es {
+		switch e {
+		case Identity:
+			b[i] = '.'
+		case UniqueX:
+			b[i] = 'X'
+		case UniqueY:
+			b[i] = 'Y'
+		case Modified:
+			b[i] = 'M'
+		default:
+			panic("invalid edit-type")
+		}
+	}
+	return string(b)
+}
+
+// stats returns a histogram of the number of each type of edit operation.
+func (es EditScript) stats() (s struct{ NI, NX, NY, NM int }) {
+	for _, e := range es {
+		switch e {
+		case Identity:
+			s.NI++
+		case UniqueX:
+			s.NX++
+		case UniqueY:
+			s.NY++
+		case Modified:
+			s.NM++
+		default:
+			panic("invalid edit-type")
+		}
+	}
+	return
+}
+
+// Dist is the Levenshtein distance and is guaranteed to be 0 if and only if
+// lists X and Y are equal.
+func (es EditScript) Dist() int { return len(es) - es.stats().NI }
+
+// LenX is the length of the X list.
+func (es EditScript) LenX() int { return len(es) - es.stats().NY }
+
+// LenY is the length of the Y list.
+func (es EditScript) LenY() int { return len(es) - es.stats().NX }
+
+// EqualFunc reports whether the symbols at indexes ix and iy are equal.
+// When called by Difference, the index is guaranteed to be within nx and ny.
+type EqualFunc func(ix int, iy int) Result
+
+// Result is the result of comparison.
+// NumSame is the number of sub-elements that are equal.
+// NumDiff is the number of sub-elements that are not equal.
+type Result struct{ NumSame, NumDiff int }
+
+// BoolResult returns a Result that is either Equal or not Equal.
+func BoolResult(b bool) Result {
+	if b {
+		return Result{NumSame: 1} // Equal, Similar
+	} else {
+		return Result{NumDiff: 2} // Not Equal, not Similar
+	}
+}
+
+// Equal indicates whether the symbols are equal. Two symbols are equal
+// if and only if NumDiff == 0. If Equal, then they are also Similar.
+func (r Result) Equal() bool { return r.NumDiff == 0 }
+
+// Similar indicates whether two symbols are similar and may be represented
+// by using the Modified type. As a special case, we consider binary comparisons
+// (i.e., those that return Result{1, 0} or Result{0, 1}) to be similar.
+//
+// The exact ratio of NumSame to NumDiff to determine similarity may change.
+func (r Result) Similar() bool {
+	// Use NumSame+1 to offset NumSame so that binary comparisons are similar.
+	return r.NumSame+1 >= r.NumDiff
+}
+
+// Difference reports whether two lists of lengths nx and ny are equal
+// given the definition of equality provided as f.
+//
+// This function returns an edit-script, which is a sequence of operations
+// needed to convert one list into the other. The following invariants for
+// the edit-script are maintained:
+//	• eq == (es.Dist()==0)
+//	• nx == es.LenX()
+//	• ny == es.LenY()
+//
+// This algorithm is not guaranteed to be an optimal solution (i.e., one that
+// produces an edit-script with a minimal Levenshtein distance). This algorithm
+// favors performance over optimality. The exact output is not guaranteed to
+// be stable and may change over time.
+func Difference(nx, ny int, f EqualFunc) (es EditScript) {
+	// This algorithm is based on traversing what is known as an "edit-graph".
+	// See Figure 1 from "An O(ND) Difference Algorithm and Its Variations"
+	// by Eugene W. Myers. Since D can be as large as N itself, this is
+	// effectively O(N^2). Unlike the algorithm from that paper, we are not
+	// interested in the optimal path, but at least some "decent" path.
+	//
+	// For example, let X and Y be lists of symbols:
+	//	X = [A B C A B B A]
+	//	Y = [C B A B A C]
+	//
+	// The edit-graph can be drawn as the following:
+	//	   A B C A B B A
+	//	  ┌─────────────┐
+	//	C │_|_|\|_|_|_|_│ 0
+	//	B │_|\|_|_|\|\|_│ 1
+	//	A │\|_|_|\|_|_|\│ 2
+	//	B │_|\|_|_|\|\|_│ 3
+	//	A │\|_|_|\|_|_|\│ 4
+	//	C │ | |\| | | | │ 5
+	//	  └─────────────┘ 6
+	//	   0 1 2 3 4 5 6 7
+	//
+	// List X is written along the horizontal axis, while list Y is written
+	// along the vertical axis. At any point on this grid, if the symbol in
+	// list X matches the corresponding symbol in list Y, then a '\' is drawn.
+	// The goal of any minimal edit-script algorithm is to find a path from the
+	// top-left corner to the bottom-right corner, while traveling through the
+	// fewest horizontal or vertical edges.
+	// A horizontal edge is equivalent to inserting a symbol from list X.
+	// A vertical edge is equivalent to inserting a symbol from list Y.
+	// A diagonal edge is equivalent to a matching symbol between both X and Y.
+
+	// Invariants:
+	//	• 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx
+	//	• 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny
+	//
+	// In general:
+	//	• fwdFrontier.X < revFrontier.X
+	//	• fwdFrontier.Y < revFrontier.Y
+	// Unless, it is time for the algorithm to terminate.
+	fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)}
+	revPath := path{-1, point{nx, ny}, make(EditScript, 0)}
+	fwdFrontier := fwdPath.point // Forward search frontier
+	revFrontier := revPath.point // Reverse search frontier
+
+	// Search budget bounds the cost of searching for better paths.
+	// The longest sequence of non-matching symbols that can be tolerated is
+	// approximately the square-root of the search budget.
+	searchBudget := 4 * (nx + ny) // O(n)
+
+	// The algorithm below is a greedy, meet-in-the-middle algorithm for
+	// computing sub-optimal edit-scripts between two lists.
+	//
+	// The algorithm is approximately as follows:
+	//	• Searching for differences switches back-and-forth between
+	//	a search that starts at the beginning (the top-left corner), and
+	//	a search that starts at the end (the bottom-right corner). The goal of
+	//	the search is connect with the search from the opposite corner.
+	//	• As we search, we build a path in a greedy manner, where the first
+	//	match seen is added to the path (this is sub-optimal, but provides a
+	//	decent result in practice). When matches are found, we try the next pair
+	//	of symbols in the lists and follow all matches as far as possible.
+	//	• When searching for matches, we search along a diagonal going through
+	//	through the "frontier" point. If no matches are found, we advance the
+	//	frontier towards the opposite corner.
+	//	• This algorithm terminates when either the X coordinates or the
+	//	Y coordinates of the forward and reverse frontier points ever intersect.
+	//
+	// This algorithm is correct even if searching only in the forward direction
+	// or in the reverse direction. We do both because it is commonly observed
+	// that two lists commonly differ because elements were added to the front
+	// or end of the other list.
+	//
+	// Running the tests with the "cmp_debug" build tag prints a visualization
+	// of the algorithm running in real-time. This is educational for
+	// understanding how the algorithm works. See debug_enable.go.
+	f = debug.Begin(nx, ny, f, &fwdPath.es, &revPath.es)
+	for {
+		// Forward search from the beginning.
+		if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 {
+			break
+		}
+		for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ {
+			// Search in a diagonal pattern for a match.
+			z := zigzag(i)
+			p := point{fwdFrontier.X + z, fwdFrontier.Y - z}
+			switch {
+			case p.X >= revPath.X || p.Y < fwdPath.Y:
+				stop1 = true // Hit top-right corner
+			case p.Y >= revPath.Y || p.X < fwdPath.X:
+				stop2 = true // Hit bottom-left corner
+			case f(p.X, p.Y).Equal():
+				// Match found, so connect the path to this point.
+				fwdPath.connect(p, f)
+				fwdPath.append(Identity)
+				// Follow sequence of matches as far as possible.
+				for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y {
+					if !f(fwdPath.X, fwdPath.Y).Equal() {
+						break
+					}
+					fwdPath.append(Identity)
+				}
+				fwdFrontier = fwdPath.point
+				stop1, stop2 = true, true
+			default:
+				searchBudget-- // Match not found
+			}
+			debug.Update()
+		}
+		// Advance the frontier towards reverse point.
+		if revPath.X-fwdFrontier.X >= revPath.Y-fwdFrontier.Y {
+			fwdFrontier.X++
+		} else {
+			fwdFrontier.Y++
+		}
+
+		// Reverse search from the end.
+		if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 {
+			break
+		}
+		for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ {
+			// Search in a diagonal pattern for a match.
+			z := zigzag(i)
+			p := point{revFrontier.X - z, revFrontier.Y + z}
+			switch {
+			case fwdPath.X >= p.X || revPath.Y < p.Y:
+				stop1 = true // Hit bottom-left corner
+			case fwdPath.Y >= p.Y || revPath.X < p.X:
+				stop2 = true // Hit top-right corner
+			case f(p.X-1, p.Y-1).Equal():
+				// Match found, so connect the path to this point.
+				revPath.connect(p, f)
+				revPath.append(Identity)
+				// Follow sequence of matches as far as possible.
+				for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y {
+					if !f(revPath.X-1, revPath.Y-1).Equal() {
+						break
+					}
+					revPath.append(Identity)
+				}
+				revFrontier = revPath.point
+				stop1, stop2 = true, true
+			default:
+				searchBudget-- // Match not found
+			}
+			debug.Update()
+		}
+		// Advance the frontier towards forward point.
+		if revFrontier.X-fwdPath.X >= revFrontier.Y-fwdPath.Y {
+			revFrontier.X--
+		} else {
+			revFrontier.Y--
+		}
+	}
+
+	// Join the forward and reverse paths and then append the reverse path.
+	fwdPath.connect(revPath.point, f)
+	for i := len(revPath.es) - 1; i >= 0; i-- {
+		t := revPath.es[i]
+		revPath.es = revPath.es[:i]
+		fwdPath.append(t)
+	}
+	debug.Finish()
+	return fwdPath.es
+}
+
+type path struct {
+	dir   int // +1 if forward, -1 if reverse
+	point     // Leading point of the EditScript path
+	es    EditScript
+}
+
+// connect appends any necessary Identity, Modified, UniqueX, or UniqueY types
+// to the edit-script to connect p.point to dst.
+func (p *path) connect(dst point, f EqualFunc) {
+	if p.dir > 0 {
+		// Connect in forward direction.
+		for dst.X > p.X && dst.Y > p.Y {
+			switch r := f(p.X, p.Y); {
+			case r.Equal():
+				p.append(Identity)
+			case r.Similar():
+				p.append(Modified)
+			case dst.X-p.X >= dst.Y-p.Y:
+				p.append(UniqueX)
+			default:
+				p.append(UniqueY)
+			}
+		}
+		for dst.X > p.X {
+			p.append(UniqueX)
+		}
+		for dst.Y > p.Y {
+			p.append(UniqueY)
+		}
+	} else {
+		// Connect in reverse direction.
+		for p.X > dst.X && p.Y > dst.Y {
+			switch r := f(p.X-1, p.Y-1); {
+			case r.Equal():
+				p.append(Identity)
+			case r.Similar():
+				p.append(Modified)
+			case p.Y-dst.Y >= p.X-dst.X:
+				p.append(UniqueY)
+			default:
+				p.append(UniqueX)
+			}
+		}
+		for p.X > dst.X {
+			p.append(UniqueX)
+		}
+		for p.Y > dst.Y {
+			p.append(UniqueY)
+		}
+	}
+}
+
+func (p *path) append(t EditType) {
+	p.es = append(p.es, t)
+	switch t {
+	case Identity, Modified:
+		p.add(p.dir, p.dir)
+	case UniqueX:
+		p.add(p.dir, 0)
+	case UniqueY:
+		p.add(0, p.dir)
+	}
+	debug.Update()
+}
+
+type point struct{ X, Y int }
+
+func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy }
+
+// zigzag maps a consecutive sequence of integers to a zig-zag sequence.
+//	[0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...]
+func zigzag(x int) int {
+	if x&1 != 0 {
+		x = ^x
+	}
+	return x >> 1
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go
new file mode 100644
index 0000000..a9e7fc0
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go
@@ -0,0 +1,9 @@
+// Copyright 2019, 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.md file.
+
+package flags
+
+// Deterministic controls whether the output of Diff should be deterministic.
+// This is only used for testing.
+var Deterministic bool
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go
new file mode 100644
index 0000000..01aed0a
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go
@@ -0,0 +1,10 @@
+// Copyright 2019, 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.md file.
+
+// +build !go1.10
+
+package flags
+
+// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10.
+const AtLeastGo110 = false
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go
new file mode 100644
index 0000000..c0b667f
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go
@@ -0,0 +1,10 @@
+// Copyright 2019, 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.md file.
+
+// +build go1.10
+
+package flags
+
+// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10.
+const AtLeastGo110 = true
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/function/func.go b/vendor/github.com/google/go-cmp/cmp/internal/function/func.go
new file mode 100644
index 0000000..ace1dbe
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/function/func.go
@@ -0,0 +1,99 @@
+// Copyright 2017, 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.md file.
+
+// Package function provides functionality for identifying function types.
+package function
+
+import (
+	"reflect"
+	"regexp"
+	"runtime"
+	"strings"
+)
+
+type funcType int
+
+const (
+	_ funcType = iota
+
+	tbFunc  // func(T) bool
+	ttbFunc // func(T, T) bool
+	trbFunc // func(T, R) bool
+	tibFunc // func(T, I) bool
+	trFunc  // func(T) R
+
+	Equal             = ttbFunc // func(T, T) bool
+	EqualAssignable   = tibFunc // func(T, I) bool; encapsulates func(T, T) bool
+	Transformer       = trFunc  // func(T) R
+	ValueFilter       = ttbFunc // func(T, T) bool
+	Less              = ttbFunc // func(T, T) bool
+	ValuePredicate    = tbFunc  // func(T) bool
+	KeyValuePredicate = trbFunc // func(T, R) bool
+)
+
+var boolType = reflect.TypeOf(true)
+
+// IsType reports whether the reflect.Type is of the specified function type.
+func IsType(t reflect.Type, ft funcType) bool {
+	if t == nil || t.Kind() != reflect.Func || t.IsVariadic() {
+		return false
+	}
+	ni, no := t.NumIn(), t.NumOut()
+	switch ft {
+	case tbFunc: // func(T) bool
+		if ni == 1 && no == 1 && t.Out(0) == boolType {
+			return true
+		}
+	case ttbFunc: // func(T, T) bool
+		if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType {
+			return true
+		}
+	case trbFunc: // func(T, R) bool
+		if ni == 2 && no == 1 && t.Out(0) == boolType {
+			return true
+		}
+	case tibFunc: // func(T, I) bool
+		if ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType {
+			return true
+		}
+	case trFunc: // func(T) R
+		if ni == 1 && no == 1 {
+			return true
+		}
+	}
+	return false
+}
+
+var lastIdentRx = regexp.MustCompile(`[_\p{L}][_\p{L}\p{N}]*$`)
+
+// NameOf returns the name of the function value.
+func NameOf(v reflect.Value) string {
+	fnc := runtime.FuncForPC(v.Pointer())
+	if fnc == nil {
+		return "<unknown>"
+	}
+	fullName := fnc.Name() // e.g., "long/path/name/mypkg.(*MyType).(long/path/name/mypkg.myMethod)-fm"
+
+	// Method closures have a "-fm" suffix.
+	fullName = strings.TrimSuffix(fullName, "-fm")
+
+	var name string
+	for len(fullName) > 0 {
+		inParen := strings.HasSuffix(fullName, ")")
+		fullName = strings.TrimSuffix(fullName, ")")
+
+		s := lastIdentRx.FindString(fullName)
+		if s == "" {
+			break
+		}
+		name = s + "." + name
+		fullName = strings.TrimSuffix(fullName, s)
+
+		if i := strings.LastIndexByte(fullName, '('); inParen && i >= 0 {
+			fullName = fullName[:i]
+		}
+		fullName = strings.TrimSuffix(fullName, ".")
+	}
+	return strings.TrimSuffix(name, ".")
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go
new file mode 100644
index 0000000..0a01c47
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go
@@ -0,0 +1,23 @@
+// Copyright 2018, 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.md file.
+
+// +build purego
+
+package value
+
+import "reflect"
+
+// Pointer is an opaque typed pointer and is guaranteed to be comparable.
+type Pointer struct {
+	p uintptr
+	t reflect.Type
+}
+
+// PointerOf returns a Pointer from v, which must be a
+// reflect.Ptr, reflect.Slice, or reflect.Map.
+func PointerOf(v reflect.Value) Pointer {
+	// NOTE: Storing a pointer as an uintptr is technically incorrect as it
+	// assumes that the GC implementation does not use a moving collector.
+	return Pointer{v.Pointer(), v.Type()}
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go
new file mode 100644
index 0000000..da134ae
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go
@@ -0,0 +1,26 @@
+// Copyright 2018, 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.md file.
+
+// +build !purego
+
+package value
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+// Pointer is an opaque typed pointer and is guaranteed to be comparable.
+type Pointer struct {
+	p unsafe.Pointer
+	t reflect.Type
+}
+
+// PointerOf returns a Pointer from v, which must be a
+// reflect.Ptr, reflect.Slice, or reflect.Map.
+func PointerOf(v reflect.Value) Pointer {
+	// The proper representation of a pointer is unsafe.Pointer,
+	// which is necessary if the GC ever uses a moving collector.
+	return Pointer{unsafe.Pointer(v.Pointer()), v.Type()}
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go b/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
new file mode 100644
index 0000000..24fbae6
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
@@ -0,0 +1,106 @@
+// Copyright 2017, 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.md file.
+
+package value
+
+import (
+	"fmt"
+	"math"
+	"reflect"
+	"sort"
+)
+
+// SortKeys sorts a list of map keys, deduplicating keys if necessary.
+// The type of each value must be comparable.
+func SortKeys(vs []reflect.Value) []reflect.Value {
+	if len(vs) == 0 {
+		return vs
+	}
+
+	// Sort the map keys.
+	sort.SliceStable(vs, func(i, j int) bool { return isLess(vs[i], vs[j]) })
+
+	// Deduplicate keys (fails for NaNs).
+	vs2 := vs[:1]
+	for _, v := range vs[1:] {
+		if isLess(vs2[len(vs2)-1], v) {
+			vs2 = append(vs2, v)
+		}
+	}
+	return vs2
+}
+
+// isLess is a generic function for sorting arbitrary map keys.
+// The inputs must be of the same type and must be comparable.
+func isLess(x, y reflect.Value) bool {
+	switch x.Type().Kind() {
+	case reflect.Bool:
+		return !x.Bool() && y.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return x.Int() < y.Int()
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return x.Uint() < y.Uint()
+	case reflect.Float32, reflect.Float64:
+		// NOTE: This does not sort -0 as less than +0
+		// since Go maps treat -0 and +0 as equal keys.
+		fx, fy := x.Float(), y.Float()
+		return fx < fy || math.IsNaN(fx) && !math.IsNaN(fy)
+	case reflect.Complex64, reflect.Complex128:
+		cx, cy := x.Complex(), y.Complex()
+		rx, ix, ry, iy := real(cx), imag(cx), real(cy), imag(cy)
+		if rx == ry || (math.IsNaN(rx) && math.IsNaN(ry)) {
+			return ix < iy || math.IsNaN(ix) && !math.IsNaN(iy)
+		}
+		return rx < ry || math.IsNaN(rx) && !math.IsNaN(ry)
+	case reflect.Ptr, reflect.UnsafePointer, reflect.Chan:
+		return x.Pointer() < y.Pointer()
+	case reflect.String:
+		return x.String() < y.String()
+	case reflect.Array:
+		for i := 0; i < x.Len(); i++ {
+			if isLess(x.Index(i), y.Index(i)) {
+				return true
+			}
+			if isLess(y.Index(i), x.Index(i)) {
+				return false
+			}
+		}
+		return false
+	case reflect.Struct:
+		for i := 0; i < x.NumField(); i++ {
+			if isLess(x.Field(i), y.Field(i)) {
+				return true
+			}
+			if isLess(y.Field(i), x.Field(i)) {
+				return false
+			}
+		}
+		return false
+	case reflect.Interface:
+		vx, vy := x.Elem(), y.Elem()
+		if !vx.IsValid() || !vy.IsValid() {
+			return !vx.IsValid() && vy.IsValid()
+		}
+		tx, ty := vx.Type(), vy.Type()
+		if tx == ty {
+			return isLess(x.Elem(), y.Elem())
+		}
+		if tx.Kind() != ty.Kind() {
+			return vx.Kind() < vy.Kind()
+		}
+		if tx.String() != ty.String() {
+			return tx.String() < ty.String()
+		}
+		if tx.PkgPath() != ty.PkgPath() {
+			return tx.PkgPath() < ty.PkgPath()
+		}
+		// This can happen in rare situations, so we fallback to just comparing
+		// the unique pointer for a reflect.Type. This guarantees deterministic
+		// ordering within a program, but it is obviously not stable.
+		return reflect.ValueOf(vx.Type()).Pointer() < reflect.ValueOf(vy.Type()).Pointer()
+	default:
+		// Must be Func, Map, or Slice; which are not comparable.
+		panic(fmt.Sprintf("%T is not comparable", x.Type()))
+	}
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go b/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
new file mode 100644
index 0000000..06a8ffd
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
@@ -0,0 +1,48 @@
+// Copyright 2017, 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.md file.
+
+package value
+
+import (
+	"math"
+	"reflect"
+)
+
+// IsZero reports whether v is the zero value.
+// This does not rely on Interface and so can be used on unexported fields.
+func IsZero(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Bool:
+		return v.Bool() == false
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return math.Float64bits(v.Float()) == 0
+	case reflect.Complex64, reflect.Complex128:
+		return math.Float64bits(real(v.Complex())) == 0 && math.Float64bits(imag(v.Complex())) == 0
+	case reflect.String:
+		return v.String() == ""
+	case reflect.UnsafePointer:
+		return v.Pointer() == 0
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
+		return v.IsNil()
+	case reflect.Array:
+		for i := 0; i < v.Len(); i++ {
+			if !IsZero(v.Index(i)) {
+				return false
+			}
+		}
+		return true
+	case reflect.Struct:
+		for i := 0; i < v.NumField(); i++ {
+			if !IsZero(v.Field(i)) {
+				return false
+			}
+		}
+		return true
+	}
+	return false
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go
new file mode 100644
index 0000000..abbd2a6
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/options.go
@@ -0,0 +1,549 @@
+// Copyright 2017, 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.md file.
+
+package cmp
+
+import (
+	"fmt"
+	"reflect"
+	"regexp"
+	"strings"
+
+	"github.com/google/go-cmp/cmp/internal/function"
+)
+
+// Option configures for specific behavior of Equal and Diff. In particular,
+// the fundamental Option functions (Ignore, Transformer, and Comparer),
+// configure how equality is determined.
+//
+// The fundamental options may be composed with filters (FilterPath and
+// FilterValues) to control the scope over which they are applied.
+//
+// The cmp/cmpopts package provides helper functions for creating options that
+// may be used with Equal and Diff.
+type Option interface {
+	// filter applies all filters and returns the option that remains.
+	// Each option may only read s.curPath and call s.callTTBFunc.
+	//
+	// An Options is returned only if multiple comparers or transformers
+	// can apply simultaneously and will only contain values of those types
+	// or sub-Options containing values of those types.
+	filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption
+}
+
+// applicableOption represents the following types:
+//	Fundamental: ignore | validator | *comparer | *transformer
+//	Grouping:    Options
+type applicableOption interface {
+	Option
+
+	// apply executes the option, which may mutate s or panic.
+	apply(s *state, vx, vy reflect.Value)
+}
+
+// coreOption represents the following types:
+//	Fundamental: ignore | validator | *comparer | *transformer
+//	Filters:     *pathFilter | *valuesFilter
+type coreOption interface {
+	Option
+	isCore()
+}
+
+type core struct{}
+
+func (core) isCore() {}
+
+// Options is a list of Option values that also satisfies the Option interface.
+// Helper comparison packages may return an Options value when packing multiple
+// Option values into a single Option. When this package processes an Options,
+// it will be implicitly expanded into a flat list.
+//
+// Applying a filter on an Options is equivalent to applying that same filter
+// on all individual options held within.
+type Options []Option
+
+func (opts Options) filter(s *state, t reflect.Type, vx, vy reflect.Value) (out applicableOption) {
+	for _, opt := range opts {
+		switch opt := opt.filter(s, t, vx, vy); opt.(type) {
+		case ignore:
+			return ignore{} // Only ignore can short-circuit evaluation
+		case validator:
+			out = validator{} // Takes precedence over comparer or transformer
+		case *comparer, *transformer, Options:
+			switch out.(type) {
+			case nil:
+				out = opt
+			case validator:
+				// Keep validator
+			case *comparer, *transformer, Options:
+				out = Options{out, opt} // Conflicting comparers or transformers
+			}
+		}
+	}
+	return out
+}
+
+func (opts Options) apply(s *state, _, _ reflect.Value) {
+	const warning = "ambiguous set of applicable options"
+	const help = "consider using filters to ensure at most one Comparer or Transformer may apply"
+	var ss []string
+	for _, opt := range flattenOptions(nil, opts) {
+		ss = append(ss, fmt.Sprint(opt))
+	}
+	set := strings.Join(ss, "\n\t")
+	panic(fmt.Sprintf("%s at %#v:\n\t%s\n%s", warning, s.curPath, set, help))
+}
+
+func (opts Options) String() string {
+	var ss []string
+	for _, opt := range opts {
+		ss = append(ss, fmt.Sprint(opt))
+	}
+	return fmt.Sprintf("Options{%s}", strings.Join(ss, ", "))
+}
+
+// FilterPath returns a new Option where opt is only evaluated if filter f
+// returns true for the current Path in the value tree.
+//
+// This filter is called even if a slice element or map entry is missing and
+// provides an opportunity to ignore such cases. The filter function must be
+// symmetric such that the filter result is identical regardless of whether the
+// missing value is from x or y.
+//
+// The option passed in may be an Ignore, Transformer, Comparer, Options, or
+// a previously filtered Option.
+func FilterPath(f func(Path) bool, opt Option) Option {
+	if f == nil {
+		panic("invalid path filter function")
+	}
+	if opt := normalizeOption(opt); opt != nil {
+		return &pathFilter{fnc: f, opt: opt}
+	}
+	return nil
+}
+
+type pathFilter struct {
+	core
+	fnc func(Path) bool
+	opt Option
+}
+
+func (f pathFilter) filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption {
+	if f.fnc(s.curPath) {
+		return f.opt.filter(s, t, vx, vy)
+	}
+	return nil
+}
+
+func (f pathFilter) String() string {
+	return fmt.Sprintf("FilterPath(%s, %v)", function.NameOf(reflect.ValueOf(f.fnc)), f.opt)
+}
+
+// FilterValues returns a new Option where opt is only evaluated if filter f,
+// which is a function of the form "func(T, T) bool", returns true for the
+// current pair of values being compared. If either value is invalid or
+// the type of the values is not assignable to T, then this filter implicitly
+// returns false.
+//
+// The filter function must be
+// symmetric (i.e., agnostic to the order of the inputs) and
+// deterministic (i.e., produces the same result when given the same inputs).
+// If T is an interface, it is possible that f is called with two values with
+// different concrete types that both implement T.
+//
+// The option passed in may be an Ignore, Transformer, Comparer, Options, or
+// a previously filtered Option.
+func FilterValues(f interface{}, opt Option) Option {
+	v := reflect.ValueOf(f)
+	if !function.IsType(v.Type(), function.ValueFilter) || v.IsNil() {
+		panic(fmt.Sprintf("invalid values filter function: %T", f))
+	}
+	if opt := normalizeOption(opt); opt != nil {
+		vf := &valuesFilter{fnc: v, opt: opt}
+		if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
+			vf.typ = ti
+		}
+		return vf
+	}
+	return nil
+}
+
+type valuesFilter struct {
+	core
+	typ reflect.Type  // T
+	fnc reflect.Value // func(T, T) bool
+	opt Option
+}
+
+func (f valuesFilter) filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption {
+	if !vx.IsValid() || !vx.CanInterface() || !vy.IsValid() || !vy.CanInterface() {
+		return nil
+	}
+	if (f.typ == nil || t.AssignableTo(f.typ)) && s.callTTBFunc(f.fnc, vx, vy) {
+		return f.opt.filter(s, t, vx, vy)
+	}
+	return nil
+}
+
+func (f valuesFilter) String() string {
+	return fmt.Sprintf("FilterValues(%s, %v)", function.NameOf(f.fnc), f.opt)
+}
+
+// Ignore is an Option that causes all comparisons to be ignored.
+// This value is intended to be combined with FilterPath or FilterValues.
+// It is an error to pass an unfiltered Ignore option to Equal.
+func Ignore() Option { return ignore{} }
+
+type ignore struct{ core }
+
+func (ignore) isFiltered() bool                                                     { return false }
+func (ignore) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption { return ignore{} }
+func (ignore) apply(s *state, _, _ reflect.Value)                                   { s.report(true, reportByIgnore) }
+func (ignore) String() string                                                       { return "Ignore()" }
+
+// validator is a sentinel Option type to indicate that some options could not
+// be evaluated due to unexported fields, missing slice elements, or
+// missing map entries. Both values are validator only for unexported fields.
+type validator struct{ core }
+
+func (validator) filter(_ *state, _ reflect.Type, vx, vy reflect.Value) applicableOption {
+	if !vx.IsValid() || !vy.IsValid() {
+		return validator{}
+	}
+	if !vx.CanInterface() || !vy.CanInterface() {
+		return validator{}
+	}
+	return nil
+}
+func (validator) apply(s *state, vx, vy reflect.Value) {
+	// Implies missing slice element or map entry.
+	if !vx.IsValid() || !vy.IsValid() {
+		s.report(vx.IsValid() == vy.IsValid(), 0)
+		return
+	}
+
+	// Unable to Interface implies unexported field without visibility access.
+	if !vx.CanInterface() || !vy.CanInterface() {
+		const help = "consider using a custom Comparer; if you control the implementation of type, you can also consider using an Exporter, AllowUnexported, or cmpopts.IgnoreUnexported"
+		var name string
+		if t := s.curPath.Index(-2).Type(); t.Name() != "" {
+			// Named type with unexported fields.
+			name = fmt.Sprintf("%q.%v", t.PkgPath(), t.Name()) // e.g., "path/to/package".MyType
+		} else {
+			// Unnamed type with unexported fields. Derive PkgPath from field.
+			var pkgPath string
+			for i := 0; i < t.NumField() && pkgPath == ""; i++ {
+				pkgPath = t.Field(i).PkgPath
+			}
+			name = fmt.Sprintf("%q.(%v)", pkgPath, t.String()) // e.g., "path/to/package".(struct { a int })
+		}
+		panic(fmt.Sprintf("cannot handle unexported field at %#v:\n\t%v\n%s", s.curPath, name, help))
+	}
+
+	panic("not reachable")
+}
+
+// identRx represents a valid identifier according to the Go specification.
+const identRx = `[_\p{L}][_\p{L}\p{N}]*`
+
+var identsRx = regexp.MustCompile(`^` + identRx + `(\.` + identRx + `)*$`)
+
+// Transformer returns an Option that applies a transformation function that
+// converts values of a certain type into that of another.
+//
+// The transformer f must be a function "func(T) R" that converts values of
+// type T to those of type R and is implicitly filtered to input values
+// assignable to T. The transformer must not mutate T in any way.
+//
+// To help prevent some cases of infinite recursive cycles applying the
+// same transform to the output of itself (e.g., in the case where the
+// input and output types are the same), an implicit filter is added such that
+// a transformer is applicable only if that exact transformer is not already
+// in the tail of the Path since the last non-Transform step.
+// For situations where the implicit filter is still insufficient,
+// consider using cmpopts.AcyclicTransformer, which adds a filter
+// to prevent the transformer from being recursively applied upon itself.
+//
+// The name is a user provided label that is used as the Transform.Name in the
+// transformation PathStep (and eventually shown in the Diff output).
+// The name must be a valid identifier or qualified identifier in Go syntax.
+// If empty, an arbitrary name is used.
+func Transformer(name string, f interface{}) Option {
+	v := reflect.ValueOf(f)
+	if !function.IsType(v.Type(), function.Transformer) || v.IsNil() {
+		panic(fmt.Sprintf("invalid transformer function: %T", f))
+	}
+	if name == "" {
+		name = function.NameOf(v)
+		if !identsRx.MatchString(name) {
+			name = "λ" // Lambda-symbol as placeholder name
+		}
+	} else if !identsRx.MatchString(name) {
+		panic(fmt.Sprintf("invalid name: %q", name))
+	}
+	tr := &transformer{name: name, fnc: reflect.ValueOf(f)}
+	if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
+		tr.typ = ti
+	}
+	return tr
+}
+
+type transformer struct {
+	core
+	name string
+	typ  reflect.Type  // T
+	fnc  reflect.Value // func(T) R
+}
+
+func (tr *transformer) isFiltered() bool { return tr.typ != nil }
+
+func (tr *transformer) filter(s *state, t reflect.Type, _, _ reflect.Value) applicableOption {
+	for i := len(s.curPath) - 1; i >= 0; i-- {
+		if t, ok := s.curPath[i].(Transform); !ok {
+			break // Hit most recent non-Transform step
+		} else if tr == t.trans {
+			return nil // Cannot directly use same Transform
+		}
+	}
+	if tr.typ == nil || t.AssignableTo(tr.typ) {
+		return tr
+	}
+	return nil
+}
+
+func (tr *transformer) apply(s *state, vx, vy reflect.Value) {
+	step := Transform{&transform{pathStep{typ: tr.fnc.Type().Out(0)}, tr}}
+	vvx := s.callTRFunc(tr.fnc, vx, step)
+	vvy := s.callTRFunc(tr.fnc, vy, step)
+	step.vx, step.vy = vvx, vvy
+	s.compareAny(step)
+}
+
+func (tr transformer) String() string {
+	return fmt.Sprintf("Transformer(%s, %s)", tr.name, function.NameOf(tr.fnc))
+}
+
+// Comparer returns an Option that determines whether two values are equal
+// to each other.
+//
+// The comparer f must be a function "func(T, T) bool" and is implicitly
+// filtered to input values assignable to T. If T is an interface, it is
+// possible that f is called with two values of different concrete types that
+// both implement T.
+//
+// The equality function must be:
+//	• Symmetric: equal(x, y) == equal(y, x)
+//	• Deterministic: equal(x, y) == equal(x, y)
+//	• Pure: equal(x, y) does not modify x or y
+func Comparer(f interface{}) Option {
+	v := reflect.ValueOf(f)
+	if !function.IsType(v.Type(), function.Equal) || v.IsNil() {
+		panic(fmt.Sprintf("invalid comparer function: %T", f))
+	}
+	cm := &comparer{fnc: v}
+	if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
+		cm.typ = ti
+	}
+	return cm
+}
+
+type comparer struct {
+	core
+	typ reflect.Type  // T
+	fnc reflect.Value // func(T, T) bool
+}
+
+func (cm *comparer) isFiltered() bool { return cm.typ != nil }
+
+func (cm *comparer) filter(_ *state, t reflect.Type, _, _ reflect.Value) applicableOption {
+	if cm.typ == nil || t.AssignableTo(cm.typ) {
+		return cm
+	}
+	return nil
+}
+
+func (cm *comparer) apply(s *state, vx, vy reflect.Value) {
+	eq := s.callTTBFunc(cm.fnc, vx, vy)
+	s.report(eq, reportByFunc)
+}
+
+func (cm comparer) String() string {
+	return fmt.Sprintf("Comparer(%s)", function.NameOf(cm.fnc))
+}
+
+// Exporter returns an Option that specifies whether Equal is allowed to
+// introspect into the unexported fields of certain struct types.
+//
+// Users of this option must understand that comparing on unexported fields
+// from external packages is not safe since changes in the internal
+// implementation of some external package may cause the result of Equal
+// to unexpectedly change. However, it may be valid to use this option on types
+// defined in an internal package where the semantic meaning of an unexported
+// field is in the control of the user.
+//
+// In many cases, a custom Comparer should be used instead that defines
+// equality as a function of the public API of a type rather than the underlying
+// unexported implementation.
+//
+// For example, the reflect.Type documentation defines equality to be determined
+// by the == operator on the interface (essentially performing a shallow pointer
+// comparison) and most attempts to compare *regexp.Regexp types are interested
+// in only checking that the regular expression strings are equal.
+// Both of these are accomplished using Comparers:
+//
+//	Comparer(func(x, y reflect.Type) bool { return x == y })
+//	Comparer(func(x, y *regexp.Regexp) bool { return x.String() == y.String() })
+//
+// In other cases, the cmpopts.IgnoreUnexported option can be used to ignore
+// all unexported fields on specified struct types.
+func Exporter(f func(reflect.Type) bool) Option {
+	if !supportExporters {
+		panic("Exporter is not supported on purego builds")
+	}
+	return exporter(f)
+}
+
+type exporter func(reflect.Type) bool
+
+func (exporter) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption {
+	panic("not implemented")
+}
+
+// AllowUnexported returns an Options that allows Equal to forcibly introspect
+// unexported fields of the specified struct types.
+//
+// See Exporter for the proper use of this option.
+func AllowUnexported(types ...interface{}) Option {
+	m := make(map[reflect.Type]bool)
+	for _, typ := range types {
+		t := reflect.TypeOf(typ)
+		if t.Kind() != reflect.Struct {
+			panic(fmt.Sprintf("invalid struct type: %T", typ))
+		}
+		m[t] = true
+	}
+	return exporter(func(t reflect.Type) bool { return m[t] })
+}
+
+// Result represents the comparison result for a single node and
+// is provided by cmp when calling Result (see Reporter).
+type Result struct {
+	_     [0]func() // Make Result incomparable
+	flags resultFlags
+}
+
+// Equal reports whether the node was determined to be equal or not.
+// As a special case, ignored nodes are considered equal.
+func (r Result) Equal() bool {
+	return r.flags&(reportEqual|reportByIgnore) != 0
+}
+
+// ByIgnore reports whether the node is equal because it was ignored.
+// This never reports true if Equal reports false.
+func (r Result) ByIgnore() bool {
+	return r.flags&reportByIgnore != 0
+}
+
+// ByMethod reports whether the Equal method determined equality.
+func (r Result) ByMethod() bool {
+	return r.flags&reportByMethod != 0
+}
+
+// ByFunc reports whether a Comparer function determined equality.
+func (r Result) ByFunc() bool {
+	return r.flags&reportByFunc != 0
+}
+
+// ByCycle reports whether a reference cycle was detected.
+func (r Result) ByCycle() bool {
+	return r.flags&reportByCycle != 0
+}
+
+type resultFlags uint
+
+const (
+	_ resultFlags = (1 << iota) / 2
+
+	reportEqual
+	reportUnequal
+	reportByIgnore
+	reportByMethod
+	reportByFunc
+	reportByCycle
+)
+
+// Reporter is an Option that can be passed to Equal. When Equal traverses
+// the value trees, it calls PushStep as it descends into each node in the
+// tree and PopStep as it ascend out of the node. The leaves of the tree are
+// either compared (determined to be equal or not equal) or ignored and reported
+// as such by calling the Report method.
+func Reporter(r interface {
+	// PushStep is called when a tree-traversal operation is performed.
+	// The PathStep itself is only valid until the step is popped.
+	// The PathStep.Values are valid for the duration of the entire traversal
+	// and must not be mutated.
+	//
+	// Equal always calls PushStep at the start to provide an operation-less
+	// PathStep used to report the root values.
+	//
+	// Within a slice, the exact set of inserted, removed, or modified elements
+	// is unspecified and may change in future implementations.
+	// The entries of a map are iterated through in an unspecified order.
+	PushStep(PathStep)
+
+	// Report is called exactly once on leaf nodes to report whether the
+	// comparison identified the node as equal, unequal, or ignored.
+	// A leaf node is one that is immediately preceded by and followed by
+	// a pair of PushStep and PopStep calls.
+	Report(Result)
+
+	// PopStep ascends back up the value tree.
+	// There is always a matching pop call for every push call.
+	PopStep()
+}) Option {
+	return reporter{r}
+}
+
+type reporter struct{ reporterIface }
+type reporterIface interface {
+	PushStep(PathStep)
+	Report(Result)
+	PopStep()
+}
+
+func (reporter) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption {
+	panic("not implemented")
+}
+
+// normalizeOption normalizes the input options such that all Options groups
+// are flattened and groups with a single element are reduced to that element.
+// Only coreOptions and Options containing coreOptions are allowed.
+func normalizeOption(src Option) Option {
+	switch opts := flattenOptions(nil, Options{src}); len(opts) {
+	case 0:
+		return nil
+	case 1:
+		return opts[0]
+	default:
+		return opts
+	}
+}
+
+// flattenOptions copies all options in src to dst as a flat list.
+// Only coreOptions and Options containing coreOptions are allowed.
+func flattenOptions(dst, src Options) Options {
+	for _, opt := range src {
+		switch opt := opt.(type) {
+		case nil:
+			continue
+		case Options:
+			dst = flattenOptions(dst, opt)
+		case coreOption:
+			dst = append(dst, opt)
+		default:
+			panic(fmt.Sprintf("invalid option type: %T", opt))
+		}
+	}
+	return dst
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go
new file mode 100644
index 0000000..509d6b8
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/path.go
@@ -0,0 +1,377 @@
+// Copyright 2017, 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.md file.
+
+package cmp
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"github.com/google/go-cmp/cmp/internal/value"
+)
+
+// Path is a list of PathSteps describing the sequence of operations to get
+// from some root type to the current position in the value tree.
+// The first Path element is always an operation-less PathStep that exists
+// simply to identify the initial type.
+//
+// When traversing structs with embedded structs, the embedded struct will
+// always be accessed as a field before traversing the fields of the
+// embedded struct themselves. That is, an exported field from the
+// embedded struct will never be accessed directly from the parent struct.
+type Path []PathStep
+
+// PathStep is a union-type for specific operations to traverse
+// a value's tree structure. Users of this package never need to implement
+// these types as values of this type will be returned by this package.
+//
+// Implementations of this interface are
+// StructField, SliceIndex, MapIndex, Indirect, TypeAssertion, and Transform.
+type PathStep interface {
+	String() string
+
+	// Type is the resulting type after performing the path step.
+	Type() reflect.Type
+
+	// Values is the resulting values after performing the path step.
+	// The type of each valid value is guaranteed to be identical to Type.
+	//
+	// In some cases, one or both may be invalid or have restrictions:
+	//	• For StructField, both are not interface-able if the current field
+	//	is unexported and the struct type is not explicitly permitted by
+	//	an Exporter to traverse unexported fields.
+	//	• For SliceIndex, one may be invalid if an element is missing from
+	//	either the x or y slice.
+	//	• For MapIndex, one may be invalid if an entry is missing from
+	//	either the x or y map.
+	//
+	// The provided values must not be mutated.
+	Values() (vx, vy reflect.Value)
+}
+
+var (
+	_ PathStep = StructField{}
+	_ PathStep = SliceIndex{}
+	_ PathStep = MapIndex{}
+	_ PathStep = Indirect{}
+	_ PathStep = TypeAssertion{}
+	_ PathStep = Transform{}
+)
+
+func (pa *Path) push(s PathStep) {
+	*pa = append(*pa, s)
+}
+
+func (pa *Path) pop() {
+	*pa = (*pa)[:len(*pa)-1]
+}
+
+// Last returns the last PathStep in the Path.
+// If the path is empty, this returns a non-nil PathStep that reports a nil Type.
+func (pa Path) Last() PathStep {
+	return pa.Index(-1)
+}
+
+// Index returns the ith step in the Path and supports negative indexing.
+// A negative index starts counting from the tail of the Path such that -1
+// refers to the last step, -2 refers to the second-to-last step, and so on.
+// If index is invalid, this returns a non-nil PathStep that reports a nil Type.
+func (pa Path) Index(i int) PathStep {
+	if i < 0 {
+		i = len(pa) + i
+	}
+	if i < 0 || i >= len(pa) {
+		return pathStep{}
+	}
+	return pa[i]
+}
+
+// String returns the simplified path to a node.
+// The simplified path only contains struct field accesses.
+//
+// For example:
+//	MyMap.MySlices.MyField
+func (pa Path) String() string {
+	var ss []string
+	for _, s := range pa {
+		if _, ok := s.(StructField); ok {
+			ss = append(ss, s.String())
+		}
+	}
+	return strings.TrimPrefix(strings.Join(ss, ""), ".")
+}
+
+// GoString returns the path to a specific node using Go syntax.
+//
+// For example:
+//	(*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField
+func (pa Path) GoString() string {
+	var ssPre, ssPost []string
+	var numIndirect int
+	for i, s := range pa {
+		var nextStep PathStep
+		if i+1 < len(pa) {
+			nextStep = pa[i+1]
+		}
+		switch s := s.(type) {
+		case Indirect:
+			numIndirect++
+			pPre, pPost := "(", ")"
+			switch nextStep.(type) {
+			case Indirect:
+				continue // Next step is indirection, so let them batch up
+			case StructField:
+				numIndirect-- // Automatic indirection on struct fields
+			case nil:
+				pPre, pPost = "", "" // Last step; no need for parenthesis
+			}
+			if numIndirect > 0 {
+				ssPre = append(ssPre, pPre+strings.Repeat("*", numIndirect))
+				ssPost = append(ssPost, pPost)
+			}
+			numIndirect = 0
+			continue
+		case Transform:
+			ssPre = append(ssPre, s.trans.name+"(")
+			ssPost = append(ssPost, ")")
+			continue
+		}
+		ssPost = append(ssPost, s.String())
+	}
+	for i, j := 0, len(ssPre)-1; i < j; i, j = i+1, j-1 {
+		ssPre[i], ssPre[j] = ssPre[j], ssPre[i]
+	}
+	return strings.Join(ssPre, "") + strings.Join(ssPost, "")
+}
+
+type pathStep struct {
+	typ    reflect.Type
+	vx, vy reflect.Value
+}
+
+func (ps pathStep) Type() reflect.Type             { return ps.typ }
+func (ps pathStep) Values() (vx, vy reflect.Value) { return ps.vx, ps.vy }
+func (ps pathStep) String() string {
+	if ps.typ == nil {
+		return "<nil>"
+	}
+	s := ps.typ.String()
+	if s == "" || strings.ContainsAny(s, "{}\n") {
+		return "root" // Type too simple or complex to print
+	}
+	return fmt.Sprintf("{%s}", s)
+}
+
+// StructField represents a struct field access on a field called Name.
+type StructField struct{ *structField }
+type structField struct {
+	pathStep
+	name string
+	idx  int
+
+	// These fields are used for forcibly accessing an unexported field.
+	// pvx, pvy, and field are only valid if unexported is true.
+	unexported bool
+	mayForce   bool                // Forcibly allow visibility
+	pvx, pvy   reflect.Value       // Parent values
+	field      reflect.StructField // Field information
+}
+
+func (sf StructField) Type() reflect.Type { return sf.typ }
+func (sf StructField) Values() (vx, vy reflect.Value) {
+	if !sf.unexported {
+		return sf.vx, sf.vy // CanInterface reports true
+	}
+
+	// Forcibly obtain read-write access to an unexported struct field.
+	if sf.mayForce {
+		vx = retrieveUnexportedField(sf.pvx, sf.field)
+		vy = retrieveUnexportedField(sf.pvy, sf.field)
+		return vx, vy // CanInterface reports true
+	}
+	return sf.vx, sf.vy // CanInterface reports false
+}
+func (sf StructField) String() string { return fmt.Sprintf(".%s", sf.name) }
+
+// Name is the field name.
+func (sf StructField) Name() string { return sf.name }
+
+// Index is the index of the field in the parent struct type.
+// See reflect.Type.Field.
+func (sf StructField) Index() int { return sf.idx }
+
+// SliceIndex is an index operation on a slice or array at some index Key.
+type SliceIndex struct{ *sliceIndex }
+type sliceIndex struct {
+	pathStep
+	xkey, ykey int
+	isSlice    bool // False for reflect.Array
+}
+
+func (si SliceIndex) Type() reflect.Type             { return si.typ }
+func (si SliceIndex) Values() (vx, vy reflect.Value) { return si.vx, si.vy }
+func (si SliceIndex) String() string {
+	switch {
+	case si.xkey == si.ykey:
+		return fmt.Sprintf("[%d]", si.xkey)
+	case si.ykey == -1:
+		// [5->?] means "I don't know where X[5] went"
+		return fmt.Sprintf("[%d->?]", si.xkey)
+	case si.xkey == -1:
+		// [?->3] means "I don't know where Y[3] came from"
+		return fmt.Sprintf("[?->%d]", si.ykey)
+	default:
+		// [5->3] means "X[5] moved to Y[3]"
+		return fmt.Sprintf("[%d->%d]", si.xkey, si.ykey)
+	}
+}
+
+// Key is the index key; it may return -1 if in a split state
+func (si SliceIndex) Key() int {
+	if si.xkey != si.ykey {
+		return -1
+	}
+	return si.xkey
+}
+
+// SplitKeys are the indexes for indexing into slices in the
+// x and y values, respectively. These indexes may differ due to the
+// insertion or removal of an element in one of the slices, causing
+// all of the indexes to be shifted. If an index is -1, then that
+// indicates that the element does not exist in the associated slice.
+//
+// Key is guaranteed to return -1 if and only if the indexes returned
+// by SplitKeys are not the same. SplitKeys will never return -1 for
+// both indexes.
+func (si SliceIndex) SplitKeys() (ix, iy int) { return si.xkey, si.ykey }
+
+// MapIndex is an index operation on a map at some index Key.
+type MapIndex struct{ *mapIndex }
+type mapIndex struct {
+	pathStep
+	key reflect.Value
+}
+
+func (mi MapIndex) Type() reflect.Type             { return mi.typ }
+func (mi MapIndex) Values() (vx, vy reflect.Value) { return mi.vx, mi.vy }
+func (mi MapIndex) String() string                 { return fmt.Sprintf("[%#v]", mi.key) }
+
+// Key is the value of the map key.
+func (mi MapIndex) Key() reflect.Value { return mi.key }
+
+// Indirect represents pointer indirection on the parent type.
+type Indirect struct{ *indirect }
+type indirect struct {
+	pathStep
+}
+
+func (in Indirect) Type() reflect.Type             { return in.typ }
+func (in Indirect) Values() (vx, vy reflect.Value) { return in.vx, in.vy }
+func (in Indirect) String() string                 { return "*" }
+
+// TypeAssertion represents a type assertion on an interface.
+type TypeAssertion struct{ *typeAssertion }
+type typeAssertion struct {
+	pathStep
+}
+
+func (ta TypeAssertion) Type() reflect.Type             { return ta.typ }
+func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy }
+func (ta TypeAssertion) String() string                 { return fmt.Sprintf(".(%v)", ta.typ) }
+
+// Transform is a transformation from the parent type to the current type.
+type Transform struct{ *transform }
+type transform struct {
+	pathStep
+	trans *transformer
+}
+
+func (tf Transform) Type() reflect.Type             { return tf.typ }
+func (tf Transform) Values() (vx, vy reflect.Value) { return tf.vx, tf.vy }
+func (tf Transform) String() string                 { return fmt.Sprintf("%s()", tf.trans.name) }
+
+// Name is the name of the Transformer.
+func (tf Transform) Name() string { return tf.trans.name }
+
+// Func is the function pointer to the transformer function.
+func (tf Transform) Func() reflect.Value { return tf.trans.fnc }
+
+// Option returns the originally constructed Transformer option.
+// The == operator can be used to detect the exact option used.
+func (tf Transform) Option() Option { return tf.trans }
+
+// pointerPath represents a dual-stack of pointers encountered when
+// recursively traversing the x and y values. This data structure supports
+// detection of cycles and determining whether the cycles are equal.
+// In Go, cycles can occur via pointers, slices, and maps.
+//
+// The pointerPath uses a map to represent a stack; where descension into a
+// pointer pushes the address onto the stack, and ascension from a pointer
+// pops the address from the stack. Thus, when traversing into a pointer from
+// reflect.Ptr, reflect.Slice element, or reflect.Map, we can detect cycles
+// by checking whether the pointer has already been visited. The cycle detection
+// uses a seperate stack for the x and y values.
+//
+// If a cycle is detected we need to determine whether the two pointers
+// should be considered equal. The definition of equality chosen by Equal
+// requires two graphs to have the same structure. To determine this, both the
+// x and y values must have a cycle where the previous pointers were also
+// encountered together as a pair.
+//
+// Semantically, this is equivalent to augmenting Indirect, SliceIndex, and
+// MapIndex with pointer information for the x and y values.
+// Suppose px and py are two pointers to compare, we then search the
+// Path for whether px was ever encountered in the Path history of x, and
+// similarly so with py. If either side has a cycle, the comparison is only
+// equal if both px and py have a cycle resulting from the same PathStep.
+//
+// Using a map as a stack is more performant as we can perform cycle detection
+// in O(1) instead of O(N) where N is len(Path).
+type pointerPath struct {
+	// mx is keyed by x pointers, where the value is the associated y pointer.
+	mx map[value.Pointer]value.Pointer
+	// my is keyed by y pointers, where the value is the associated x pointer.
+	my map[value.Pointer]value.Pointer
+}
+
+func (p *pointerPath) Init() {
+	p.mx = make(map[value.Pointer]value.Pointer)
+	p.my = make(map[value.Pointer]value.Pointer)
+}
+
+// Push indicates intent to descend into pointers vx and vy where
+// visited reports whether either has been seen before. If visited before,
+// equal reports whether both pointers were encountered together.
+// Pop must be called if and only if the pointers were never visited.
+//
+// The pointers vx and vy must be a reflect.Ptr, reflect.Slice, or reflect.Map
+// and be non-nil.
+func (p pointerPath) Push(vx, vy reflect.Value) (equal, visited bool) {
+	px := value.PointerOf(vx)
+	py := value.PointerOf(vy)
+	_, ok1 := p.mx[px]
+	_, ok2 := p.my[py]
+	if ok1 || ok2 {
+		equal = p.mx[px] == py && p.my[py] == px // Pointers paired together
+		return equal, true
+	}
+	p.mx[px] = py
+	p.my[py] = px
+	return false, false
+}
+
+// Pop ascends from pointers vx and vy.
+func (p pointerPath) Pop(vx, vy reflect.Value) {
+	delete(p.mx, value.PointerOf(vx))
+	delete(p.my, value.PointerOf(vy))
+}
+
+// isExported reports whether the identifier is exported.
+func isExported(id string) bool {
+	r, _ := utf8.DecodeRuneInString(id)
+	return unicode.IsUpper(r)
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/report.go b/vendor/github.com/google/go-cmp/cmp/report.go
new file mode 100644
index 0000000..6ddf299
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/report.go
@@ -0,0 +1,51 @@
+// Copyright 2017, 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.md file.
+
+package cmp
+
+// defaultReporter implements the reporter interface.
+//
+// As Equal serially calls the PushStep, Report, and PopStep methods, the
+// defaultReporter constructs a tree-based representation of the compared value
+// and the result of each comparison (see valueNode).
+//
+// When the String method is called, the FormatDiff method transforms the
+// valueNode tree into a textNode tree, which is a tree-based representation
+// of the textual output (see textNode).
+//
+// Lastly, the textNode.String method produces the final report as a string.
+type defaultReporter struct {
+	root *valueNode
+	curr *valueNode
+}
+
+func (r *defaultReporter) PushStep(ps PathStep) {
+	r.curr = r.curr.PushStep(ps)
+	if r.root == nil {
+		r.root = r.curr
+	}
+}
+func (r *defaultReporter) Report(rs Result) {
+	r.curr.Report(rs)
+}
+func (r *defaultReporter) PopStep() {
+	r.curr = r.curr.PopStep()
+}
+
+// String provides a full report of the differences detected as a structured
+// literal in pseudo-Go syntax. String may only be called after the entire tree
+// has been traversed.
+func (r *defaultReporter) String() string {
+	assert(r.root != nil && r.curr == nil)
+	if r.root.NumDiff == 0 {
+		return ""
+	}
+	return formatOptions{}.FormatDiff(r.root).String()
+}
+
+func assert(ok bool) {
+	if !ok {
+		panic("assertion failure")
+	}
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/report_compare.go b/vendor/github.com/google/go-cmp/cmp/report_compare.go
new file mode 100644
index 0000000..17a05ee
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/report_compare.go
@@ -0,0 +1,296 @@
+// Copyright 2019, 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.md file.
+
+package cmp
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/google/go-cmp/cmp/internal/value"
+)
+
+// TODO: Enforce limits?
+//	* Enforce maximum number of records to print per node?
+//	* Enforce maximum size in bytes allowed?
+//	* As a heuristic, use less verbosity for equal nodes than unequal nodes.
+// TODO: Enforce unique outputs?
+//	* Avoid Stringer methods if it results in same output?
+//	* Print pointer address if outputs still equal?
+
+// numContextRecords is the number of surrounding equal records to print.
+const numContextRecords = 2
+
+type diffMode byte
+
+const (
+	diffUnknown   diffMode = 0
+	diffIdentical diffMode = ' '
+	diffRemoved   diffMode = '-'
+	diffInserted  diffMode = '+'
+)
+
+type typeMode int
+
+const (
+	// emitType always prints the type.
+	emitType typeMode = iota
+	// elideType never prints the type.
+	elideType
+	// autoType prints the type only for composite kinds
+	// (i.e., structs, slices, arrays, and maps).
+	autoType
+)
+
+type formatOptions struct {
+	// DiffMode controls the output mode of FormatDiff.
+	//
+	// If diffUnknown,   then produce a diff of the x and y values.
+	// If diffIdentical, then emit values as if they were equal.
+	// If diffRemoved,   then only emit x values (ignoring y values).
+	// If diffInserted,  then only emit y values (ignoring x values).
+	DiffMode diffMode
+
+	// TypeMode controls whether to print the type for the current node.
+	//
+	// As a general rule of thumb, we always print the type of the next node
+	// after an interface, and always elide the type of the next node after
+	// a slice or map node.
+	TypeMode typeMode
+
+	// formatValueOptions are options specific to printing reflect.Values.
+	formatValueOptions
+}
+
+func (opts formatOptions) WithDiffMode(d diffMode) formatOptions {
+	opts.DiffMode = d
+	return opts
+}
+func (opts formatOptions) WithTypeMode(t typeMode) formatOptions {
+	opts.TypeMode = t
+	return opts
+}
+
+// FormatDiff converts a valueNode tree into a textNode tree, where the later
+// is a textual representation of the differences detected in the former.
+func (opts formatOptions) FormatDiff(v *valueNode) textNode {
+	// Check whether we have specialized formatting for this node.
+	// This is not necessary, but helpful for producing more readable outputs.
+	if opts.CanFormatDiffSlice(v) {
+		return opts.FormatDiffSlice(v)
+	}
+
+	// For leaf nodes, format the value based on the reflect.Values alone.
+	if v.MaxDepth == 0 {
+		switch opts.DiffMode {
+		case diffUnknown, diffIdentical:
+			// Format Equal.
+			if v.NumDiff == 0 {
+				outx := opts.FormatValue(v.ValueX, visitedPointers{})
+				outy := opts.FormatValue(v.ValueY, visitedPointers{})
+				if v.NumIgnored > 0 && v.NumSame == 0 {
+					return textEllipsis
+				} else if outx.Len() < outy.Len() {
+					return outx
+				} else {
+					return outy
+				}
+			}
+
+			// Format unequal.
+			assert(opts.DiffMode == diffUnknown)
+			var list textList
+			outx := opts.WithTypeMode(elideType).FormatValue(v.ValueX, visitedPointers{})
+			outy := opts.WithTypeMode(elideType).FormatValue(v.ValueY, visitedPointers{})
+			if outx != nil {
+				list = append(list, textRecord{Diff: '-', Value: outx})
+			}
+			if outy != nil {
+				list = append(list, textRecord{Diff: '+', Value: outy})
+			}
+			return opts.WithTypeMode(emitType).FormatType(v.Type, list)
+		case diffRemoved:
+			return opts.FormatValue(v.ValueX, visitedPointers{})
+		case diffInserted:
+			return opts.FormatValue(v.ValueY, visitedPointers{})
+		default:
+			panic("invalid diff mode")
+		}
+	}
+
+	// Descend into the child value node.
+	if v.TransformerName != "" {
+		out := opts.WithTypeMode(emitType).FormatDiff(v.Value)
+		out = textWrap{"Inverse(" + v.TransformerName + ", ", out, ")"}
+		return opts.FormatType(v.Type, out)
+	} else {
+		switch k := v.Type.Kind(); k {
+		case reflect.Struct, reflect.Array, reflect.Slice, reflect.Map:
+			return opts.FormatType(v.Type, opts.formatDiffList(v.Records, k))
+		case reflect.Ptr:
+			return textWrap{"&", opts.FormatDiff(v.Value), ""}
+		case reflect.Interface:
+			return opts.WithTypeMode(emitType).FormatDiff(v.Value)
+		default:
+			panic(fmt.Sprintf("%v cannot have children", k))
+		}
+	}
+}
+
+func (opts formatOptions) formatDiffList(recs []reportRecord, k reflect.Kind) textNode {
+	// Derive record name based on the data structure kind.
+	var name string
+	var formatKey func(reflect.Value) string
+	switch k {
+	case reflect.Struct:
+		name = "field"
+		opts = opts.WithTypeMode(autoType)
+		formatKey = func(v reflect.Value) string { return v.String() }
+	case reflect.Slice, reflect.Array:
+		name = "element"
+		opts = opts.WithTypeMode(elideType)
+		formatKey = func(reflect.Value) string { return "" }
+	case reflect.Map:
+		name = "entry"
+		opts = opts.WithTypeMode(elideType)
+		formatKey = formatMapKey
+	}
+
+	// Handle unification.
+	switch opts.DiffMode {
+	case diffIdentical, diffRemoved, diffInserted:
+		var list textList
+		var deferredEllipsis bool // Add final "..." to indicate records were dropped
+		for _, r := range recs {
+			// Elide struct fields that are zero value.
+			if k == reflect.Struct {
+				var isZero bool
+				switch opts.DiffMode {
+				case diffIdentical:
+					isZero = value.IsZero(r.Value.ValueX) || value.IsZero(r.Value.ValueY)
+				case diffRemoved:
+					isZero = value.IsZero(r.Value.ValueX)
+				case diffInserted:
+					isZero = value.IsZero(r.Value.ValueY)
+				}
+				if isZero {
+					continue
+				}
+			}
+			// Elide ignored nodes.
+			if r.Value.NumIgnored > 0 && r.Value.NumSame+r.Value.NumDiff == 0 {
+				deferredEllipsis = !(k == reflect.Slice || k == reflect.Array)
+				if !deferredEllipsis {
+					list.AppendEllipsis(diffStats{})
+				}
+				continue
+			}
+			if out := opts.FormatDiff(r.Value); out != nil {
+				list = append(list, textRecord{Key: formatKey(r.Key), Value: out})
+			}
+		}
+		if deferredEllipsis {
+			list.AppendEllipsis(diffStats{})
+		}
+		return textWrap{"{", list, "}"}
+	case diffUnknown:
+	default:
+		panic("invalid diff mode")
+	}
+
+	// Handle differencing.
+	var list textList
+	groups := coalesceAdjacentRecords(name, recs)
+	for i, ds := range groups {
+		// Handle equal records.
+		if ds.NumDiff() == 0 {
+			// Compute the number of leading and trailing records to print.
+			var numLo, numHi int
+			numEqual := ds.NumIgnored + ds.NumIdentical
+			for numLo < numContextRecords && numLo+numHi < numEqual && i != 0 {
+				if r := recs[numLo].Value; r.NumIgnored > 0 && r.NumSame+r.NumDiff == 0 {
+					break
+				}
+				numLo++
+			}
+			for numHi < numContextRecords && numLo+numHi < numEqual && i != len(groups)-1 {
+				if r := recs[numEqual-numHi-1].Value; r.NumIgnored > 0 && r.NumSame+r.NumDiff == 0 {
+					break
+				}
+				numHi++
+			}
+			if numEqual-(numLo+numHi) == 1 && ds.NumIgnored == 0 {
+				numHi++ // Avoid pointless coalescing of a single equal record
+			}
+
+			// Format the equal values.
+			for _, r := range recs[:numLo] {
+				out := opts.WithDiffMode(diffIdentical).FormatDiff(r.Value)
+				list = append(list, textRecord{Key: formatKey(r.Key), Value: out})
+			}
+			if numEqual > numLo+numHi {
+				ds.NumIdentical -= numLo + numHi
+				list.AppendEllipsis(ds)
+			}
+			for _, r := range recs[numEqual-numHi : numEqual] {
+				out := opts.WithDiffMode(diffIdentical).FormatDiff(r.Value)
+				list = append(list, textRecord{Key: formatKey(r.Key), Value: out})
+			}
+			recs = recs[numEqual:]
+			continue
+		}
+
+		// Handle unequal records.
+		for _, r := range recs[:ds.NumDiff()] {
+			switch {
+			case opts.CanFormatDiffSlice(r.Value):
+				out := opts.FormatDiffSlice(r.Value)
+				list = append(list, textRecord{Key: formatKey(r.Key), Value: out})
+			case r.Value.NumChildren == r.Value.MaxDepth:
+				outx := opts.WithDiffMode(diffRemoved).FormatDiff(r.Value)
+				outy := opts.WithDiffMode(diffInserted).FormatDiff(r.Value)
+				if outx != nil {
+					list = append(list, textRecord{Diff: diffRemoved, Key: formatKey(r.Key), Value: outx})
+				}
+				if outy != nil {
+					list = append(list, textRecord{Diff: diffInserted, Key: formatKey(r.Key), Value: outy})
+				}
+			default:
+				out := opts.FormatDiff(r.Value)
+				list = append(list, textRecord{Key: formatKey(r.Key), Value: out})
+			}
+		}
+		recs = recs[ds.NumDiff():]
+	}
+	assert(len(recs) == 0)
+	return textWrap{"{", list, "}"}
+}
+
+// coalesceAdjacentRecords coalesces the list of records into groups of
+// adjacent equal, or unequal counts.
+func coalesceAdjacentRecords(name string, recs []reportRecord) (groups []diffStats) {
+	var prevCase int // Arbitrary index into which case last occurred
+	lastStats := func(i int) *diffStats {
+		if prevCase != i {
+			groups = append(groups, diffStats{Name: name})
+			prevCase = i
+		}
+		return &groups[len(groups)-1]
+	}
+	for _, r := range recs {
+		switch rv := r.Value; {
+		case rv.NumIgnored > 0 && rv.NumSame+rv.NumDiff == 0:
+			lastStats(1).NumIgnored++
+		case rv.NumDiff == 0:
+			lastStats(1).NumIdentical++
+		case rv.NumDiff > 0 && !rv.ValueY.IsValid():
+			lastStats(2).NumRemoved++
+		case rv.NumDiff > 0 && !rv.ValueX.IsValid():
+			lastStats(2).NumInserted++
+		default:
+			lastStats(2).NumModified++
+		}
+	}
+	return groups
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/report_reflect.go b/vendor/github.com/google/go-cmp/cmp/report_reflect.go
new file mode 100644
index 0000000..2761b62
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/report_reflect.go
@@ -0,0 +1,278 @@
+// Copyright 2019, 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.md file.
+
+package cmp
+
+import (
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+	"unicode"
+
+	"github.com/google/go-cmp/cmp/internal/flags"
+	"github.com/google/go-cmp/cmp/internal/value"
+)
+
+type formatValueOptions struct {
+	// AvoidStringer controls whether to avoid calling custom stringer
+	// methods like error.Error or fmt.Stringer.String.
+	AvoidStringer bool
+
+	// ShallowPointers controls whether to avoid descending into pointers.
+	// Useful when printing map keys, where pointer comparison is performed
+	// on the pointer address rather than the pointed-at value.
+	ShallowPointers bool
+
+	// PrintAddresses controls whether to print the address of all pointers,
+	// slice elements, and maps.
+	PrintAddresses bool
+}
+
+// FormatType prints the type as if it were wrapping s.
+// This may return s as-is depending on the current type and TypeMode mode.
+func (opts formatOptions) FormatType(t reflect.Type, s textNode) textNode {
+	// Check whether to emit the type or not.
+	switch opts.TypeMode {
+	case autoType:
+		switch t.Kind() {
+		case reflect.Struct, reflect.Slice, reflect.Array, reflect.Map:
+			if s.Equal(textNil) {
+				return s
+			}
+		default:
+			return s
+		}
+	case elideType:
+		return s
+	}
+
+	// Determine the type label, applying special handling for unnamed types.
+	typeName := t.String()
+	if t.Name() == "" {
+		// According to Go grammar, certain type literals contain symbols that
+		// do not strongly bind to the next lexicographical token (e.g., *T).
+		switch t.Kind() {
+		case reflect.Chan, reflect.Func, reflect.Ptr:
+			typeName = "(" + typeName + ")"
+		}
+		typeName = strings.Replace(typeName, "struct {", "struct{", -1)
+		typeName = strings.Replace(typeName, "interface {", "interface{", -1)
+	}
+
+	// Avoid wrap the value in parenthesis if unnecessary.
+	if s, ok := s.(textWrap); ok {
+		hasParens := strings.HasPrefix(s.Prefix, "(") && strings.HasSuffix(s.Suffix, ")")
+		hasBraces := strings.HasPrefix(s.Prefix, "{") && strings.HasSuffix(s.Suffix, "}")
+		if hasParens || hasBraces {
+			return textWrap{typeName, s, ""}
+		}
+	}
+	return textWrap{typeName + "(", s, ")"}
+}
+
+// FormatValue prints the reflect.Value, taking extra care to avoid descending
+// into pointers already in m. As pointers are visited, m is also updated.
+func (opts formatOptions) FormatValue(v reflect.Value, m visitedPointers) (out textNode) {
+	if !v.IsValid() {
+		return nil
+	}
+	t := v.Type()
+
+	// Check whether there is an Error or String method to call.
+	if !opts.AvoidStringer && v.CanInterface() {
+		// Avoid calling Error or String methods on nil receivers since many
+		// implementations crash when doing so.
+		if (t.Kind() != reflect.Ptr && t.Kind() != reflect.Interface) || !v.IsNil() {
+			switch v := v.Interface().(type) {
+			case error:
+				return textLine("e" + formatString(v.Error()))
+			case fmt.Stringer:
+				return textLine("s" + formatString(v.String()))
+			}
+		}
+	}
+
+	// Check whether to explicitly wrap the result with the type.
+	var skipType bool
+	defer func() {
+		if !skipType {
+			out = opts.FormatType(t, out)
+		}
+	}()
+
+	var ptr string
+	switch t.Kind() {
+	case reflect.Bool:
+		return textLine(fmt.Sprint(v.Bool()))
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return textLine(fmt.Sprint(v.Int()))
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		// Unnamed uints are usually bytes or words, so use hexadecimal.
+		if t.PkgPath() == "" || t.Kind() == reflect.Uintptr {
+			return textLine(formatHex(v.Uint()))
+		}
+		return textLine(fmt.Sprint(v.Uint()))
+	case reflect.Float32, reflect.Float64:
+		return textLine(fmt.Sprint(v.Float()))
+	case reflect.Complex64, reflect.Complex128:
+		return textLine(fmt.Sprint(v.Complex()))
+	case reflect.String:
+		return textLine(formatString(v.String()))
+	case reflect.UnsafePointer, reflect.Chan, reflect.Func:
+		return textLine(formatPointer(v))
+	case reflect.Struct:
+		var list textList
+		for i := 0; i < v.NumField(); i++ {
+			vv := v.Field(i)
+			if value.IsZero(vv) {
+				continue // Elide fields with zero values
+			}
+			s := opts.WithTypeMode(autoType).FormatValue(vv, m)
+			list = append(list, textRecord{Key: t.Field(i).Name, Value: s})
+		}
+		return textWrap{"{", list, "}"}
+	case reflect.Slice:
+		if v.IsNil() {
+			return textNil
+		}
+		if opts.PrintAddresses {
+			ptr = formatPointer(v)
+		}
+		fallthrough
+	case reflect.Array:
+		var list textList
+		for i := 0; i < v.Len(); i++ {
+			vi := v.Index(i)
+			if vi.CanAddr() { // Check for cyclic elements
+				p := vi.Addr()
+				if m.Visit(p) {
+					var out textNode
+					out = textLine(formatPointer(p))
+					out = opts.WithTypeMode(emitType).FormatType(p.Type(), out)
+					out = textWrap{"*", out, ""}
+					list = append(list, textRecord{Value: out})
+					continue
+				}
+			}
+			s := opts.WithTypeMode(elideType).FormatValue(vi, m)
+			list = append(list, textRecord{Value: s})
+		}
+		return textWrap{ptr + "{", list, "}"}
+	case reflect.Map:
+		if v.IsNil() {
+			return textNil
+		}
+		if m.Visit(v) {
+			return textLine(formatPointer(v))
+		}
+
+		var list textList
+		for _, k := range value.SortKeys(v.MapKeys()) {
+			sk := formatMapKey(k)
+			sv := opts.WithTypeMode(elideType).FormatValue(v.MapIndex(k), m)
+			list = append(list, textRecord{Key: sk, Value: sv})
+		}
+		if opts.PrintAddresses {
+			ptr = formatPointer(v)
+		}
+		return textWrap{ptr + "{", list, "}"}
+	case reflect.Ptr:
+		if v.IsNil() {
+			return textNil
+		}
+		if m.Visit(v) || opts.ShallowPointers {
+			return textLine(formatPointer(v))
+		}
+		if opts.PrintAddresses {
+			ptr = formatPointer(v)
+		}
+		skipType = true // Let the underlying value print the type instead
+		return textWrap{"&" + ptr, opts.FormatValue(v.Elem(), m), ""}
+	case reflect.Interface:
+		if v.IsNil() {
+			return textNil
+		}
+		// Interfaces accept different concrete types,
+		// so configure the underlying value to explicitly print the type.
+		skipType = true // Print the concrete type instead
+		return opts.WithTypeMode(emitType).FormatValue(v.Elem(), m)
+	default:
+		panic(fmt.Sprintf("%v kind not handled", v.Kind()))
+	}
+}
+
+// formatMapKey formats v as if it were a map key.
+// The result is guaranteed to be a single line.
+func formatMapKey(v reflect.Value) string {
+	var opts formatOptions
+	opts.TypeMode = elideType
+	opts.ShallowPointers = true
+	s := opts.FormatValue(v, visitedPointers{}).String()
+	return strings.TrimSpace(s)
+}
+
+// formatString prints s as a double-quoted or backtick-quoted string.
+func formatString(s string) string {
+	// Use quoted string if it the same length as a raw string literal.
+	// Otherwise, attempt to use the raw string form.
+	qs := strconv.Quote(s)
+	if len(qs) == 1+len(s)+1 {
+		return qs
+	}
+
+	// Disallow newlines to ensure output is a single line.
+	// Only allow printable runes for readability purposes.
+	rawInvalid := func(r rune) bool {
+		return r == '`' || r == '\n' || !(unicode.IsPrint(r) || r == '\t')
+	}
+	if strings.IndexFunc(s, rawInvalid) < 0 {
+		return "`" + s + "`"
+	}
+	return qs
+}
+
+// formatHex prints u as a hexadecimal integer in Go notation.
+func formatHex(u uint64) string {
+	var f string
+	switch {
+	case u <= 0xff:
+		f = "0x%02x"
+	case u <= 0xffff:
+		f = "0x%04x"
+	case u <= 0xffffff:
+		f = "0x%06x"
+	case u <= 0xffffffff:
+		f = "0x%08x"
+	case u <= 0xffffffffff:
+		f = "0x%010x"
+	case u <= 0xffffffffffff:
+		f = "0x%012x"
+	case u <= 0xffffffffffffff:
+		f = "0x%014x"
+	case u <= 0xffffffffffffffff:
+		f = "0x%016x"
+	}
+	return fmt.Sprintf(f, u)
+}
+
+// formatPointer prints the address of the pointer.
+func formatPointer(v reflect.Value) string {
+	p := v.Pointer()
+	if flags.Deterministic {
+		p = 0xdeadf00f // Only used for stable testing purposes
+	}
+	return fmt.Sprintf("⟪0x%x⟫", p)
+}
+
+type visitedPointers map[value.Pointer]struct{}
+
+// Visit inserts pointer v into the visited map and reports whether it had
+// already been visited before.
+func (m visitedPointers) Visit(v reflect.Value) bool {
+	p := value.PointerOf(v)
+	_, visited := m[p]
+	m[p] = struct{}{}
+	return visited
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/report_slices.go b/vendor/github.com/google/go-cmp/cmp/report_slices.go
new file mode 100644
index 0000000..eafcf2e
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/report_slices.go
@@ -0,0 +1,333 @@
+// Copyright 2019, 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.md file.
+
+package cmp
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"github.com/google/go-cmp/cmp/internal/diff"
+)
+
+// CanFormatDiffSlice reports whether we support custom formatting for nodes
+// that are slices of primitive kinds or strings.
+func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool {
+	switch {
+	case opts.DiffMode != diffUnknown:
+		return false // Must be formatting in diff mode
+	case v.NumDiff == 0:
+		return false // No differences detected
+	case v.NumIgnored+v.NumCompared+v.NumTransformed > 0:
+		// TODO: Handle the case where someone uses bytes.Equal on a large slice.
+		return false // Some custom option was used to determined equality
+	case !v.ValueX.IsValid() || !v.ValueY.IsValid():
+		return false // Both values must be valid
+	}
+
+	switch t := v.Type; t.Kind() {
+	case reflect.String:
+	case reflect.Array, reflect.Slice:
+		// Only slices of primitive types have specialized handling.
+		switch t.Elem().Kind() {
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
+			reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
+		default:
+			return false
+		}
+
+		// If a sufficient number of elements already differ,
+		// use specialized formatting even if length requirement is not met.
+		if v.NumDiff > v.NumSame {
+			return true
+		}
+	default:
+		return false
+	}
+
+	// Use specialized string diffing for longer slices or strings.
+	const minLength = 64
+	return v.ValueX.Len() >= minLength && v.ValueY.Len() >= minLength
+}
+
+// FormatDiffSlice prints a diff for the slices (or strings) represented by v.
+// This provides custom-tailored logic to make printing of differences in
+// textual strings and slices of primitive kinds more readable.
+func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
+	assert(opts.DiffMode == diffUnknown)
+	t, vx, vy := v.Type, v.ValueX, v.ValueY
+
+	// Auto-detect the type of the data.
+	var isLinedText, isText, isBinary bool
+	var sx, sy string
+	switch {
+	case t.Kind() == reflect.String:
+		sx, sy = vx.String(), vy.String()
+		isText = true // Initial estimate, verify later
+	case t.Kind() == reflect.Slice && t.Elem() == reflect.TypeOf(byte(0)):
+		sx, sy = string(vx.Bytes()), string(vy.Bytes())
+		isBinary = true // Initial estimate, verify later
+	case t.Kind() == reflect.Array:
+		// Arrays need to be addressable for slice operations to work.
+		vx2, vy2 := reflect.New(t).Elem(), reflect.New(t).Elem()
+		vx2.Set(vx)
+		vy2.Set(vy)
+		vx, vy = vx2, vy2
+	}
+	if isText || isBinary {
+		var numLines, lastLineIdx, maxLineLen int
+		isBinary = false
+		for i, r := range sx + sy {
+			if !(unicode.IsPrint(r) || unicode.IsSpace(r)) || r == utf8.RuneError {
+				isBinary = true
+				break
+			}
+			if r == '\n' {
+				if maxLineLen < i-lastLineIdx {
+					maxLineLen = i - lastLineIdx
+				}
+				lastLineIdx = i + 1
+				numLines++
+			}
+		}
+		isText = !isBinary
+		isLinedText = isText && numLines >= 4 && maxLineLen <= 256
+	}
+
+	// Format the string into printable records.
+	var list textList
+	var delim string
+	switch {
+	// If the text appears to be multi-lined text,
+	// then perform differencing across individual lines.
+	case isLinedText:
+		ssx := strings.Split(sx, "\n")
+		ssy := strings.Split(sy, "\n")
+		list = opts.formatDiffSlice(
+			reflect.ValueOf(ssx), reflect.ValueOf(ssy), 1, "line",
+			func(v reflect.Value, d diffMode) textRecord {
+				s := formatString(v.Index(0).String())
+				return textRecord{Diff: d, Value: textLine(s)}
+			},
+		)
+		delim = "\n"
+	// If the text appears to be single-lined text,
+	// then perform differencing in approximately fixed-sized chunks.
+	// The output is printed as quoted strings.
+	case isText:
+		list = opts.formatDiffSlice(
+			reflect.ValueOf(sx), reflect.ValueOf(sy), 64, "byte",
+			func(v reflect.Value, d diffMode) textRecord {
+				s := formatString(v.String())
+				return textRecord{Diff: d, Value: textLine(s)}
+			},
+		)
+		delim = ""
+	// If the text appears to be binary data,
+	// then perform differencing in approximately fixed-sized chunks.
+	// The output is inspired by hexdump.
+	case isBinary:
+		list = opts.formatDiffSlice(
+			reflect.ValueOf(sx), reflect.ValueOf(sy), 16, "byte",
+			func(v reflect.Value, d diffMode) textRecord {
+				var ss []string
+				for i := 0; i < v.Len(); i++ {
+					ss = append(ss, formatHex(v.Index(i).Uint()))
+				}
+				s := strings.Join(ss, ", ")
+				comment := commentString(fmt.Sprintf("%c|%v|", d, formatASCII(v.String())))
+				return textRecord{Diff: d, Value: textLine(s), Comment: comment}
+			},
+		)
+	// For all other slices of primitive types,
+	// then perform differencing in approximately fixed-sized chunks.
+	// The size of each chunk depends on the width of the element kind.
+	default:
+		var chunkSize int
+		if t.Elem().Kind() == reflect.Bool {
+			chunkSize = 16
+		} else {
+			switch t.Elem().Bits() {
+			case 8:
+				chunkSize = 16
+			case 16:
+				chunkSize = 12
+			case 32:
+				chunkSize = 8
+			default:
+				chunkSize = 8
+			}
+		}
+		list = opts.formatDiffSlice(
+			vx, vy, chunkSize, t.Elem().Kind().String(),
+			func(v reflect.Value, d diffMode) textRecord {
+				var ss []string
+				for i := 0; i < v.Len(); i++ {
+					switch t.Elem().Kind() {
+					case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+						ss = append(ss, fmt.Sprint(v.Index(i).Int()))
+					case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+						ss = append(ss, formatHex(v.Index(i).Uint()))
+					case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
+						ss = append(ss, fmt.Sprint(v.Index(i).Interface()))
+					}
+				}
+				s := strings.Join(ss, ", ")
+				return textRecord{Diff: d, Value: textLine(s)}
+			},
+		)
+	}
+
+	// Wrap the output with appropriate type information.
+	var out textNode = textWrap{"{", list, "}"}
+	if !isText {
+		// The "{...}" byte-sequence literal is not valid Go syntax for strings.
+		// Emit the type for extra clarity (e.g. "string{...}").
+		if t.Kind() == reflect.String {
+			opts = opts.WithTypeMode(emitType)
+		}
+		return opts.FormatType(t, out)
+	}
+	switch t.Kind() {
+	case reflect.String:
+		out = textWrap{"strings.Join(", out, fmt.Sprintf(", %q)", delim)}
+		if t != reflect.TypeOf(string("")) {
+			out = opts.FormatType(t, out)
+		}
+	case reflect.Slice:
+		out = textWrap{"bytes.Join(", out, fmt.Sprintf(", %q)", delim)}
+		if t != reflect.TypeOf([]byte(nil)) {
+			out = opts.FormatType(t, out)
+		}
+	}
+	return out
+}
+
+// formatASCII formats s as an ASCII string.
+// This is useful for printing binary strings in a semi-legible way.
+func formatASCII(s string) string {
+	b := bytes.Repeat([]byte{'.'}, len(s))
+	for i := 0; i < len(s); i++ {
+		if ' ' <= s[i] && s[i] <= '~' {
+			b[i] = s[i]
+		}
+	}
+	return string(b)
+}
+
+func (opts formatOptions) formatDiffSlice(
+	vx, vy reflect.Value, chunkSize int, name string,
+	makeRec func(reflect.Value, diffMode) textRecord,
+) (list textList) {
+	es := diff.Difference(vx.Len(), vy.Len(), func(ix int, iy int) diff.Result {
+		return diff.BoolResult(vx.Index(ix).Interface() == vy.Index(iy).Interface())
+	})
+
+	appendChunks := func(v reflect.Value, d diffMode) int {
+		n0 := v.Len()
+		for v.Len() > 0 {
+			n := chunkSize
+			if n > v.Len() {
+				n = v.Len()
+			}
+			list = append(list, makeRec(v.Slice(0, n), d))
+			v = v.Slice(n, v.Len())
+		}
+		return n0 - v.Len()
+	}
+
+	groups := coalesceAdjacentEdits(name, es)
+	groups = coalesceInterveningIdentical(groups, chunkSize/4)
+	for i, ds := range groups {
+		// Print equal.
+		if ds.NumDiff() == 0 {
+			// Compute the number of leading and trailing equal bytes to print.
+			var numLo, numHi int
+			numEqual := ds.NumIgnored + ds.NumIdentical
+			for numLo < chunkSize*numContextRecords && numLo+numHi < numEqual && i != 0 {
+				numLo++
+			}
+			for numHi < chunkSize*numContextRecords && numLo+numHi < numEqual && i != len(groups)-1 {
+				numHi++
+			}
+			if numEqual-(numLo+numHi) <= chunkSize && ds.NumIgnored == 0 {
+				numHi = numEqual - numLo // Avoid pointless coalescing of single equal row
+			}
+
+			// Print the equal bytes.
+			appendChunks(vx.Slice(0, numLo), diffIdentical)
+			if numEqual > numLo+numHi {
+				ds.NumIdentical -= numLo + numHi
+				list.AppendEllipsis(ds)
+			}
+			appendChunks(vx.Slice(numEqual-numHi, numEqual), diffIdentical)
+			vx = vx.Slice(numEqual, vx.Len())
+			vy = vy.Slice(numEqual, vy.Len())
+			continue
+		}
+
+		// Print unequal.
+		nx := appendChunks(vx.Slice(0, ds.NumIdentical+ds.NumRemoved+ds.NumModified), diffRemoved)
+		vx = vx.Slice(nx, vx.Len())
+		ny := appendChunks(vy.Slice(0, ds.NumIdentical+ds.NumInserted+ds.NumModified), diffInserted)
+		vy = vy.Slice(ny, vy.Len())
+	}
+	assert(vx.Len() == 0 && vy.Len() == 0)
+	return list
+}
+
+// coalesceAdjacentEdits coalesces the list of edits into groups of adjacent
+// equal or unequal counts.
+func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) {
+	var prevCase int // Arbitrary index into which case last occurred
+	lastStats := func(i int) *diffStats {
+		if prevCase != i {
+			groups = append(groups, diffStats{Name: name})
+			prevCase = i
+		}
+		return &groups[len(groups)-1]
+	}
+	for _, e := range es {
+		switch e {
+		case diff.Identity:
+			lastStats(1).NumIdentical++
+		case diff.UniqueX:
+			lastStats(2).NumRemoved++
+		case diff.UniqueY:
+			lastStats(2).NumInserted++
+		case diff.Modified:
+			lastStats(2).NumModified++
+		}
+	}
+	return groups
+}
+
+// coalesceInterveningIdentical coalesces sufficiently short (<= windowSize)
+// equal groups into adjacent unequal groups that currently result in a
+// dual inserted/removed printout. This acts as a high-pass filter to smooth
+// out high-frequency changes within the windowSize.
+func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats {
+	groups, groupsOrig := groups[:0], groups
+	for i, ds := range groupsOrig {
+		if len(groups) >= 2 && ds.NumDiff() > 0 {
+			prev := &groups[len(groups)-2] // Unequal group
+			curr := &groups[len(groups)-1] // Equal group
+			next := &groupsOrig[i]         // Unequal group
+			hadX, hadY := prev.NumRemoved > 0, prev.NumInserted > 0
+			hasX, hasY := next.NumRemoved > 0, next.NumInserted > 0
+			if ((hadX || hasX) && (hadY || hasY)) && curr.NumIdentical <= windowSize {
+				*prev = prev.Append(*curr).Append(*next)
+				groups = groups[:len(groups)-1] // Truncate off equal group
+				continue
+			}
+		}
+		groups = append(groups, ds)
+	}
+	return groups
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/report_text.go b/vendor/github.com/google/go-cmp/cmp/report_text.go
new file mode 100644
index 0000000..8b8fcab
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/report_text.go
@@ -0,0 +1,387 @@
+// Copyright 2019, 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.md file.
+
+package cmp
+
+import (
+	"bytes"
+	"fmt"
+	"math/rand"
+	"strings"
+	"time"
+
+	"github.com/google/go-cmp/cmp/internal/flags"
+)
+
+var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0
+
+type indentMode int
+
+func (n indentMode) appendIndent(b []byte, d diffMode) []byte {
+	// The output of Diff is documented as being unstable to provide future
+	// flexibility in changing the output for more humanly readable reports.
+	// This logic intentionally introduces instability to the exact output
+	// so that users can detect accidental reliance on stability early on,
+	// rather than much later when an actual change to the format occurs.
+	if flags.Deterministic || randBool {
+		// Use regular spaces (U+0020).
+		switch d {
+		case diffUnknown, diffIdentical:
+			b = append(b, "  "...)
+		case diffRemoved:
+			b = append(b, "- "...)
+		case diffInserted:
+			b = append(b, "+ "...)
+		}
+	} else {
+		// Use non-breaking spaces (U+00a0).
+		switch d {
+		case diffUnknown, diffIdentical:
+			b = append(b, "  "...)
+		case diffRemoved:
+			b = append(b, "- "...)
+		case diffInserted:
+			b = append(b, "+ "...)
+		}
+	}
+	return repeatCount(n).appendChar(b, '\t')
+}
+
+type repeatCount int
+
+func (n repeatCount) appendChar(b []byte, c byte) []byte {
+	for ; n > 0; n-- {
+		b = append(b, c)
+	}
+	return b
+}
+
+// textNode is a simplified tree-based representation of structured text.
+// Possible node types are textWrap, textList, or textLine.
+type textNode interface {
+	// Len reports the length in bytes of a single-line version of the tree.
+	// Nested textRecord.Diff and textRecord.Comment fields are ignored.
+	Len() int
+	// Equal reports whether the two trees are structurally identical.
+	// Nested textRecord.Diff and textRecord.Comment fields are compared.
+	Equal(textNode) bool
+	// String returns the string representation of the text tree.
+	// It is not guaranteed that len(x.String()) == x.Len(),
+	// nor that x.String() == y.String() implies that x.Equal(y).
+	String() string
+
+	// formatCompactTo formats the contents of the tree as a single-line string
+	// to the provided buffer. Any nested textRecord.Diff and textRecord.Comment
+	// fields are ignored.
+	//
+	// However, not all nodes in the tree should be collapsed as a single-line.
+	// If a node can be collapsed as a single-line, it is replaced by a textLine
+	// node. Since the top-level node cannot replace itself, this also returns
+	// the current node itself.
+	//
+	// This does not mutate the receiver.
+	formatCompactTo([]byte, diffMode) ([]byte, textNode)
+	// formatExpandedTo formats the contents of the tree as a multi-line string
+	// to the provided buffer. In order for column alignment to operate well,
+	// formatCompactTo must be called before calling formatExpandedTo.
+	formatExpandedTo([]byte, diffMode, indentMode) []byte
+}
+
+// textWrap is a wrapper that concatenates a prefix and/or a suffix
+// to the underlying node.
+type textWrap struct {
+	Prefix string   // e.g., "bytes.Buffer{"
+	Value  textNode // textWrap | textList | textLine
+	Suffix string   // e.g., "}"
+}
+
+func (s textWrap) Len() int {
+	return len(s.Prefix) + s.Value.Len() + len(s.Suffix)
+}
+func (s1 textWrap) Equal(s2 textNode) bool {
+	if s2, ok := s2.(textWrap); ok {
+		return s1.Prefix == s2.Prefix && s1.Value.Equal(s2.Value) && s1.Suffix == s2.Suffix
+	}
+	return false
+}
+func (s textWrap) String() string {
+	var d diffMode
+	var n indentMode
+	_, s2 := s.formatCompactTo(nil, d)
+	b := n.appendIndent(nil, d)      // Leading indent
+	b = s2.formatExpandedTo(b, d, n) // Main body
+	b = append(b, '\n')              // Trailing newline
+	return string(b)
+}
+func (s textWrap) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) {
+	n0 := len(b) // Original buffer length
+	b = append(b, s.Prefix...)
+	b, s.Value = s.Value.formatCompactTo(b, d)
+	b = append(b, s.Suffix...)
+	if _, ok := s.Value.(textLine); ok {
+		return b, textLine(b[n0:])
+	}
+	return b, s
+}
+func (s textWrap) formatExpandedTo(b []byte, d diffMode, n indentMode) []byte {
+	b = append(b, s.Prefix...)
+	b = s.Value.formatExpandedTo(b, d, n)
+	b = append(b, s.Suffix...)
+	return b
+}
+
+// textList is a comma-separated list of textWrap or textLine nodes.
+// The list may be formatted as multi-lines or single-line at the discretion
+// of the textList.formatCompactTo method.
+type textList []textRecord
+type textRecord struct {
+	Diff    diffMode     // e.g., 0 or '-' or '+'
+	Key     string       // e.g., "MyField"
+	Value   textNode     // textWrap | textLine
+	Comment fmt.Stringer // e.g., "6 identical fields"
+}
+
+// AppendEllipsis appends a new ellipsis node to the list if none already
+// exists at the end. If cs is non-zero it coalesces the statistics with the
+// previous diffStats.
+func (s *textList) AppendEllipsis(ds diffStats) {
+	hasStats := ds != diffStats{}
+	if len(*s) == 0 || !(*s)[len(*s)-1].Value.Equal(textEllipsis) {
+		if hasStats {
+			*s = append(*s, textRecord{Value: textEllipsis, Comment: ds})
+		} else {
+			*s = append(*s, textRecord{Value: textEllipsis})
+		}
+		return
+	}
+	if hasStats {
+		(*s)[len(*s)-1].Comment = (*s)[len(*s)-1].Comment.(diffStats).Append(ds)
+	}
+}
+
+func (s textList) Len() (n int) {
+	for i, r := range s {
+		n += len(r.Key)
+		if r.Key != "" {
+			n += len(": ")
+		}
+		n += r.Value.Len()
+		if i < len(s)-1 {
+			n += len(", ")
+		}
+	}
+	return n
+}
+
+func (s1 textList) Equal(s2 textNode) bool {
+	if s2, ok := s2.(textList); ok {
+		if len(s1) != len(s2) {
+			return false
+		}
+		for i := range s1 {
+			r1, r2 := s1[i], s2[i]
+			if !(r1.Diff == r2.Diff && r1.Key == r2.Key && r1.Value.Equal(r2.Value) && r1.Comment == r2.Comment) {
+				return false
+			}
+		}
+		return true
+	}
+	return false
+}
+
+func (s textList) String() string {
+	return textWrap{"{", s, "}"}.String()
+}
+
+func (s textList) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) {
+	s = append(textList(nil), s...) // Avoid mutating original
+
+	// Determine whether we can collapse this list as a single line.
+	n0 := len(b) // Original buffer length
+	var multiLine bool
+	for i, r := range s {
+		if r.Diff == diffInserted || r.Diff == diffRemoved {
+			multiLine = true
+		}
+		b = append(b, r.Key...)
+		if r.Key != "" {
+			b = append(b, ": "...)
+		}
+		b, s[i].Value = r.Value.formatCompactTo(b, d|r.Diff)
+		if _, ok := s[i].Value.(textLine); !ok {
+			multiLine = true
+		}
+		if r.Comment != nil {
+			multiLine = true
+		}
+		if i < len(s)-1 {
+			b = append(b, ", "...)
+		}
+	}
+	// Force multi-lined output when printing a removed/inserted node that
+	// is sufficiently long.
+	if (d == diffInserted || d == diffRemoved) && len(b[n0:]) > 80 {
+		multiLine = true
+	}
+	if !multiLine {
+		return b, textLine(b[n0:])
+	}
+	return b, s
+}
+
+func (s textList) formatExpandedTo(b []byte, d diffMode, n indentMode) []byte {
+	alignKeyLens := s.alignLens(
+		func(r textRecord) bool {
+			_, isLine := r.Value.(textLine)
+			return r.Key == "" || !isLine
+		},
+		func(r textRecord) int { return len(r.Key) },
+	)
+	alignValueLens := s.alignLens(
+		func(r textRecord) bool {
+			_, isLine := r.Value.(textLine)
+			return !isLine || r.Value.Equal(textEllipsis) || r.Comment == nil
+		},
+		func(r textRecord) int { return len(r.Value.(textLine)) },
+	)
+
+	// Format the list as a multi-lined output.
+	n++
+	for i, r := range s {
+		b = n.appendIndent(append(b, '\n'), d|r.Diff)
+		if r.Key != "" {
+			b = append(b, r.Key+": "...)
+		}
+		b = alignKeyLens[i].appendChar(b, ' ')
+
+		b = r.Value.formatExpandedTo(b, d|r.Diff, n)
+		if !r.Value.Equal(textEllipsis) {
+			b = append(b, ',')
+		}
+		b = alignValueLens[i].appendChar(b, ' ')
+
+		if r.Comment != nil {
+			b = append(b, " // "+r.Comment.String()...)
+		}
+	}
+	n--
+
+	return n.appendIndent(append(b, '\n'), d)
+}
+
+func (s textList) alignLens(
+	skipFunc func(textRecord) bool,
+	lenFunc func(textRecord) int,
+) []repeatCount {
+	var startIdx, endIdx, maxLen int
+	lens := make([]repeatCount, len(s))
+	for i, r := range s {
+		if skipFunc(r) {
+			for j := startIdx; j < endIdx && j < len(s); j++ {
+				lens[j] = repeatCount(maxLen - lenFunc(s[j]))
+			}
+			startIdx, endIdx, maxLen = i+1, i+1, 0
+		} else {
+			if maxLen < lenFunc(r) {
+				maxLen = lenFunc(r)
+			}
+			endIdx = i + 1
+		}
+	}
+	for j := startIdx; j < endIdx && j < len(s); j++ {
+		lens[j] = repeatCount(maxLen - lenFunc(s[j]))
+	}
+	return lens
+}
+
+// textLine is a single-line segment of text and is always a leaf node
+// in the textNode tree.
+type textLine []byte
+
+var (
+	textNil      = textLine("nil")
+	textEllipsis = textLine("...")
+)
+
+func (s textLine) Len() int {
+	return len(s)
+}
+func (s1 textLine) Equal(s2 textNode) bool {
+	if s2, ok := s2.(textLine); ok {
+		return bytes.Equal([]byte(s1), []byte(s2))
+	}
+	return false
+}
+func (s textLine) String() string {
+	return string(s)
+}
+func (s textLine) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) {
+	return append(b, s...), s
+}
+func (s textLine) formatExpandedTo(b []byte, _ diffMode, _ indentMode) []byte {
+	return append(b, s...)
+}
+
+type diffStats struct {
+	Name         string
+	NumIgnored   int
+	NumIdentical int
+	NumRemoved   int
+	NumInserted  int
+	NumModified  int
+}
+
+func (s diffStats) NumDiff() int {
+	return s.NumRemoved + s.NumInserted + s.NumModified
+}
+
+func (s diffStats) Append(ds diffStats) diffStats {
+	assert(s.Name == ds.Name)
+	s.NumIgnored += ds.NumIgnored
+	s.NumIdentical += ds.NumIdentical
+	s.NumRemoved += ds.NumRemoved
+	s.NumInserted += ds.NumInserted
+	s.NumModified += ds.NumModified
+	return s
+}
+
+// String prints a humanly-readable summary of coalesced records.
+//
+// Example:
+//	diffStats{Name: "Field", NumIgnored: 5}.String() => "5 ignored fields"
+func (s diffStats) String() string {
+	var ss []string
+	var sum int
+	labels := [...]string{"ignored", "identical", "removed", "inserted", "modified"}
+	counts := [...]int{s.NumIgnored, s.NumIdentical, s.NumRemoved, s.NumInserted, s.NumModified}
+	for i, n := range counts {
+		if n > 0 {
+			ss = append(ss, fmt.Sprintf("%d %v", n, labels[i]))
+		}
+		sum += n
+	}
+
+	// Pluralize the name (adjusting for some obscure English grammar rules).
+	name := s.Name
+	if sum > 1 {
+		name += "s"
+		if strings.HasSuffix(name, "ys") {
+			name = name[:len(name)-2] + "ies" // e.g., "entrys" => "entries"
+		}
+	}
+
+	// Format the list according to English grammar (with Oxford comma).
+	switch n := len(ss); n {
+	case 0:
+		return ""
+	case 1, 2:
+		return strings.Join(ss, " and ") + " " + name
+	default:
+		return strings.Join(ss[:n-1], ", ") + ", and " + ss[n-1] + " " + name
+	}
+}
+
+type commentString string
+
+func (s commentString) String() string { return string(s) }
diff --git a/vendor/github.com/google/go-cmp/cmp/report_value.go b/vendor/github.com/google/go-cmp/cmp/report_value.go
new file mode 100644
index 0000000..83031a7
--- /dev/null
+++ b/vendor/github.com/google/go-cmp/cmp/report_value.go
@@ -0,0 +1,121 @@
+// Copyright 2019, 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.md file.
+
+package cmp
+
+import "reflect"
+
+// valueNode represents a single node within a report, which is a
+// structured representation of the value tree, containing information
+// regarding which nodes are equal or not.
+type valueNode struct {
+	parent *valueNode
+
+	Type   reflect.Type
+	ValueX reflect.Value
+	ValueY reflect.Value
+
+	// NumSame is the number of leaf nodes that are equal.
+	// All descendants are equal only if NumDiff is 0.
+	NumSame int
+	// NumDiff is the number of leaf nodes that are not equal.
+	NumDiff int
+	// NumIgnored is the number of leaf nodes that are ignored.
+	NumIgnored int
+	// NumCompared is the number of leaf nodes that were compared
+	// using an Equal method or Comparer function.
+	NumCompared int
+	// NumTransformed is the number of non-leaf nodes that were transformed.
+	NumTransformed int
+	// NumChildren is the number of transitive descendants of this node.
+	// This counts from zero; thus, leaf nodes have no descendants.
+	NumChildren int
+	// MaxDepth is the maximum depth of the tree. This counts from zero;
+	// thus, leaf nodes have a depth of zero.
+	MaxDepth int
+
+	// Records is a list of struct fields, slice elements, or map entries.
+	Records []reportRecord // If populated, implies Value is not populated
+
+	// Value is the result of a transformation, pointer indirect, of
+	// type assertion.
+	Value *valueNode // If populated, implies Records is not populated
+
+	// TransformerName is the name of the transformer.
+	TransformerName string // If non-empty, implies Value is populated
+}
+type reportRecord struct {
+	Key   reflect.Value // Invalid for slice element
+	Value *valueNode
+}
+
+func (parent *valueNode) PushStep(ps PathStep) (child *valueNode) {
+	vx, vy := ps.Values()
+	child = &valueNode{parent: parent, Type: ps.Type(), ValueX: vx, ValueY: vy}
+	switch s := ps.(type) {
+	case StructField:
+		assert(parent.Value == nil)
+		parent.Records = append(parent.Records, reportRecord{Key: reflect.ValueOf(s.Name()), Value: child})
+	case SliceIndex:
+		assert(parent.Value == nil)
+		parent.Records = append(parent.Records, reportRecord{Value: child})
+	case MapIndex:
+		assert(parent.Value == nil)
+		parent.Records = append(parent.Records, reportRecord{Key: s.Key(), Value: child})
+	case Indirect:
+		assert(parent.Value == nil && parent.Records == nil)
+		parent.Value = child
+	case TypeAssertion:
+		assert(parent.Value == nil && parent.Records == nil)
+		parent.Value = child
+	case Transform:
+		assert(parent.Value == nil && parent.Records == nil)
+		parent.Value = child
+		parent.TransformerName = s.Name()
+		parent.NumTransformed++
+	default:
+		assert(parent == nil) // Must be the root step
+	}
+	return child
+}
+
+func (r *valueNode) Report(rs Result) {
+	assert(r.MaxDepth == 0) // May only be called on leaf nodes
+
+	if rs.ByIgnore() {
+		r.NumIgnored++
+	} else {
+		if rs.Equal() {
+			r.NumSame++
+		} else {
+			r.NumDiff++
+		}
+	}
+	assert(r.NumSame+r.NumDiff+r.NumIgnored == 1)
+
+	if rs.ByMethod() {
+		r.NumCompared++
+	}
+	if rs.ByFunc() {
+		r.NumCompared++
+	}
+	assert(r.NumCompared <= 1)
+}
+
+func (child *valueNode) PopStep() (parent *valueNode) {
+	if child.parent == nil {
+		return nil
+	}
+	parent = child.parent
+	parent.NumSame += child.NumSame
+	parent.NumDiff += child.NumDiff
+	parent.NumIgnored += child.NumIgnored
+	parent.NumCompared += child.NumCompared
+	parent.NumTransformed += child.NumTransformed
+	parent.NumChildren += child.NumChildren + 1
+	if parent.MaxDepth < child.MaxDepth+1 {
+		parent.MaxDepth = child.MaxDepth + 1
+	}
+	return parent
+}
diff --git a/vendor/gotest.tools/LICENSE b/vendor/gotest.tools/LICENSE
new file mode 100644
index 0000000..aeaa2fa
--- /dev/null
+++ b/vendor/gotest.tools/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2018 gotest.tools authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/vendor/gotest.tools/assert/assert.go b/vendor/gotest.tools/assert/assert.go
new file mode 100644
index 0000000..05d6635
--- /dev/null
+++ b/vendor/gotest.tools/assert/assert.go
@@ -0,0 +1,311 @@
+/*Package assert provides assertions for comparing expected values to actual
+values. When an assertion fails a helpful error message is printed.
+
+Assert and Check
+
+Assert() and Check() both accept a Comparison, and fail the test when the
+comparison fails. The one difference is that Assert() will end the test execution
+immediately (using t.FailNow()) whereas Check() will fail the test (using t.Fail()),
+return the value of the comparison, then proceed with the rest of the test case.
+
+Example usage
+
+The example below shows assert used with some common types.
+
+
+	import (
+	    "testing"
+
+	    "gotest.tools/assert"
+	    is "gotest.tools/assert/cmp"
+	)
+
+	func TestEverything(t *testing.T) {
+	    // booleans
+	    assert.Assert(t, ok)
+	    assert.Assert(t, !missing)
+
+	    // primitives
+	    assert.Equal(t, count, 1)
+	    assert.Equal(t, msg, "the message")
+	    assert.Assert(t, total != 10) // NotEqual
+
+	    // errors
+	    assert.NilError(t, closer.Close())
+	    assert.Error(t, err, "the exact error message")
+	    assert.ErrorContains(t, err, "includes this")
+	    assert.ErrorType(t, err, os.IsNotExist)
+
+	    // complex types
+	    assert.DeepEqual(t, result, myStruct{Name: "title"})
+	    assert.Assert(t, is.Len(items, 3))
+	    assert.Assert(t, len(sequence) != 0) // NotEmpty
+	    assert.Assert(t, is.Contains(mapping, "key"))
+
+	    // pointers and interface
+	    assert.Assert(t, is.Nil(ref))
+	    assert.Assert(t, ref != nil) // NotNil
+	}
+
+Comparisons
+
+Package https://godoc.org/gotest.tools/assert/cmp provides
+many common comparisons. Additional comparisons can be written to compare
+values in other ways. See the example Assert (CustomComparison).
+
+Automated migration from testify
+
+gty-migrate-from-testify is a binary which can update source code which uses
+testify assertions to use the assertions provided by this package.
+
+See http://bit.do/cmd-gty-migrate-from-testify.
+
+
+*/
+package assert // import "gotest.tools/assert"
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+
+	gocmp "github.com/google/go-cmp/cmp"
+	"gotest.tools/assert/cmp"
+	"gotest.tools/internal/format"
+	"gotest.tools/internal/source"
+)
+
+// BoolOrComparison can be a bool, or cmp.Comparison. See Assert() for usage.
+type BoolOrComparison interface{}
+
+// TestingT is the subset of testing.T used by the assert package.
+type TestingT interface {
+	FailNow()
+	Fail()
+	Log(args ...interface{})
+}
+
+type helperT interface {
+	Helper()
+}
+
+const failureMessage = "assertion failed: "
+
+// nolint: gocyclo
+func assert(
+	t TestingT,
+	failer func(),
+	argSelector argSelector,
+	comparison BoolOrComparison,
+	msgAndArgs ...interface{},
+) bool {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	var success bool
+	switch check := comparison.(type) {
+	case bool:
+		if check {
+			return true
+		}
+		logFailureFromBool(t, msgAndArgs...)
+
+	// Undocumented legacy comparison without Result type
+	case func() (success bool, message string):
+		success = runCompareFunc(t, check, msgAndArgs...)
+
+	case nil:
+		return true
+
+	case error:
+		msg := "error is not nil: "
+		t.Log(format.WithCustomMessage(failureMessage+msg+check.Error(), msgAndArgs...))
+
+	case cmp.Comparison:
+		success = runComparison(t, argSelector, check, msgAndArgs...)
+
+	case func() cmp.Result:
+		success = runComparison(t, argSelector, check, msgAndArgs...)
+
+	default:
+		t.Log(fmt.Sprintf("invalid Comparison: %v (%T)", check, check))
+	}
+
+	if success {
+		return true
+	}
+	failer()
+	return false
+}
+
+func runCompareFunc(
+	t TestingT,
+	f func() (success bool, message string),
+	msgAndArgs ...interface{},
+) bool {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	if success, message := f(); !success {
+		t.Log(format.WithCustomMessage(failureMessage+message, msgAndArgs...))
+		return false
+	}
+	return true
+}
+
+func logFailureFromBool(t TestingT, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	const stackIndex = 3 // Assert()/Check(), assert(), formatFailureFromBool()
+	const comparisonArgPos = 1
+	args, err := source.CallExprArgs(stackIndex)
+	if err != nil {
+		t.Log(err.Error())
+		return
+	}
+
+	msg, err := boolFailureMessage(args[comparisonArgPos])
+	if err != nil {
+		t.Log(err.Error())
+		msg = "expression is false"
+	}
+
+	t.Log(format.WithCustomMessage(failureMessage+msg, msgAndArgs...))
+}
+
+func boolFailureMessage(expr ast.Expr) (string, error) {
+	if binaryExpr, ok := expr.(*ast.BinaryExpr); ok && binaryExpr.Op == token.NEQ {
+		x, err := source.FormatNode(binaryExpr.X)
+		if err != nil {
+			return "", err
+		}
+		y, err := source.FormatNode(binaryExpr.Y)
+		if err != nil {
+			return "", err
+		}
+		return x + " is " + y, nil
+	}
+
+	if unaryExpr, ok := expr.(*ast.UnaryExpr); ok && unaryExpr.Op == token.NOT {
+		x, err := source.FormatNode(unaryExpr.X)
+		if err != nil {
+			return "", err
+		}
+		return x + " is true", nil
+	}
+
+	formatted, err := source.FormatNode(expr)
+	if err != nil {
+		return "", err
+	}
+	return "expression is false: " + formatted, nil
+}
+
+// Assert performs a comparison. If the comparison fails the test is marked as
+// failed, a failure message is logged, and execution is stopped immediately.
+//
+// The comparison argument may be one of three types: bool, cmp.Comparison or
+// error.
+// When called with a bool the failure message will contain the literal source
+// code of the expression.
+// When called with a cmp.Comparison the comparison is responsible for producing
+// a helpful failure message.
+// When called with an error a nil value is considered success. A non-nil error
+// is a failure, and Error() is used as the failure message.
+func Assert(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsFromComparisonCall, comparison, msgAndArgs...)
+}
+
+// Check performs a comparison. If the comparison fails the test is marked as
+// failed, a failure message is logged, and Check returns false. Otherwise returns
+// true.
+//
+// See Assert for details about the comparison arg and failure messages.
+func Check(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) bool {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	return assert(t, t.Fail, argsFromComparisonCall, comparison, msgAndArgs...)
+}
+
+// NilError fails the test immediately if err is not nil.
+// This is equivalent to Assert(t, err)
+func NilError(t TestingT, err error, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, err, msgAndArgs...)
+}
+
+// Equal uses the == operator to assert two values are equal and fails the test
+// if they are not equal.
+//
+// If the comparison fails Equal will use the variable names for x and y as part
+// of the failure message to identify the actual and expected values.
+//
+// If either x or y are a multi-line string the failure message will include a
+// unified diff of the two values. If the values only differ by whitespace
+// the unified diff will be augmented by replacing whitespace characters with
+// visible characters to identify the whitespace difference.
+//
+// This is equivalent to Assert(t, cmp.Equal(x, y)).
+func Equal(t TestingT, x, y interface{}, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, cmp.Equal(x, y), msgAndArgs...)
+}
+
+// DeepEqual uses google/go-cmp (http://bit.do/go-cmp) to assert two values are
+// equal and fails the test if they are not equal.
+//
+// Package https://godoc.org/gotest.tools/assert/opt provides some additional
+// commonly used Options.
+//
+// This is equivalent to Assert(t, cmp.DeepEqual(x, y)).
+func DeepEqual(t TestingT, x, y interface{}, opts ...gocmp.Option) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, cmp.DeepEqual(x, y, opts...))
+}
+
+// Error fails the test if err is nil, or the error message is not the expected
+// message.
+// Equivalent to Assert(t, cmp.Error(err, message)).
+func Error(t TestingT, err error, message string, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, cmp.Error(err, message), msgAndArgs...)
+}
+
+// ErrorContains fails the test if err is nil, or the error message does not
+// contain the expected substring.
+// Equivalent to Assert(t, cmp.ErrorContains(err, substring)).
+func ErrorContains(t TestingT, err error, substring string, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, cmp.ErrorContains(err, substring), msgAndArgs...)
+}
+
+// ErrorType fails the test if err is nil, or err is not the expected type.
+//
+// Expected can be one of:
+// a func(error) bool which returns true if the error is the expected type,
+// an instance of (or a pointer to) a struct of the expected type,
+// a pointer to an interface the error is expected to implement,
+// a reflect.Type of the expected struct or interface.
+//
+// Equivalent to Assert(t, cmp.ErrorType(err, expected)).
+func ErrorType(t TestingT, err error, expected interface{}, msgAndArgs ...interface{}) {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	assert(t, t.FailNow, argsAfterT, cmp.ErrorType(err, expected), msgAndArgs...)
+}
diff --git a/vendor/gotest.tools/assert/cmp/compare.go b/vendor/gotest.tools/assert/cmp/compare.go
new file mode 100644
index 0000000..cf48d88
--- /dev/null
+++ b/vendor/gotest.tools/assert/cmp/compare.go
@@ -0,0 +1,356 @@
+/*Package cmp provides Comparisons for Assert and Check*/
+package cmp // import "gotest.tools/assert/cmp"
+
+import (
+	"fmt"
+	"reflect"
+	"regexp"
+	"strings"
+
+	"github.com/google/go-cmp/cmp"
+	"gotest.tools/internal/format"
+)
+
+// Comparison is a function which compares values and returns ResultSuccess if
+// the actual value matches the expected value. If the values do not match the
+// Result will contain a message about why it failed.
+type Comparison func() Result
+
+// DeepEqual compares two values using google/go-cmp (http://bit.do/go-cmp)
+// and succeeds if the values are equal.
+//
+// The comparison can be customized using comparison Options.
+// Package https://godoc.org/gotest.tools/assert/opt provides some additional
+// commonly used Options.
+func DeepEqual(x, y interface{}, opts ...cmp.Option) Comparison {
+	return func() (result Result) {
+		defer func() {
+			if panicmsg, handled := handleCmpPanic(recover()); handled {
+				result = ResultFailure(panicmsg)
+			}
+		}()
+		diff := cmp.Diff(x, y, opts...)
+		if diff == "" {
+			return ResultSuccess
+		}
+		return multiLineDiffResult(diff)
+	}
+}
+
+func handleCmpPanic(r interface{}) (string, bool) {
+	if r == nil {
+		return "", false
+	}
+	panicmsg, ok := r.(string)
+	if !ok {
+		panic(r)
+	}
+	switch {
+	case strings.HasPrefix(panicmsg, "cannot handle unexported field"):
+		return panicmsg, true
+	}
+	panic(r)
+}
+
+func toResult(success bool, msg string) Result {
+	if success {
+		return ResultSuccess
+	}
+	return ResultFailure(msg)
+}
+
+// RegexOrPattern may be either a *regexp.Regexp or a string that is a valid
+// regexp pattern.
+type RegexOrPattern interface{}
+
+// Regexp succeeds if value v matches regular expression re.
+//
+// Example:
+//   assert.Assert(t, cmp.Regexp("^[0-9a-f]{32}$", str))
+//   r := regexp.MustCompile("^[0-9a-f]{32}$")
+//   assert.Assert(t, cmp.Regexp(r, str))
+func Regexp(re RegexOrPattern, v string) Comparison {
+	match := func(re *regexp.Regexp) Result {
+		return toResult(
+			re.MatchString(v),
+			fmt.Sprintf("value %q does not match regexp %q", v, re.String()))
+	}
+
+	return func() Result {
+		switch regex := re.(type) {
+		case *regexp.Regexp:
+			return match(regex)
+		case string:
+			re, err := regexp.Compile(regex)
+			if err != nil {
+				return ResultFailure(err.Error())
+			}
+			return match(re)
+		default:
+			return ResultFailure(fmt.Sprintf("invalid type %T for regex pattern", regex))
+		}
+	}
+}
+
+// Equal succeeds if x == y. See assert.Equal for full documentation.
+func Equal(x, y interface{}) Comparison {
+	return func() Result {
+		switch {
+		case x == y:
+			return ResultSuccess
+		case isMultiLineStringCompare(x, y):
+			diff := format.UnifiedDiff(format.DiffConfig{A: x.(string), B: y.(string)})
+			return multiLineDiffResult(diff)
+		}
+		return ResultFailureTemplate(`
+			{{- .Data.x}} (
+				{{- with callArg 0 }}{{ formatNode . }} {{end -}}
+				{{- printf "%T" .Data.x -}}
+			) != {{ .Data.y}} (
+				{{- with callArg 1 }}{{ formatNode . }} {{end -}}
+				{{- printf "%T" .Data.y -}}
+			)`,
+			map[string]interface{}{"x": x, "y": y})
+	}
+}
+
+func isMultiLineStringCompare(x, y interface{}) bool {
+	strX, ok := x.(string)
+	if !ok {
+		return false
+	}
+	strY, ok := y.(string)
+	if !ok {
+		return false
+	}
+	return strings.Contains(strX, "\n") || strings.Contains(strY, "\n")
+}
+
+func multiLineDiffResult(diff string) Result {
+	return ResultFailureTemplate(`
+--- {{ with callArg 0 }}{{ formatNode . }}{{else}}←{{end}}
++++ {{ with callArg 1 }}{{ formatNode . }}{{else}}→{{end}}
+{{ .Data.diff }}`,
+		map[string]interface{}{"diff": diff})
+}
+
+// Len succeeds if the sequence has the expected length.
+func Len(seq interface{}, expected int) Comparison {
+	return func() (result Result) {
+		defer func() {
+			if e := recover(); e != nil {
+				result = ResultFailure(fmt.Sprintf("type %T does not have a length", seq))
+			}
+		}()
+		value := reflect.ValueOf(seq)
+		length := value.Len()
+		if length == expected {
+			return ResultSuccess
+		}
+		msg := fmt.Sprintf("expected %s (length %d) to have length %d", seq, length, expected)
+		return ResultFailure(msg)
+	}
+}
+
+// Contains succeeds if item is in collection. Collection may be a string, map,
+// slice, or array.
+//
+// If collection is a string, item must also be a string, and is compared using
+// strings.Contains().
+// If collection is a Map, contains will succeed if item is a key in the map.
+// If collection is a slice or array, item is compared to each item in the
+// sequence using reflect.DeepEqual().
+func Contains(collection interface{}, item interface{}) Comparison {
+	return func() Result {
+		colValue := reflect.ValueOf(collection)
+		if !colValue.IsValid() {
+			return ResultFailure(fmt.Sprintf("nil does not contain items"))
+		}
+		msg := fmt.Sprintf("%v does not contain %v", collection, item)
+
+		itemValue := reflect.ValueOf(item)
+		switch colValue.Type().Kind() {
+		case reflect.String:
+			if itemValue.Type().Kind() != reflect.String {
+				return ResultFailure("string may only contain strings")
+			}
+			return toResult(
+				strings.Contains(colValue.String(), itemValue.String()),
+				fmt.Sprintf("string %q does not contain %q", collection, item))
+
+		case reflect.Map:
+			if itemValue.Type() != colValue.Type().Key() {
+				return ResultFailure(fmt.Sprintf(
+					"%v can not contain a %v key", colValue.Type(), itemValue.Type()))
+			}
+			return toResult(colValue.MapIndex(itemValue).IsValid(), msg)
+
+		case reflect.Slice, reflect.Array:
+			for i := 0; i < colValue.Len(); i++ {
+				if reflect.DeepEqual(colValue.Index(i).Interface(), item) {
+					return ResultSuccess
+				}
+			}
+			return ResultFailure(msg)
+		default:
+			return ResultFailure(fmt.Sprintf("type %T does not contain items", collection))
+		}
+	}
+}
+
+// Panics succeeds if f() panics.
+func Panics(f func()) Comparison {
+	return func() (result Result) {
+		defer func() {
+			if err := recover(); err != nil {
+				result = ResultSuccess
+			}
+		}()
+		f()
+		return ResultFailure("did not panic")
+	}
+}
+
+// Error succeeds if err is a non-nil error, and the error message equals the
+// expected message.
+func Error(err error, message string) Comparison {
+	return func() Result {
+		switch {
+		case err == nil:
+			return ResultFailure("expected an error, got nil")
+		case err.Error() != message:
+			return ResultFailure(fmt.Sprintf(
+				"expected error %q, got %s", message, formatErrorMessage(err)))
+		}
+		return ResultSuccess
+	}
+}
+
+// ErrorContains succeeds if err is a non-nil error, and the error message contains
+// the expected substring.
+func ErrorContains(err error, substring string) Comparison {
+	return func() Result {
+		switch {
+		case err == nil:
+			return ResultFailure("expected an error, got nil")
+		case !strings.Contains(err.Error(), substring):
+			return ResultFailure(fmt.Sprintf(
+				"expected error to contain %q, got %s", substring, formatErrorMessage(err)))
+		}
+		return ResultSuccess
+	}
+}
+
+func formatErrorMessage(err error) string {
+	if _, ok := err.(interface {
+		Cause() error
+	}); ok {
+		return fmt.Sprintf("%q\n%+v", err, err)
+	}
+	// This error was not wrapped with github.com/pkg/errors
+	return fmt.Sprintf("%q", err)
+}
+
+// Nil succeeds if obj is a nil interface, pointer, or function.
+//
+// Use NilError() for comparing errors. Use Len(obj, 0) for comparing slices,
+// maps, and channels.
+func Nil(obj interface{}) Comparison {
+	msgFunc := func(value reflect.Value) string {
+		return fmt.Sprintf("%v (type %s) is not nil", reflect.Indirect(value), value.Type())
+	}
+	return isNil(obj, msgFunc)
+}
+
+func isNil(obj interface{}, msgFunc func(reflect.Value) string) Comparison {
+	return func() Result {
+		if obj == nil {
+			return ResultSuccess
+		}
+		value := reflect.ValueOf(obj)
+		kind := value.Type().Kind()
+		if kind >= reflect.Chan && kind <= reflect.Slice {
+			if value.IsNil() {
+				return ResultSuccess
+			}
+			return ResultFailure(msgFunc(value))
+		}
+
+		return ResultFailure(fmt.Sprintf("%v (type %s) can not be nil", value, value.Type()))
+	}
+}
+
+// ErrorType succeeds if err is not nil and is of the expected type.
+//
+// Expected can be one of:
+// a func(error) bool which returns true if the error is the expected type,
+// an instance of (or a pointer to) a struct of the expected type,
+// a pointer to an interface the error is expected to implement,
+// a reflect.Type of the expected struct or interface.
+func ErrorType(err error, expected interface{}) Comparison {
+	return func() Result {
+		switch expectedType := expected.(type) {
+		case func(error) bool:
+			return cmpErrorTypeFunc(err, expectedType)
+		case reflect.Type:
+			if expectedType.Kind() == reflect.Interface {
+				return cmpErrorTypeImplementsType(err, expectedType)
+			}
+			return cmpErrorTypeEqualType(err, expectedType)
+		case nil:
+			return ResultFailure(fmt.Sprintf("invalid type for expected: nil"))
+		}
+
+		expectedType := reflect.TypeOf(expected)
+		switch {
+		case expectedType.Kind() == reflect.Struct, isPtrToStruct(expectedType):
+			return cmpErrorTypeEqualType(err, expectedType)
+		case isPtrToInterface(expectedType):
+			return cmpErrorTypeImplementsType(err, expectedType.Elem())
+		}
+		return ResultFailure(fmt.Sprintf("invalid type for expected: %T", expected))
+	}
+}
+
+func cmpErrorTypeFunc(err error, f func(error) bool) Result {
+	if f(err) {
+		return ResultSuccess
+	}
+	actual := "nil"
+	if err != nil {
+		actual = fmt.Sprintf("%s (%T)", err, err)
+	}
+	return ResultFailureTemplate(`error is {{ .Data.actual }}
+		{{- with callArg 1 }}, not {{ formatNode . }}{{end -}}`,
+		map[string]interface{}{"actual": actual})
+}
+
+func cmpErrorTypeEqualType(err error, expectedType reflect.Type) Result {
+	if err == nil {
+		return ResultFailure(fmt.Sprintf("error is nil, not %s", expectedType))
+	}
+	errValue := reflect.ValueOf(err)
+	if errValue.Type() == expectedType {
+		return ResultSuccess
+	}
+	return ResultFailure(fmt.Sprintf("error is %s (%T), not %s", err, err, expectedType))
+}
+
+func cmpErrorTypeImplementsType(err error, expectedType reflect.Type) Result {
+	if err == nil {
+		return ResultFailure(fmt.Sprintf("error is nil, not %s", expectedType))
+	}
+	errValue := reflect.ValueOf(err)
+	if errValue.Type().Implements(expectedType) {
+		return ResultSuccess
+	}
+	return ResultFailure(fmt.Sprintf("error is %s (%T), not %s", err, err, expectedType))
+}
+
+func isPtrToInterface(typ reflect.Type) bool {
+	return typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Interface
+}
+
+func isPtrToStruct(typ reflect.Type) bool {
+	return typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct
+}
diff --git a/vendor/gotest.tools/assert/cmp/result.go b/vendor/gotest.tools/assert/cmp/result.go
new file mode 100644
index 0000000..7c3c37d
--- /dev/null
+++ b/vendor/gotest.tools/assert/cmp/result.go
@@ -0,0 +1,94 @@
+package cmp
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"text/template"
+
+	"gotest.tools/internal/source"
+)
+
+// Result of a Comparison.
+type Result interface {
+	Success() bool
+}
+
+type result struct {
+	success bool
+	message string
+}
+
+func (r result) Success() bool {
+	return r.success
+}
+
+func (r result) FailureMessage() string {
+	return r.message
+}
+
+// ResultSuccess is a constant which is returned by a ComparisonWithResult to
+// indicate success.
+var ResultSuccess = result{success: true}
+
+// ResultFailure returns a failed Result with a failure message.
+func ResultFailure(message string) Result {
+	return result{message: message}
+}
+
+// ResultFromError returns ResultSuccess if err is nil. Otherwise ResultFailure
+// is returned with the error message as the failure message.
+func ResultFromError(err error) Result {
+	if err == nil {
+		return ResultSuccess
+	}
+	return ResultFailure(err.Error())
+}
+
+type templatedResult struct {
+	success  bool
+	template string
+	data     map[string]interface{}
+}
+
+func (r templatedResult) Success() bool {
+	return r.success
+}
+
+func (r templatedResult) FailureMessage(args []ast.Expr) string {
+	msg, err := renderMessage(r, args)
+	if err != nil {
+		return fmt.Sprintf("failed to render failure message: %s", err)
+	}
+	return msg
+}
+
+// ResultFailureTemplate returns a Result with a template string and data which
+// can be used to format a failure message. The template may access data from .Data,
+// the comparison args with the callArg function, and the formatNode function may
+// be used to format the call args.
+func ResultFailureTemplate(template string, data map[string]interface{}) Result {
+	return templatedResult{template: template, data: data}
+}
+
+func renderMessage(result templatedResult, args []ast.Expr) (string, error) {
+	tmpl := template.New("failure").Funcs(template.FuncMap{
+		"formatNode": source.FormatNode,
+		"callArg": func(index int) ast.Expr {
+			if index >= len(args) {
+				return nil
+			}
+			return args[index]
+		},
+	})
+	var err error
+	tmpl, err = tmpl.Parse(result.template)
+	if err != nil {
+		return "", err
+	}
+	buf := new(bytes.Buffer)
+	err = tmpl.Execute(buf, map[string]interface{}{
+		"Data": result.data,
+	})
+	return buf.String(), err
+}
diff --git a/vendor/gotest.tools/assert/result.go b/vendor/gotest.tools/assert/result.go
new file mode 100644
index 0000000..949d939
--- /dev/null
+++ b/vendor/gotest.tools/assert/result.go
@@ -0,0 +1,106 @@
+package assert
+
+import (
+	"fmt"
+	"go/ast"
+
+	"gotest.tools/assert/cmp"
+	"gotest.tools/internal/format"
+	"gotest.tools/internal/source"
+)
+
+func runComparison(
+	t TestingT,
+	argSelector argSelector,
+	f cmp.Comparison,
+	msgAndArgs ...interface{},
+) bool {
+	if ht, ok := t.(helperT); ok {
+		ht.Helper()
+	}
+	result := f()
+	if result.Success() {
+		return true
+	}
+
+	var message string
+	switch typed := result.(type) {
+	case resultWithComparisonArgs:
+		const stackIndex = 3 // Assert/Check, assert, runComparison
+		args, err := source.CallExprArgs(stackIndex)
+		if err != nil {
+			t.Log(err.Error())
+		}
+		message = typed.FailureMessage(filterPrintableExpr(argSelector(args)))
+	case resultBasic:
+		message = typed.FailureMessage()
+	default:
+		message = fmt.Sprintf("comparison returned invalid Result type: %T", result)
+	}
+
+	t.Log(format.WithCustomMessage(failureMessage+message, msgAndArgs...))
+	return false
+}
+
+type resultWithComparisonArgs interface {
+	FailureMessage(args []ast.Expr) string
+}
+
+type resultBasic interface {
+	FailureMessage() string
+}
+
+// filterPrintableExpr filters the ast.Expr slice to only include Expr that are
+// easy to read when printed and contain relevant information to an assertion.
+//
+// Ident and SelectorExpr are included because they print nicely and the variable
+// names may provide additional context to their values.
+// BasicLit and CompositeLit are excluded because their source is equivalent to
+// their value, which is already available.
+// Other types are ignored for now, but could be added if they are relevant.
+func filterPrintableExpr(args []ast.Expr) []ast.Expr {
+	result := make([]ast.Expr, len(args))
+	for i, arg := range args {
+		if isShortPrintableExpr(arg) {
+			result[i] = arg
+			continue
+		}
+
+		if starExpr, ok := arg.(*ast.StarExpr); ok {
+			result[i] = starExpr.X
+			continue
+		}
+	}
+	return result
+}
+
+func isShortPrintableExpr(expr ast.Expr) bool {
+	switch expr.(type) {
+	case *ast.Ident, *ast.SelectorExpr, *ast.IndexExpr, *ast.SliceExpr:
+		return true
+	case *ast.BinaryExpr, *ast.UnaryExpr:
+		return true
+	default:
+		// CallExpr, ParenExpr, TypeAssertExpr, KeyValueExpr, StarExpr
+		return false
+	}
+}
+
+type argSelector func([]ast.Expr) []ast.Expr
+
+func argsAfterT(args []ast.Expr) []ast.Expr {
+	if len(args) < 1 {
+		return nil
+	}
+	return args[1:]
+}
+
+func argsFromComparisonCall(args []ast.Expr) []ast.Expr {
+	if len(args) < 1 {
+		return nil
+	}
+	if callExpr, ok := args[1].(*ast.CallExpr); ok {
+		return callExpr.Args
+	}
+	return nil
+}
diff --git a/vendor/gotest.tools/internal/difflib/LICENSE b/vendor/gotest.tools/internal/difflib/LICENSE
new file mode 100644
index 0000000..c67dad6
--- /dev/null
+++ b/vendor/gotest.tools/internal/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/vendor/gotest.tools/internal/difflib/difflib.go b/vendor/gotest.tools/internal/difflib/difflib.go
new file mode 100644
index 0000000..b6f486b
--- /dev/null
+++ b/vendor/gotest.tools/internal/difflib/difflib.go
@@ -0,0 +1,423 @@
+/*Package difflib is a partial port of Python difflib module.
+
+Original source: https://github.com/pmezard/go-difflib
+
+This file is trimmed to only the parts used by this repository.
+*/
+package difflib // import "gotest.tools/internal/difflib"
+
+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
+}
+
+// Match stores line numbers of size of match
+type Match struct {
+	A    int
+	B    int
+	Size int
+}
+
+// OpCode identifies the type of diff
+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
+}
+
+// NewMatcher returns a new SequenceMatcher
+func NewMatcher(a, b []string) *SequenceMatcher {
+	m := SequenceMatcher{autoJunk: true}
+	m.SetSeqs(a, b)
+	return &m
+}
+
+// SetSeqs sets two sequences to be compared.
+func (m *SequenceMatcher) SetSeqs(a, b []string) {
+	m.SetSeq1(a)
+	m.SetSeq2(b)
+}
+
+// SetSeq1 sets 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
+}
+
+// SetSeq2 sets 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}
+}
+
+// GetMatchingBlocks returns a 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
+}
+
+// GetOpCodes returns a 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
+}
+
+// GetGroupedOpCodes isolates 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{{'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
+}
diff --git a/vendor/gotest.tools/internal/format/diff.go b/vendor/gotest.tools/internal/format/diff.go
new file mode 100644
index 0000000..c938c97
--- /dev/null
+++ b/vendor/gotest.tools/internal/format/diff.go
@@ -0,0 +1,161 @@
+package format
+
+import (
+	"bytes"
+	"fmt"
+	"strings"
+	"unicode"
+
+	"gotest.tools/internal/difflib"
+)
+
+const (
+	contextLines = 2
+)
+
+// DiffConfig for a unified diff
+type DiffConfig struct {
+	A    string
+	B    string
+	From string
+	To   string
+}
+
+// UnifiedDiff is a modified version of difflib.WriteUnifiedDiff with better
+// support for showing the whitespace differences.
+func UnifiedDiff(conf DiffConfig) string {
+	a := strings.SplitAfter(conf.A, "\n")
+	b := strings.SplitAfter(conf.B, "\n")
+	groups := difflib.NewMatcher(a, b).GetGroupedOpCodes(contextLines)
+	if len(groups) == 0 {
+		return ""
+	}
+
+	buf := new(bytes.Buffer)
+	writeFormat := func(format string, args ...interface{}) {
+		buf.WriteString(fmt.Sprintf(format, args...))
+	}
+	writeLine := func(prefix string, s string) {
+		buf.WriteString(prefix + s)
+	}
+	if hasWhitespaceDiffLines(groups, a, b) {
+		writeLine = visibleWhitespaceLine(writeLine)
+	}
+	formatHeader(writeFormat, conf)
+	for _, group := range groups {
+		formatRangeLine(writeFormat, group)
+		for _, opCode := range group {
+			in, out := a[opCode.I1:opCode.I2], b[opCode.J1:opCode.J2]
+			switch opCode.Tag {
+			case 'e':
+				formatLines(writeLine, " ", in)
+			case 'r':
+				formatLines(writeLine, "-", in)
+				formatLines(writeLine, "+", out)
+			case 'd':
+				formatLines(writeLine, "-", in)
+			case 'i':
+				formatLines(writeLine, "+", out)
+			}
+		}
+	}
+	return buf.String()
+}
+
+// hasWhitespaceDiffLines returns true if any diff groups is only different
+// because of whitespace characters.
+func hasWhitespaceDiffLines(groups [][]difflib.OpCode, a, b []string) bool {
+	for _, group := range groups {
+		in, out := new(bytes.Buffer), new(bytes.Buffer)
+		for _, opCode := range group {
+			if opCode.Tag == 'e' {
+				continue
+			}
+			for _, line := range a[opCode.I1:opCode.I2] {
+				in.WriteString(line)
+			}
+			for _, line := range b[opCode.J1:opCode.J2] {
+				out.WriteString(line)
+			}
+		}
+		if removeWhitespace(in.String()) == removeWhitespace(out.String()) {
+			return true
+		}
+	}
+	return false
+}
+
+func removeWhitespace(s string) string {
+	var result []rune
+	for _, r := range s {
+		if !unicode.IsSpace(r) {
+			result = append(result, r)
+		}
+	}
+	return string(result)
+}
+
+func visibleWhitespaceLine(ws func(string, string)) func(string, string) {
+	mapToVisibleSpace := func(r rune) rune {
+		switch r {
+		case '\n':
+		case ' ':
+			return '·'
+		case '\t':
+			return '▷'
+		case '\v':
+			return '▽'
+		case '\r':
+			return '↵'
+		case '\f':
+			return '↓'
+		default:
+			if unicode.IsSpace(r) {
+				return '�'
+			}
+		}
+		return r
+	}
+	return func(prefix, s string) {
+		ws(prefix, strings.Map(mapToVisibleSpace, s))
+	}
+}
+
+func formatHeader(wf func(string, ...interface{}), conf DiffConfig) {
+	if conf.From != "" || conf.To != "" {
+		wf("--- %s\n", conf.From)
+		wf("+++ %s\n", conf.To)
+	}
+}
+
+func formatRangeLine(wf func(string, ...interface{}), group []difflib.OpCode) {
+	first, last := group[0], group[len(group)-1]
+	range1 := formatRangeUnified(first.I1, last.I2)
+	range2 := formatRangeUnified(first.J1, last.J2)
+	wf("@@ -%s +%s @@\n", range1, range2)
+}
+
+// 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-- // empty ranges begin at line just before the range
+	}
+	return fmt.Sprintf("%d,%d", beginning, length)
+}
+
+func formatLines(writeLine func(string, string), prefix string, lines []string) {
+	for _, line := range lines {
+		writeLine(prefix, line)
+	}
+	// Add a newline if the last line is missing one so that the diff displays
+	// properly.
+	if !strings.HasSuffix(lines[len(lines)-1], "\n") {
+		writeLine("", "\n")
+	}
+}
diff --git a/vendor/gotest.tools/internal/format/format.go b/vendor/gotest.tools/internal/format/format.go
new file mode 100644
index 0000000..8f6494f
--- /dev/null
+++ b/vendor/gotest.tools/internal/format/format.go
@@ -0,0 +1,27 @@
+package format // import "gotest.tools/internal/format"
+
+import "fmt"
+
+// Message accepts a msgAndArgs varargs and formats it using fmt.Sprintf
+func Message(msgAndArgs ...interface{}) string {
+	switch len(msgAndArgs) {
+	case 0:
+		return ""
+	case 1:
+		return fmt.Sprintf("%v", msgAndArgs[0])
+	default:
+		return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
+	}
+}
+
+// WithCustomMessage accepts one or two messages and formats them appropriately
+func WithCustomMessage(source string, msgAndArgs ...interface{}) string {
+	custom := Message(msgAndArgs...)
+	switch {
+	case custom == "":
+		return source
+	case source == "":
+		return custom
+	}
+	return fmt.Sprintf("%s: %s", source, custom)
+}
diff --git a/vendor/gotest.tools/internal/source/defers.go b/vendor/gotest.tools/internal/source/defers.go
new file mode 100644
index 0000000..66cfafb
--- /dev/null
+++ b/vendor/gotest.tools/internal/source/defers.go
@@ -0,0 +1,53 @@
+package source
+
+import (
+	"go/ast"
+	"go/token"
+
+	"github.com/pkg/errors"
+)
+
+func scanToDeferLine(fileset *token.FileSet, node ast.Node, lineNum int) ast.Node {
+	var matchedNode ast.Node
+	ast.Inspect(node, func(node ast.Node) bool {
+		switch {
+		case node == nil || matchedNode != nil:
+			return false
+		case fileset.Position(node.End()).Line == lineNum:
+			if funcLit, ok := node.(*ast.FuncLit); ok {
+				matchedNode = funcLit
+				return false
+			}
+		}
+		return true
+	})
+	debug("defer line node: %s", debugFormatNode{matchedNode})
+	return matchedNode
+}
+
+func guessDefer(node ast.Node) (ast.Node, error) {
+	defers := collectDefers(node)
+	switch len(defers) {
+	case 0:
+		return nil, errors.New("failed to expression in defer")
+	case 1:
+		return defers[0].Call, nil
+	default:
+		return nil, errors.Errorf(
+			"ambiguous call expression: multiple (%d) defers in call block",
+			len(defers))
+	}
+}
+
+func collectDefers(node ast.Node) []*ast.DeferStmt {
+	var defers []*ast.DeferStmt
+	ast.Inspect(node, func(node ast.Node) bool {
+		if d, ok := node.(*ast.DeferStmt); ok {
+			defers = append(defers, d)
+			debug("defer: %s", debugFormatNode{d})
+			return false
+		}
+		return true
+	})
+	return defers
+}
diff --git a/vendor/gotest.tools/internal/source/source.go b/vendor/gotest.tools/internal/source/source.go
new file mode 100644
index 0000000..8a5d0e8
--- /dev/null
+++ b/vendor/gotest.tools/internal/source/source.go
@@ -0,0 +1,166 @@
+package source // import "gotest.tools/internal/source"
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/parser"
+	"go/token"
+	"os"
+	"runtime"
+	"strconv"
+	"strings"
+
+	"github.com/pkg/errors"
+)
+
+const baseStackIndex = 1
+
+// FormattedCallExprArg returns the argument from an ast.CallExpr at the
+// index in the call stack. The argument is formatted using FormatNode.
+func FormattedCallExprArg(stackIndex int, argPos int) (string, error) {
+	args, err := CallExprArgs(stackIndex + 1)
+	if err != nil {
+		return "", err
+	}
+	if argPos >= len(args) {
+		return "", errors.New("failed to find expression")
+	}
+	return FormatNode(args[argPos])
+}
+
+// CallExprArgs returns the ast.Expr slice for the args of an ast.CallExpr at
+// the index in the call stack.
+func CallExprArgs(stackIndex int) ([]ast.Expr, error) {
+	_, filename, lineNum, ok := runtime.Caller(baseStackIndex + stackIndex)
+	if !ok {
+		return nil, errors.New("failed to get call stack")
+	}
+	debug("call stack position: %s:%d", filename, lineNum)
+
+	node, err := getNodeAtLine(filename, lineNum)
+	if err != nil {
+		return nil, err
+	}
+	debug("found node: %s", debugFormatNode{node})
+
+	return getCallExprArgs(node)
+}
+
+func getNodeAtLine(filename string, lineNum int) (ast.Node, error) {
+	fileset := token.NewFileSet()
+	astFile, err := parser.ParseFile(fileset, filename, nil, parser.AllErrors)
+	if err != nil {
+		return nil, errors.Wrapf(err, "failed to parse source file: %s", filename)
+	}
+
+	if node := scanToLine(fileset, astFile, lineNum); node != nil {
+		return node, nil
+	}
+	if node := scanToDeferLine(fileset, astFile, lineNum); node != nil {
+		node, err := guessDefer(node)
+		if err != nil || node != nil {
+			return node, err
+		}
+	}
+	return nil, errors.Errorf(
+		"failed to find an expression on line %d in %s", lineNum, filename)
+}
+
+func scanToLine(fileset *token.FileSet, node ast.Node, lineNum int) ast.Node {
+	var matchedNode ast.Node
+	ast.Inspect(node, func(node ast.Node) bool {
+		switch {
+		case node == nil || matchedNode != nil:
+			return false
+		case nodePosition(fileset, node).Line == lineNum:
+			matchedNode = node
+			return false
+		}
+		return true
+	})
+	return matchedNode
+}
+
+// In golang 1.9 the line number changed from being the line where the statement
+// ended to the line where the statement began.
+func nodePosition(fileset *token.FileSet, node ast.Node) token.Position {
+	if goVersionBefore19 {
+		return fileset.Position(node.End())
+	}
+	return fileset.Position(node.Pos())
+}
+
+var goVersionBefore19 = func() bool {
+	version := runtime.Version()
+	// not a release version
+	if !strings.HasPrefix(version, "go") {
+		return false
+	}
+	version = strings.TrimPrefix(version, "go")
+	parts := strings.Split(version, ".")
+	if len(parts) < 2 {
+		return false
+	}
+	minor, err := strconv.ParseInt(parts[1], 10, 32)
+	return err == nil && parts[0] == "1" && minor < 9
+}()
+
+func getCallExprArgs(node ast.Node) ([]ast.Expr, error) {
+	visitor := &callExprVisitor{}
+	ast.Walk(visitor, node)
+	if visitor.expr == nil {
+		return nil, errors.New("failed to find call expression")
+	}
+	debug("callExpr: %s", debugFormatNode{visitor.expr})
+	return visitor.expr.Args, nil
+}
+
+type callExprVisitor struct {
+	expr *ast.CallExpr
+}
+
+func (v *callExprVisitor) Visit(node ast.Node) ast.Visitor {
+	if v.expr != nil || node == nil {
+		return nil
+	}
+	debug("visit: %s", debugFormatNode{node})
+
+	switch typed := node.(type) {
+	case *ast.CallExpr:
+		v.expr = typed
+		return nil
+	case *ast.DeferStmt:
+		ast.Walk(v, typed.Call.Fun)
+		return nil
+	}
+	return v
+}
+
+// FormatNode using go/format.Node and return the result as a string
+func FormatNode(node ast.Node) (string, error) {
+	buf := new(bytes.Buffer)
+	err := format.Node(buf, token.NewFileSet(), node)
+	return buf.String(), err
+}
+
+var debugEnabled = os.Getenv("GOTESTTOOLS_DEBUG") != ""
+
+func debug(format string, args ...interface{}) {
+	if debugEnabled {
+		fmt.Fprintf(os.Stderr, "DEBUG: "+format+"\n", args...)
+	}
+}
+
+type debugFormatNode struct {
+	ast.Node
+}
+
+func (n debugFormatNode) String() string {
+	out, err := FormatNode(n.Node)
+	if err != nil {
+		return fmt.Sprintf("failed to format %s: %s", n.Node, err)
+	}
+	return fmt.Sprintf("(%T) %s", n.Node, out)
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 29bc98b..7137959 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -11,6 +11,12 @@
 github.com/golang/protobuf/ptypes/any
 github.com/golang/protobuf/ptypes/duration
 github.com/golang/protobuf/ptypes/timestamp
+# github.com/google/go-cmp v0.4.0
+github.com/google/go-cmp/cmp
+github.com/google/go-cmp/cmp/internal/diff
+github.com/google/go-cmp/cmp/internal/flags
+github.com/google/go-cmp/cmp/internal/function
+github.com/google/go-cmp/cmp/internal/value
 # github.com/google/gofuzz v1.1.0
 github.com/google/gofuzz
 # github.com/googleapis/gnostic v0.4.1
@@ -135,6 +141,12 @@
 gopkg.in/inf.v0
 # gopkg.in/yaml.v2 v2.3.0
 gopkg.in/yaml.v2
+# gotest.tools v2.2.0+incompatible
+gotest.tools/assert
+gotest.tools/assert/cmp
+gotest.tools/internal/difflib
+gotest.tools/internal/format
+gotest.tools/internal/source
 # k8s.io/api v0.19.0
 k8s.io/api/admissionregistration/v1
 k8s.io/api/admissionregistration/v1beta1
