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
+}
