git subrepo clone (merge) https://github.com/kubernetes-incubator/metrics-server.git metrics-server

subrepo:
  subdir:   "metrics-server"
  merged:   "92d8412"
upstream:
  origin:   "https://github.com/kubernetes-incubator/metrics-server.git"
  branch:   "master"
  commit:   "92d8412"
git-subrepo:
  version:  "0.4.0"
  origin:   "???"
  commit:   "???"
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/and.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/and.go
new file mode 100644
index 0000000..d83a291
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/and.go
@@ -0,0 +1,63 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+	"github.com/onsi/gomega/internal/oraclematcher"
+	"github.com/onsi/gomega/types"
+)
+
+type AndMatcher struct {
+	Matchers []types.GomegaMatcher
+
+	// state
+	firstFailedMatcher types.GomegaMatcher
+}
+
+func (m *AndMatcher) Match(actual interface{}) (success bool, err error) {
+	m.firstFailedMatcher = nil
+	for _, matcher := range m.Matchers {
+		success, err := matcher.Match(actual)
+		if !success || err != nil {
+			m.firstFailedMatcher = matcher
+			return false, err
+		}
+	}
+	return true, nil
+}
+
+func (m *AndMatcher) FailureMessage(actual interface{}) (message string) {
+	return m.firstFailedMatcher.FailureMessage(actual)
+}
+
+func (m *AndMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	// not the most beautiful list of matchers, but not bad either...
+	return format.Message(actual, fmt.Sprintf("To not satisfy all of these matchers: %s", m.Matchers))
+}
+
+func (m *AndMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	/*
+		Example with 3 matchers: A, B, C
+
+		Match evaluates them: T, F, <?>  => F
+		So match is currently F, what should MatchMayChangeInTheFuture() return?
+		Seems like it only depends on B, since currently B MUST change to allow the result to become T
+
+		Match eval: T, T, T  => T
+		So match is currently T, what should MatchMayChangeInTheFuture() return?
+		Seems to depend on ANY of them being able to change to F.
+	*/
+
+	if m.firstFailedMatcher == nil {
+		// so all matchers succeeded.. Any one of them changing would change the result.
+		for _, matcher := range m.Matchers {
+			if oraclematcher.MatchMayChangeInTheFuture(matcher, actual) {
+				return true
+			}
+		}
+		return false // none of were going to change
+	}
+	// one of the matchers failed.. it must be able to change in order to affect the result
+	return oraclematcher.MatchMayChangeInTheFuture(m.firstFailedMatcher, actual)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go
new file mode 100644
index 0000000..51f8be6
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go
@@ -0,0 +1,35 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type AssignableToTypeOfMatcher struct {
+	Expected interface{}
+}
+
+func (matcher *AssignableToTypeOfMatcher) Match(actual interface{}) (success bool, err error) {
+	if actual == nil && matcher.Expected == nil {
+		return false, fmt.Errorf("Refusing to compare <nil> to <nil>.\nBe explicit and use BeNil() instead.  This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.")
+	} else if matcher.Expected == nil {
+		return false, fmt.Errorf("Refusing to compare type to <nil>.\nBe explicit and use BeNil() instead.  This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.")
+	} else if actual == nil {
+		return false, nil
+	}
+
+	actualType := reflect.TypeOf(actual)
+	expectedType := reflect.TypeOf(matcher.Expected)
+
+	return actualType.AssignableTo(expectedType), nil
+}
+
+func (matcher *AssignableToTypeOfMatcher) FailureMessage(actual interface{}) string {
+	return format.Message(actual, fmt.Sprintf("to be assignable to the type: %T", matcher.Expected))
+}
+
+func (matcher *AssignableToTypeOfMatcher) NegatedFailureMessage(actual interface{}) string {
+	return format.Message(actual, fmt.Sprintf("not to be assignable to the type: %T", matcher.Expected))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/attributes_slice.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/attributes_slice.go
new file mode 100644
index 0000000..355b362
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/attributes_slice.go
@@ -0,0 +1,14 @@
+package matchers
+
+import (
+	"encoding/xml"
+	"strings"
+)
+
+type attributesSlice []xml.Attr
+
+func (attrs attributesSlice) Len() int { return len(attrs) }
+func (attrs attributesSlice) Less(i, j int) bool {
+	return strings.Compare(attrs[i].Name.Local, attrs[j].Name.Local) == -1
+}
+func (attrs attributesSlice) Swap(i, j int) { attrs[i], attrs[j] = attrs[j], attrs[i] }
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_directory.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_directory.go
new file mode 100644
index 0000000..7b6975e
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_directory.go
@@ -0,0 +1,54 @@
+package matchers
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/onsi/gomega/format"
+)
+
+type notADirectoryError struct {
+	os.FileInfo
+}
+
+func (t notADirectoryError) Error() string {
+	fileInfo := os.FileInfo(t)
+	switch {
+	case fileInfo.Mode().IsRegular():
+		return "file is a regular file"
+	default:
+		return fmt.Sprintf("file mode is: %s", fileInfo.Mode().String())
+	}
+}
+
+type BeADirectoryMatcher struct {
+	expected interface{}
+	err      error
+}
+
+func (matcher *BeADirectoryMatcher) Match(actual interface{}) (success bool, err error) {
+	actualFilename, ok := actual.(string)
+	if !ok {
+		return false, fmt.Errorf("BeADirectoryMatcher matcher expects a file path")
+	}
+
+	fileInfo, err := os.Stat(actualFilename)
+	if err != nil {
+		matcher.err = err
+		return false, nil
+	}
+
+	if !fileInfo.Mode().IsDir() {
+		matcher.err = notADirectoryError{fileInfo}
+		return false, nil
+	}
+	return true, nil
+}
+
+func (matcher *BeADirectoryMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("to be a directory: %s", matcher.err))
+}
+
+func (matcher *BeADirectoryMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not be a directory"))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go
new file mode 100644
index 0000000..e239131
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go
@@ -0,0 +1,54 @@
+package matchers
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/onsi/gomega/format"
+)
+
+type notARegularFileError struct {
+	os.FileInfo
+}
+
+func (t notARegularFileError) Error() string {
+	fileInfo := os.FileInfo(t)
+	switch {
+	case fileInfo.IsDir():
+		return "file is a directory"
+	default:
+		return fmt.Sprintf("file mode is: %s", fileInfo.Mode().String())
+	}
+}
+
+type BeARegularFileMatcher struct {
+	expected interface{}
+	err      error
+}
+
+func (matcher *BeARegularFileMatcher) Match(actual interface{}) (success bool, err error) {
+	actualFilename, ok := actual.(string)
+	if !ok {
+		return false, fmt.Errorf("BeARegularFileMatcher matcher expects a file path")
+	}
+
+	fileInfo, err := os.Stat(actualFilename)
+	if err != nil {
+		matcher.err = err
+		return false, nil
+	}
+
+	if !fileInfo.Mode().IsRegular() {
+		matcher.err = notARegularFileError{fileInfo}
+		return false, nil
+	}
+	return true, nil
+}
+
+func (matcher *BeARegularFileMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("to be a regular file: %s", matcher.err))
+}
+
+func (matcher *BeARegularFileMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not be a regular file"))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go
new file mode 100644
index 0000000..d42eba2
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go
@@ -0,0 +1,38 @@
+package matchers
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeAnExistingFileMatcher struct {
+	expected interface{}
+}
+
+func (matcher *BeAnExistingFileMatcher) Match(actual interface{}) (success bool, err error) {
+	actualFilename, ok := actual.(string)
+	if !ok {
+		return false, fmt.Errorf("BeAnExistingFileMatcher matcher expects a file path")
+	}
+
+	if _, err = os.Stat(actualFilename); err != nil {
+		switch {
+		case os.IsNotExist(err):
+			return false, nil
+		default:
+			return false, err
+		}
+	}
+
+	return true, nil
+}
+
+func (matcher *BeAnExistingFileMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("to exist"))
+}
+
+func (matcher *BeAnExistingFileMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not to exist"))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go
new file mode 100644
index 0000000..ed6f692
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go
@@ -0,0 +1,46 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeClosedMatcher struct {
+}
+
+func (matcher *BeClosedMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isChan(actual) {
+		return false, fmt.Errorf("BeClosed matcher expects a channel.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	channelType := reflect.TypeOf(actual)
+	channelValue := reflect.ValueOf(actual)
+
+	if channelType.ChanDir() == reflect.SendDir {
+		return false, fmt.Errorf("BeClosed matcher cannot determine if a send-only channel is closed or open.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	winnerIndex, _, open := reflect.Select([]reflect.SelectCase{
+		reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue},
+		reflect.SelectCase{Dir: reflect.SelectDefault},
+	})
+
+	var closed bool
+	if winnerIndex == 0 {
+		closed = !open
+	} else if winnerIndex == 1 {
+		closed = false
+	}
+
+	return closed, nil
+}
+
+func (matcher *BeClosedMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be closed")
+}
+
+func (matcher *BeClosedMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be open")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go
new file mode 100644
index 0000000..8b00311
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go
@@ -0,0 +1,27 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeEmptyMatcher struct {
+}
+
+func (matcher *BeEmptyMatcher) Match(actual interface{}) (success bool, err error) {
+	length, ok := lengthOf(actual)
+	if !ok {
+		return false, fmt.Errorf("BeEmpty matcher expects a string/array/map/channel/slice.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return length == 0, nil
+}
+
+func (matcher *BeEmptyMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be empty")
+}
+
+func (matcher *BeEmptyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be empty")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go
new file mode 100644
index 0000000..97ab20a
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go
@@ -0,0 +1,34 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeEquivalentToMatcher struct {
+	Expected interface{}
+}
+
+func (matcher *BeEquivalentToMatcher) Match(actual interface{}) (success bool, err error) {
+	if actual == nil && matcher.Expected == nil {
+		return false, fmt.Errorf("Both actual and expected must not be nil.")
+	}
+
+	convertedActual := actual
+
+	if actual != nil && matcher.Expected != nil && reflect.TypeOf(actual).ConvertibleTo(reflect.TypeOf(matcher.Expected)) {
+		convertedActual = reflect.ValueOf(actual).Convert(reflect.TypeOf(matcher.Expected)).Interface()
+	}
+
+	return reflect.DeepEqual(convertedActual, matcher.Expected), nil
+}
+
+func (matcher *BeEquivalentToMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be equivalent to", matcher.Expected)
+}
+
+func (matcher *BeEquivalentToMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be equivalent to", matcher.Expected)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go
new file mode 100644
index 0000000..91d3b77
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go
@@ -0,0 +1,26 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeFalseMatcher struct {
+}
+
+func (matcher *BeFalseMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isBool(actual) {
+		return false, fmt.Errorf("Expected a boolean.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return actual == false, nil
+}
+
+func (matcher *BeFalseMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be false")
+}
+
+func (matcher *BeFalseMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be false")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_identical_to.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_identical_to.go
new file mode 100644
index 0000000..fdcda4d
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_identical_to.go
@@ -0,0 +1,37 @@
+package matchers
+
+import (
+	"fmt"
+	"runtime"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeIdenticalToMatcher struct {
+	Expected interface{}
+}
+
+func (matcher *BeIdenticalToMatcher) Match(actual interface{}) (success bool, matchErr error) {
+	if actual == nil && matcher.Expected == nil {
+		return false, fmt.Errorf("Refusing to compare <nil> to <nil>.\nBe explicit and use BeNil() instead.  This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.")
+	}
+
+	defer func() {
+		if r := recover(); r != nil {
+			if _, ok := r.(runtime.Error); ok {
+				success = false
+				matchErr = nil
+			}
+		}
+	}()
+
+	return actual == matcher.Expected, nil
+}
+
+func (matcher *BeIdenticalToMatcher) FailureMessage(actual interface{}) string {
+	return format.Message(actual, "to be identical to", matcher.Expected)
+}
+
+func (matcher *BeIdenticalToMatcher) NegatedFailureMessage(actual interface{}) string {
+	return format.Message(actual, "not to be identical to", matcher.Expected)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go
new file mode 100644
index 0000000..7ee84fe
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go
@@ -0,0 +1,18 @@
+package matchers
+
+import "github.com/onsi/gomega/format"
+
+type BeNilMatcher struct {
+}
+
+func (matcher *BeNilMatcher) Match(actual interface{}) (success bool, err error) {
+	return isNil(actual), nil
+}
+
+func (matcher *BeNilMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be nil")
+}
+
+func (matcher *BeNilMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be nil")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go
new file mode 100644
index 0000000..0c157f6
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go
@@ -0,0 +1,120 @@
+package matchers
+
+import (
+	"fmt"
+	"math"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeNumericallyMatcher struct {
+	Comparator string
+	CompareTo  []interface{}
+}
+
+func (matcher *BeNumericallyMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("to be %s", matcher.Comparator), matcher.CompareTo[0])
+}
+
+func (matcher *BeNumericallyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not to be %s", matcher.Comparator), matcher.CompareTo[0])
+}
+
+func (matcher *BeNumericallyMatcher) Match(actual interface{}) (success bool, err error) {
+	if len(matcher.CompareTo) == 0 || len(matcher.CompareTo) > 2 {
+		return false, fmt.Errorf("BeNumerically requires 1 or 2 CompareTo arguments.  Got:\n%s", format.Object(matcher.CompareTo, 1))
+	}
+	if !isNumber(actual) {
+		return false, fmt.Errorf("Expected a number.  Got:\n%s", format.Object(actual, 1))
+	}
+	if !isNumber(matcher.CompareTo[0]) {
+		return false, fmt.Errorf("Expected a number.  Got:\n%s", format.Object(matcher.CompareTo[0], 1))
+	}
+	if len(matcher.CompareTo) == 2 && !isNumber(matcher.CompareTo[1]) {
+		return false, fmt.Errorf("Expected a number.  Got:\n%s", format.Object(matcher.CompareTo[0], 1))
+	}
+
+	switch matcher.Comparator {
+	case "==", "~", ">", ">=", "<", "<=":
+	default:
+		return false, fmt.Errorf("Unknown comparator: %s", matcher.Comparator)
+	}
+
+	if isFloat(actual) || isFloat(matcher.CompareTo[0]) {
+		var secondOperand float64 = 1e-8
+		if len(matcher.CompareTo) == 2 {
+			secondOperand = toFloat(matcher.CompareTo[1])
+		}
+		success = matcher.matchFloats(toFloat(actual), toFloat(matcher.CompareTo[0]), secondOperand)
+	} else if isInteger(actual) {
+		var secondOperand int64 = 0
+		if len(matcher.CompareTo) == 2 {
+			secondOperand = toInteger(matcher.CompareTo[1])
+		}
+		success = matcher.matchIntegers(toInteger(actual), toInteger(matcher.CompareTo[0]), secondOperand)
+	} else if isUnsignedInteger(actual) {
+		var secondOperand uint64 = 0
+		if len(matcher.CompareTo) == 2 {
+			secondOperand = toUnsignedInteger(matcher.CompareTo[1])
+		}
+		success = matcher.matchUnsignedIntegers(toUnsignedInteger(actual), toUnsignedInteger(matcher.CompareTo[0]), secondOperand)
+	} else {
+		return false, fmt.Errorf("Failed to compare:\n%s\n%s:\n%s", format.Object(actual, 1), matcher.Comparator, format.Object(matcher.CompareTo[0], 1))
+	}
+
+	return success, nil
+}
+
+func (matcher *BeNumericallyMatcher) matchIntegers(actual, compareTo, threshold int64) (success bool) {
+	switch matcher.Comparator {
+	case "==", "~":
+		diff := actual - compareTo
+		return -threshold <= diff && diff <= threshold
+	case ">":
+		return (actual > compareTo)
+	case ">=":
+		return (actual >= compareTo)
+	case "<":
+		return (actual < compareTo)
+	case "<=":
+		return (actual <= compareTo)
+	}
+	return false
+}
+
+func (matcher *BeNumericallyMatcher) matchUnsignedIntegers(actual, compareTo, threshold uint64) (success bool) {
+	switch matcher.Comparator {
+	case "==", "~":
+		if actual < compareTo {
+			actual, compareTo = compareTo, actual
+		}
+		return actual-compareTo <= threshold
+	case ">":
+		return (actual > compareTo)
+	case ">=":
+		return (actual >= compareTo)
+	case "<":
+		return (actual < compareTo)
+	case "<=":
+		return (actual <= compareTo)
+	}
+	return false
+}
+
+func (matcher *BeNumericallyMatcher) matchFloats(actual, compareTo, threshold float64) (success bool) {
+	switch matcher.Comparator {
+	case "~":
+		return math.Abs(actual-compareTo) <= threshold
+	case "==":
+		return (actual == compareTo)
+	case ">":
+		return (actual > compareTo)
+	case ">=":
+		return (actual >= compareTo)
+	case "<":
+		return (actual < compareTo)
+	case "<=":
+		return (actual <= compareTo)
+	}
+	return false
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go
new file mode 100644
index 0000000..d7c3223
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go
@@ -0,0 +1,71 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeSentMatcher struct {
+	Arg           interface{}
+	channelClosed bool
+}
+
+func (matcher *BeSentMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isChan(actual) {
+		return false, fmt.Errorf("BeSent expects a channel.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	channelType := reflect.TypeOf(actual)
+	channelValue := reflect.ValueOf(actual)
+
+	if channelType.ChanDir() == reflect.RecvDir {
+		return false, fmt.Errorf("BeSent matcher cannot be passed a receive-only channel.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	argType := reflect.TypeOf(matcher.Arg)
+	assignable := argType.AssignableTo(channelType.Elem())
+
+	if !assignable {
+		return false, fmt.Errorf("Cannot pass:\n%s to the channel:\n%s\nThe types don't match.", format.Object(matcher.Arg, 1), format.Object(actual, 1))
+	}
+
+	argValue := reflect.ValueOf(matcher.Arg)
+
+	defer func() {
+		if e := recover(); e != nil {
+			success = false
+			err = fmt.Errorf("Cannot send to a closed channel")
+			matcher.channelClosed = true
+		}
+	}()
+
+	winnerIndex, _, _ := reflect.Select([]reflect.SelectCase{
+		reflect.SelectCase{Dir: reflect.SelectSend, Chan: channelValue, Send: argValue},
+		reflect.SelectCase{Dir: reflect.SelectDefault},
+	})
+
+	var didSend bool
+	if winnerIndex == 0 {
+		didSend = true
+	}
+
+	return didSend, nil
+}
+
+func (matcher *BeSentMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to send:", matcher.Arg)
+}
+
+func (matcher *BeSentMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to send:", matcher.Arg)
+}
+
+func (matcher *BeSentMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	if !isChan(actual) {
+		return false
+	}
+
+	return !matcher.channelClosed
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go
new file mode 100644
index 0000000..cb7c038
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go
@@ -0,0 +1,66 @@
+package matchers
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeTemporallyMatcher struct {
+	Comparator string
+	CompareTo  time.Time
+	Threshold  []time.Duration
+}
+
+func (matcher *BeTemporallyMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("to be %s", matcher.Comparator), matcher.CompareTo)
+}
+
+func (matcher *BeTemporallyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not to be %s", matcher.Comparator), matcher.CompareTo)
+}
+
+func (matcher *BeTemporallyMatcher) Match(actual interface{}) (bool, error) {
+	// predicate to test for time.Time type
+	isTime := func(t interface{}) bool {
+		_, ok := t.(time.Time)
+		return ok
+	}
+
+	if !isTime(actual) {
+		return false, fmt.Errorf("Expected a time.Time.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	switch matcher.Comparator {
+	case "==", "~", ">", ">=", "<", "<=":
+	default:
+		return false, fmt.Errorf("Unknown comparator: %s", matcher.Comparator)
+	}
+
+	var threshold = time.Millisecond
+	if len(matcher.Threshold) == 1 {
+		threshold = matcher.Threshold[0]
+	}
+
+	return matcher.matchTimes(actual.(time.Time), matcher.CompareTo, threshold), nil
+}
+
+func (matcher *BeTemporallyMatcher) matchTimes(actual, compareTo time.Time, threshold time.Duration) (success bool) {
+	switch matcher.Comparator {
+	case "==":
+		return actual.Equal(compareTo)
+	case "~":
+		diff := actual.Sub(compareTo)
+		return -threshold <= diff && diff <= threshold
+	case ">":
+		return actual.After(compareTo)
+	case ">=":
+		return !actual.Before(compareTo)
+	case "<":
+		return actual.Before(compareTo)
+	case "<=":
+		return !actual.After(compareTo)
+	}
+	return false
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go
new file mode 100644
index 0000000..ec57c5d
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go
@@ -0,0 +1,26 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeTrueMatcher struct {
+}
+
+func (matcher *BeTrueMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isBool(actual) {
+		return false, fmt.Errorf("Expected a boolean.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return actual.(bool), nil
+}
+
+func (matcher *BeTrueMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be true")
+}
+
+func (matcher *BeTrueMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be true")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go
new file mode 100644
index 0000000..26196f1
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go
@@ -0,0 +1,28 @@
+package matchers
+
+import (
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeZeroMatcher struct {
+}
+
+func (matcher *BeZeroMatcher) Match(actual interface{}) (success bool, err error) {
+	if actual == nil {
+		return true, nil
+	}
+	zeroValue := reflect.Zero(reflect.TypeOf(actual)).Interface()
+
+	return reflect.DeepEqual(zeroValue, actual), nil
+
+}
+
+func (matcher *BeZeroMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be zero-valued")
+}
+
+func (matcher *BeZeroMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be zero-valued")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/consist_of.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/consist_of.go
new file mode 100644
index 0000000..7b0e088
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/consist_of.go
@@ -0,0 +1,80 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+	"github.com/onsi/gomega/matchers/support/goraph/bipartitegraph"
+)
+
+type ConsistOfMatcher struct {
+	Elements []interface{}
+}
+
+func (matcher *ConsistOfMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isArrayOrSlice(actual) && !isMap(actual) {
+		return false, fmt.Errorf("ConsistOf matcher expects an array/slice/map.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	elements := matcher.Elements
+	if len(matcher.Elements) == 1 && isArrayOrSlice(matcher.Elements[0]) {
+		elements = []interface{}{}
+		value := reflect.ValueOf(matcher.Elements[0])
+		for i := 0; i < value.Len(); i++ {
+			elements = append(elements, value.Index(i).Interface())
+		}
+	}
+
+	matchers := []interface{}{}
+	for _, element := range elements {
+		matcher, isMatcher := element.(omegaMatcher)
+		if !isMatcher {
+			matcher = &EqualMatcher{Expected: element}
+		}
+		matchers = append(matchers, matcher)
+	}
+
+	values := matcher.valuesOf(actual)
+
+	if len(values) != len(matchers) {
+		return false, nil
+	}
+
+	neighbours := func(v, m interface{}) (bool, error) {
+		match, err := m.(omegaMatcher).Match(v)
+		return match && err == nil, nil
+	}
+
+	bipartiteGraph, err := bipartitegraph.NewBipartiteGraph(values, matchers, neighbours)
+	if err != nil {
+		return false, err
+	}
+
+	return len(bipartiteGraph.LargestMatching()) == len(values), nil
+}
+
+func (matcher *ConsistOfMatcher) valuesOf(actual interface{}) []interface{} {
+	value := reflect.ValueOf(actual)
+	values := []interface{}{}
+	if isMap(actual) {
+		keys := value.MapKeys()
+		for i := 0; i < value.Len(); i++ {
+			values = append(values, value.MapIndex(keys[i]).Interface())
+		}
+	} else {
+		for i := 0; i < value.Len(); i++ {
+			values = append(values, value.Index(i).Interface())
+		}
+	}
+
+	return values
+}
+
+func (matcher *ConsistOfMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to consist of", matcher.Elements)
+}
+
+func (matcher *ConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to consist of", matcher.Elements)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go
new file mode 100644
index 0000000..4159335
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go
@@ -0,0 +1,56 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type ContainElementMatcher struct {
+	Element interface{}
+}
+
+func (matcher *ContainElementMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isArrayOrSlice(actual) && !isMap(actual) {
+		return false, fmt.Errorf("ContainElement matcher expects an array/slice/map.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	elemMatcher, elementIsMatcher := matcher.Element.(omegaMatcher)
+	if !elementIsMatcher {
+		elemMatcher = &EqualMatcher{Expected: matcher.Element}
+	}
+
+	value := reflect.ValueOf(actual)
+	var keys []reflect.Value
+	if isMap(actual) {
+		keys = value.MapKeys()
+	}
+	var lastError error
+	for i := 0; i < value.Len(); i++ {
+		var success bool
+		var err error
+		if isMap(actual) {
+			success, err = elemMatcher.Match(value.MapIndex(keys[i]).Interface())
+		} else {
+			success, err = elemMatcher.Match(value.Index(i).Interface())
+		}
+		if err != nil {
+			lastError = err
+			continue
+		}
+		if success {
+			return true, nil
+		}
+	}
+
+	return false, lastError
+}
+
+func (matcher *ContainElementMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to contain element matching", matcher.Element)
+}
+
+func (matcher *ContainElementMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to contain element matching", matcher.Element)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go
new file mode 100644
index 0000000..f8dc41e
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go
@@ -0,0 +1,38 @@
+package matchers
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/onsi/gomega/format"
+)
+
+type ContainSubstringMatcher struct {
+	Substr string
+	Args   []interface{}
+}
+
+func (matcher *ContainSubstringMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return false, fmt.Errorf("ContainSubstring matcher requires a string or stringer.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return strings.Contains(actualString, matcher.stringToMatch()), nil
+}
+
+func (matcher *ContainSubstringMatcher) stringToMatch() string {
+	stringToMatch := matcher.Substr
+	if len(matcher.Args) > 0 {
+		stringToMatch = fmt.Sprintf(matcher.Substr, matcher.Args...)
+	}
+	return stringToMatch
+}
+
+func (matcher *ContainSubstringMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to contain substring", matcher.stringToMatch())
+}
+
+func (matcher *ContainSubstringMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to contain substring", matcher.stringToMatch())
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/equal_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/equal_matcher.go
new file mode 100644
index 0000000..befb7bd
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/equal_matcher.go
@@ -0,0 +1,42 @@
+package matchers
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type EqualMatcher struct {
+	Expected interface{}
+}
+
+func (matcher *EqualMatcher) Match(actual interface{}) (success bool, err error) {
+	if actual == nil && matcher.Expected == nil {
+		return false, fmt.Errorf("Refusing to compare <nil> to <nil>.\nBe explicit and use BeNil() instead.  This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.")
+	}
+	// Shortcut for byte slices.
+	// Comparing long byte slices with reflect.DeepEqual is very slow,
+	// so use bytes.Equal if actual and expected are both byte slices.
+	if actualByteSlice, ok := actual.([]byte); ok {
+		if expectedByteSlice, ok := matcher.Expected.([]byte); ok {
+			return bytes.Equal(actualByteSlice, expectedByteSlice), nil
+		}
+	}
+	return reflect.DeepEqual(actual, matcher.Expected), nil
+}
+
+func (matcher *EqualMatcher) FailureMessage(actual interface{}) (message string) {
+	actualString, actualOK := actual.(string)
+	expectedString, expectedOK := matcher.Expected.(string)
+	if actualOK && expectedOK {
+		return format.MessageWithDiff(actualString, "to equal", expectedString)
+	}
+
+	return format.Message(actual, "to equal", matcher.Expected)
+}
+
+func (matcher *EqualMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to equal", matcher.Expected)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go
new file mode 100644
index 0000000..7ace93d
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go
@@ -0,0 +1,28 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveCapMatcher struct {
+	Count int
+}
+
+func (matcher *HaveCapMatcher) Match(actual interface{}) (success bool, err error) {
+	length, ok := capOf(actual)
+	if !ok {
+		return false, fmt.Errorf("HaveCap matcher expects a array/channel/slice.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return length == matcher.Count, nil
+}
+
+func (matcher *HaveCapMatcher) FailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected\n%s\nto have capacity %d", format.Object(actual, 1), matcher.Count)
+}
+
+func (matcher *HaveCapMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected\n%s\nnot to have capacity %d", format.Object(actual, 1), matcher.Count)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go
new file mode 100644
index 0000000..ea5b923
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go
@@ -0,0 +1,54 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveKeyMatcher struct {
+	Key interface{}
+}
+
+func (matcher *HaveKeyMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isMap(actual) {
+		return false, fmt.Errorf("HaveKey matcher expects a map.  Got:%s", format.Object(actual, 1))
+	}
+
+	keyMatcher, keyIsMatcher := matcher.Key.(omegaMatcher)
+	if !keyIsMatcher {
+		keyMatcher = &EqualMatcher{Expected: matcher.Key}
+	}
+
+	keys := reflect.ValueOf(actual).MapKeys()
+	for i := 0; i < len(keys); i++ {
+		success, err := keyMatcher.Match(keys[i].Interface())
+		if err != nil {
+			return false, fmt.Errorf("HaveKey's key matcher failed with:\n%s%s", format.Indent, err.Error())
+		}
+		if success {
+			return true, nil
+		}
+	}
+
+	return false, nil
+}
+
+func (matcher *HaveKeyMatcher) FailureMessage(actual interface{}) (message string) {
+	switch matcher.Key.(type) {
+	case omegaMatcher:
+		return format.Message(actual, "to have key matching", matcher.Key)
+	default:
+		return format.Message(actual, "to have key", matcher.Key)
+	}
+}
+
+func (matcher *HaveKeyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	switch matcher.Key.(type) {
+	case omegaMatcher:
+		return format.Message(actual, "not to have key matching", matcher.Key)
+	default:
+		return format.Message(actual, "not to have key", matcher.Key)
+	}
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go
new file mode 100644
index 0000000..06355b1
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go
@@ -0,0 +1,74 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveKeyWithValueMatcher struct {
+	Key   interface{}
+	Value interface{}
+}
+
+func (matcher *HaveKeyWithValueMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isMap(actual) {
+		return false, fmt.Errorf("HaveKeyWithValue matcher expects a map.  Got:%s", format.Object(actual, 1))
+	}
+
+	keyMatcher, keyIsMatcher := matcher.Key.(omegaMatcher)
+	if !keyIsMatcher {
+		keyMatcher = &EqualMatcher{Expected: matcher.Key}
+	}
+
+	valueMatcher, valueIsMatcher := matcher.Value.(omegaMatcher)
+	if !valueIsMatcher {
+		valueMatcher = &EqualMatcher{Expected: matcher.Value}
+	}
+
+	keys := reflect.ValueOf(actual).MapKeys()
+	for i := 0; i < len(keys); i++ {
+		success, err := keyMatcher.Match(keys[i].Interface())
+		if err != nil {
+			return false, fmt.Errorf("HaveKeyWithValue's key matcher failed with:\n%s%s", format.Indent, err.Error())
+		}
+		if success {
+			actualValue := reflect.ValueOf(actual).MapIndex(keys[i])
+			success, err := valueMatcher.Match(actualValue.Interface())
+			if err != nil {
+				return false, fmt.Errorf("HaveKeyWithValue's value matcher failed with:\n%s%s", format.Indent, err.Error())
+			}
+			return success, nil
+		}
+	}
+
+	return false, nil
+}
+
+func (matcher *HaveKeyWithValueMatcher) FailureMessage(actual interface{}) (message string) {
+	str := "to have {key: value}"
+	if _, ok := matcher.Key.(omegaMatcher); ok {
+		str += " matching"
+	} else if _, ok := matcher.Value.(omegaMatcher); ok {
+		str += " matching"
+	}
+
+	expect := make(map[interface{}]interface{}, 1)
+	expect[matcher.Key] = matcher.Value
+	return format.Message(actual, str, expect)
+}
+
+func (matcher *HaveKeyWithValueMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	kStr := "not to have key"
+	if _, ok := matcher.Key.(omegaMatcher); ok {
+		kStr = "not to have key matching"
+	}
+
+	vStr := "or that key's value not be"
+	if _, ok := matcher.Value.(omegaMatcher); ok {
+		vStr = "or to have that key's value not matching"
+	}
+
+	return format.Message(actual, kStr, matcher.Key, vStr, matcher.Value)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go
new file mode 100644
index 0000000..ee42761
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go
@@ -0,0 +1,28 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveLenMatcher struct {
+	Count int
+}
+
+func (matcher *HaveLenMatcher) Match(actual interface{}) (success bool, err error) {
+	length, ok := lengthOf(actual)
+	if !ok {
+		return false, fmt.Errorf("HaveLen matcher expects a string/array/map/channel/slice.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return length == matcher.Count, nil
+}
+
+func (matcher *HaveLenMatcher) FailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected\n%s\nto have length %d", format.Object(actual, 1), matcher.Count)
+}
+
+func (matcher *HaveLenMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected\n%s\nnot to have length %d", format.Object(actual, 1), matcher.Count)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go
new file mode 100644
index 0000000..ebdd717
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go
@@ -0,0 +1,33 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveOccurredMatcher struct {
+}
+
+func (matcher *HaveOccurredMatcher) Match(actual interface{}) (success bool, err error) {
+	// is purely nil?
+	if actual == nil {
+		return false, nil
+	}
+
+	// must be an 'error' type
+	if !isError(actual) {
+		return false, fmt.Errorf("Expected an error-type.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	// must be non-nil (or a pointer to a non-nil)
+	return !isNil(actual), nil
+}
+
+func (matcher *HaveOccurredMatcher) FailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected an error to have occurred.  Got:\n%s", format.Object(actual, 1))
+}
+
+func (matcher *HaveOccurredMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected error:\n%s\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1), "not to have occurred")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go
new file mode 100644
index 0000000..1d8e802
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go
@@ -0,0 +1,36 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HavePrefixMatcher struct {
+	Prefix string
+	Args   []interface{}
+}
+
+func (matcher *HavePrefixMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return false, fmt.Errorf("HavePrefix matcher requires a string or stringer.  Got:\n%s", format.Object(actual, 1))
+	}
+	prefix := matcher.prefix()
+	return len(actualString) >= len(prefix) && actualString[0:len(prefix)] == prefix, nil
+}
+
+func (matcher *HavePrefixMatcher) prefix() string {
+	if len(matcher.Args) > 0 {
+		return fmt.Sprintf(matcher.Prefix, matcher.Args...)
+	}
+	return matcher.Prefix
+}
+
+func (matcher *HavePrefixMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to have prefix", matcher.prefix())
+}
+
+func (matcher *HavePrefixMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to have prefix", matcher.prefix())
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go
new file mode 100644
index 0000000..40a3526
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go
@@ -0,0 +1,36 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveSuffixMatcher struct {
+	Suffix string
+	Args   []interface{}
+}
+
+func (matcher *HaveSuffixMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return false, fmt.Errorf("HaveSuffix matcher requires a string or stringer.  Got:\n%s", format.Object(actual, 1))
+	}
+	suffix := matcher.suffix()
+	return len(actualString) >= len(suffix) && actualString[len(actualString)-len(suffix):] == suffix, nil
+}
+
+func (matcher *HaveSuffixMatcher) suffix() string {
+	if len(matcher.Args) > 0 {
+		return fmt.Sprintf(matcher.Suffix, matcher.Args...)
+	}
+	return matcher.Suffix
+}
+
+func (matcher *HaveSuffixMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to have suffix", matcher.suffix())
+}
+
+func (matcher *HaveSuffixMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to have suffix", matcher.suffix())
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go
new file mode 100644
index 0000000..07499ac
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go
@@ -0,0 +1,51 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type MatchErrorMatcher struct {
+	Expected interface{}
+}
+
+func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err error) {
+	if isNil(actual) {
+		return false, fmt.Errorf("Expected an error, got nil")
+	}
+
+	if !isError(actual) {
+		return false, fmt.Errorf("Expected an error.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	actualErr := actual.(error)
+
+	if isError(matcher.Expected) {
+		return reflect.DeepEqual(actualErr, matcher.Expected), nil
+	}
+
+	if isString(matcher.Expected) {
+		return actualErr.Error() == matcher.Expected, nil
+	}
+
+	var subMatcher omegaMatcher
+	var hasSubMatcher bool
+	if matcher.Expected != nil {
+		subMatcher, hasSubMatcher = (matcher.Expected).(omegaMatcher)
+		if hasSubMatcher {
+			return subMatcher.Match(actualErr.Error())
+		}
+	}
+
+	return false, fmt.Errorf("MatchError must be passed an error, string, or Matcher that can match on strings.  Got:\n%s", format.Object(matcher.Expected, 1))
+}
+
+func (matcher *MatchErrorMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to match error", matcher.Expected)
+}
+
+func (matcher *MatchErrorMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to match error", matcher.Expected)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/match_json_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_json_matcher.go
new file mode 100644
index 0000000..499bb58
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_json_matcher.go
@@ -0,0 +1,135 @@
+package matchers
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"reflect"
+	"strings"
+
+	"github.com/onsi/gomega/format"
+)
+
+type MatchJSONMatcher struct {
+	JSONToMatch      interface{}
+	firstFailurePath []interface{}
+}
+
+func (matcher *MatchJSONMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, expectedString, err := matcher.prettyPrint(actual)
+	if err != nil {
+		return false, err
+	}
+
+	var aval interface{}
+	var eval interface{}
+
+	// this is guarded by prettyPrint
+	json.Unmarshal([]byte(actualString), &aval)
+	json.Unmarshal([]byte(expectedString), &eval)
+	var equal bool
+	equal, matcher.firstFailurePath = deepEqual(aval, eval)
+	return equal, nil
+}
+
+func (matcher *MatchJSONMatcher) FailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.prettyPrint(actual)
+	return formattedMessage(format.Message(actualString, "to match JSON of", expectedString), matcher.firstFailurePath)
+}
+
+func (matcher *MatchJSONMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.prettyPrint(actual)
+	return formattedMessage(format.Message(actualString, "not to match JSON of", expectedString), matcher.firstFailurePath)
+}
+
+func formattedMessage(comparisonMessage string, failurePath []interface{}) string {
+	var diffMessage string
+	if len(failurePath) == 0 {
+		diffMessage = ""
+	} else {
+		diffMessage = fmt.Sprintf("\n\nfirst mismatched key: %s", formattedFailurePath(failurePath))
+	}
+	return fmt.Sprintf("%s%s", comparisonMessage, diffMessage)
+}
+
+func formattedFailurePath(failurePath []interface{}) string {
+	formattedPaths := []string{}
+	for i := len(failurePath) - 1; i >= 0; i-- {
+		switch p := failurePath[i].(type) {
+		case int:
+			formattedPaths = append(formattedPaths, fmt.Sprintf(`[%d]`, p))
+		default:
+			if i != len(failurePath)-1 {
+				formattedPaths = append(formattedPaths, ".")
+			}
+			formattedPaths = append(formattedPaths, fmt.Sprintf(`"%s"`, p))
+		}
+	}
+	return strings.Join(formattedPaths, "")
+}
+
+func (matcher *MatchJSONMatcher) prettyPrint(actual interface{}) (actualFormatted, expectedFormatted string, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return "", "", fmt.Errorf("MatchJSONMatcher matcher requires a string, stringer, or []byte.  Got actual:\n%s", format.Object(actual, 1))
+	}
+	expectedString, ok := toString(matcher.JSONToMatch)
+	if !ok {
+		return "", "", fmt.Errorf("MatchJSONMatcher matcher requires a string, stringer, or []byte.  Got expected:\n%s", format.Object(matcher.JSONToMatch, 1))
+	}
+
+	abuf := new(bytes.Buffer)
+	ebuf := new(bytes.Buffer)
+
+	if err := json.Indent(abuf, []byte(actualString), "", "  "); err != nil {
+		return "", "", fmt.Errorf("Actual '%s' should be valid JSON, but it is not.\nUnderlying error:%s", actualString, err)
+	}
+
+	if err := json.Indent(ebuf, []byte(expectedString), "", "  "); err != nil {
+		return "", "", fmt.Errorf("Expected '%s' should be valid JSON, but it is not.\nUnderlying error:%s", expectedString, err)
+	}
+
+	return abuf.String(), ebuf.String(), nil
+}
+
+func deepEqual(a interface{}, b interface{}) (bool, []interface{}) {
+	var errorPath []interface{}
+	if reflect.TypeOf(a) != reflect.TypeOf(b) {
+		return false, errorPath
+	}
+
+	switch a.(type) {
+	case []interface{}:
+		if len(a.([]interface{})) != len(b.([]interface{})) {
+			return false, errorPath
+		}
+
+		for i, v := range a.([]interface{}) {
+			elementEqual, keyPath := deepEqual(v, b.([]interface{})[i])
+			if !elementEqual {
+				return false, append(keyPath, i)
+			}
+		}
+		return true, errorPath
+
+	case map[string]interface{}:
+		if len(a.(map[string]interface{})) != len(b.(map[string]interface{})) {
+			return false, errorPath
+		}
+
+		for k, v1 := range a.(map[string]interface{}) {
+			v2, ok := b.(map[string]interface{})[k]
+			if !ok {
+				return false, errorPath
+			}
+			elementEqual, keyPath := deepEqual(v1, v2)
+			if !elementEqual {
+				return false, append(keyPath, k)
+			}
+		}
+		return true, errorPath
+
+	default:
+		return a == b, errorPath
+	}
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go
new file mode 100644
index 0000000..adac5db
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go
@@ -0,0 +1,43 @@
+package matchers
+
+import (
+	"fmt"
+	"regexp"
+
+	"github.com/onsi/gomega/format"
+)
+
+type MatchRegexpMatcher struct {
+	Regexp string
+	Args   []interface{}
+}
+
+func (matcher *MatchRegexpMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return false, fmt.Errorf("RegExp matcher requires a string or stringer.\nGot:%s", format.Object(actual, 1))
+	}
+
+	match, err := regexp.Match(matcher.regexp(), []byte(actualString))
+	if err != nil {
+		return false, fmt.Errorf("RegExp match failed to compile with error:\n\t%s", err.Error())
+	}
+
+	return match, nil
+}
+
+func (matcher *MatchRegexpMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to match regular expression", matcher.regexp())
+}
+
+func (matcher *MatchRegexpMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to match regular expression", matcher.regexp())
+}
+
+func (matcher *MatchRegexpMatcher) regexp() string {
+	re := matcher.Regexp
+	if len(matcher.Args) > 0 {
+		re = fmt.Sprintf(matcher.Regexp, matcher.Args...)
+	}
+	return re
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go
new file mode 100644
index 0000000..3b412ce
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go
@@ -0,0 +1,134 @@
+package matchers
+
+import (
+	"bytes"
+	"encoding/xml"
+	"errors"
+	"fmt"
+	"io"
+	"reflect"
+	"sort"
+	"strings"
+
+	"github.com/onsi/gomega/format"
+	"golang.org/x/net/html/charset"
+)
+
+type MatchXMLMatcher struct {
+	XMLToMatch interface{}
+}
+
+func (matcher *MatchXMLMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, expectedString, err := matcher.formattedPrint(actual)
+	if err != nil {
+		return false, err
+	}
+
+	aval, err := parseXmlContent(actualString)
+	if err != nil {
+		return false, fmt.Errorf("Actual '%s' should be valid XML, but it is not.\nUnderlying error:%s", actualString, err)
+	}
+
+	eval, err := parseXmlContent(expectedString)
+	if err != nil {
+		return false, fmt.Errorf("Expected '%s' should be valid XML, but it is not.\nUnderlying error:%s", expectedString, err)
+	}
+
+	return reflect.DeepEqual(aval, eval), nil
+}
+
+func (matcher *MatchXMLMatcher) FailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.formattedPrint(actual)
+	return fmt.Sprintf("Expected\n%s\nto match XML of\n%s", actualString, expectedString)
+}
+
+func (matcher *MatchXMLMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.formattedPrint(actual)
+	return fmt.Sprintf("Expected\n%s\nnot to match XML of\n%s", actualString, expectedString)
+}
+
+func (matcher *MatchXMLMatcher) formattedPrint(actual interface{}) (actualString, expectedString string, err error) {
+	var ok bool
+	actualString, ok = toString(actual)
+	if !ok {
+		return "", "", fmt.Errorf("MatchXMLMatcher matcher requires a string, stringer, or []byte.  Got actual:\n%s", format.Object(actual, 1))
+	}
+	expectedString, ok = toString(matcher.XMLToMatch)
+	if !ok {
+		return "", "", fmt.Errorf("MatchXMLMatcher matcher requires a string, stringer, or []byte.  Got expected:\n%s", format.Object(matcher.XMLToMatch, 1))
+	}
+	return actualString, expectedString, nil
+}
+
+func parseXmlContent(content string) (*xmlNode, error) {
+	allNodes := []*xmlNode{}
+
+	dec := newXmlDecoder(strings.NewReader(content))
+	for {
+		tok, err := dec.Token()
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			return nil, fmt.Errorf("failed to decode next token: %v", err)
+		}
+
+		lastNodeIndex := len(allNodes) - 1
+		var lastNode *xmlNode
+		if len(allNodes) > 0 {
+			lastNode = allNodes[lastNodeIndex]
+		} else {
+			lastNode = &xmlNode{}
+		}
+
+		switch tok := tok.(type) {
+		case xml.StartElement:
+			attrs := attributesSlice(tok.Attr)
+			sort.Sort(attrs)
+			allNodes = append(allNodes, &xmlNode{XMLName: tok.Name, XMLAttr: tok.Attr})
+		case xml.EndElement:
+			if len(allNodes) > 1 {
+				allNodes[lastNodeIndex-1].Nodes = append(allNodes[lastNodeIndex-1].Nodes, lastNode)
+				allNodes = allNodes[:lastNodeIndex]
+			}
+		case xml.CharData:
+			lastNode.Content = append(lastNode.Content, tok.Copy()...)
+		case xml.Comment:
+			lastNode.Comments = append(lastNode.Comments, tok.Copy())
+		case xml.ProcInst:
+			lastNode.ProcInsts = append(lastNode.ProcInsts, tok.Copy())
+		}
+	}
+
+	if len(allNodes) == 0 {
+		return nil, errors.New("found no nodes")
+	}
+	firstNode := allNodes[0]
+	trimParentNodesContentSpaces(firstNode)
+
+	return firstNode, nil
+}
+
+func newXmlDecoder(reader io.Reader) *xml.Decoder {
+	dec := xml.NewDecoder(reader)
+	dec.CharsetReader = charset.NewReaderLabel
+	return dec
+}
+
+func trimParentNodesContentSpaces(node *xmlNode) {
+	if len(node.Nodes) > 0 {
+		node.Content = bytes.TrimSpace(node.Content)
+		for _, childNode := range node.Nodes {
+			trimParentNodesContentSpaces(childNode)
+		}
+	}
+}
+
+type xmlNode struct {
+	XMLName   xml.Name
+	Comments  []xml.Comment
+	ProcInsts []xml.ProcInst
+	XMLAttr   []xml.Attr
+	Content   []byte
+	Nodes     []*xmlNode
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go
new file mode 100644
index 0000000..69fb51a
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go
@@ -0,0 +1,74 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+
+	"github.com/onsi/gomega/format"
+	"gopkg.in/yaml.v2"
+)
+
+type MatchYAMLMatcher struct {
+	YAMLToMatch interface{}
+}
+
+func (matcher *MatchYAMLMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, expectedString, err := matcher.toStrings(actual)
+	if err != nil {
+		return false, err
+	}
+
+	var aval interface{}
+	var eval interface{}
+
+	if err := yaml.Unmarshal([]byte(actualString), &aval); err != nil {
+		return false, fmt.Errorf("Actual '%s' should be valid YAML, but it is not.\nUnderlying error:%s", actualString, err)
+	}
+	if err := yaml.Unmarshal([]byte(expectedString), &eval); err != nil {
+		return false, fmt.Errorf("Expected '%s' should be valid YAML, but it is not.\nUnderlying error:%s", expectedString, err)
+	}
+
+	return reflect.DeepEqual(aval, eval), nil
+}
+
+func (matcher *MatchYAMLMatcher) FailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.toNormalisedStrings(actual)
+	return format.Message(actualString, "to match YAML of", expectedString)
+}
+
+func (matcher *MatchYAMLMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.toNormalisedStrings(actual)
+	return format.Message(actualString, "not to match YAML of", expectedString)
+}
+
+func (matcher *MatchYAMLMatcher) toNormalisedStrings(actual interface{}) (actualFormatted, expectedFormatted string, err error) {
+	actualString, expectedString, err := matcher.toStrings(actual)
+	return normalise(actualString), normalise(expectedString), err
+}
+
+func normalise(input string) string {
+	var val interface{}
+	err := yaml.Unmarshal([]byte(input), &val)
+	if err != nil {
+		panic(err) // guarded by Match
+	}
+	output, err := yaml.Marshal(val)
+	if err != nil {
+		panic(err) // guarded by Unmarshal
+	}
+	return strings.TrimSpace(string(output))
+}
+
+func (matcher *MatchYAMLMatcher) toStrings(actual interface{}) (actualFormatted, expectedFormatted string, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return "", "", fmt.Errorf("MatchYAMLMatcher matcher requires a string, stringer, or []byte.  Got actual:\n%s", format.Object(actual, 1))
+	}
+	expectedString, ok := toString(matcher.YAMLToMatch)
+	if !ok {
+		return "", "", fmt.Errorf("MatchYAMLMatcher matcher requires a string, stringer, or []byte.  Got expected:\n%s", format.Object(matcher.YAMLToMatch, 1))
+	}
+
+	return actualString, expectedString, nil
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/not.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/not.go
new file mode 100644
index 0000000..2c91670
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/not.go
@@ -0,0 +1,30 @@
+package matchers
+
+import (
+	"github.com/onsi/gomega/internal/oraclematcher"
+	"github.com/onsi/gomega/types"
+)
+
+type NotMatcher struct {
+	Matcher types.GomegaMatcher
+}
+
+func (m *NotMatcher) Match(actual interface{}) (bool, error) {
+	success, err := m.Matcher.Match(actual)
+	if err != nil {
+		return false, err
+	}
+	return !success, nil
+}
+
+func (m *NotMatcher) FailureMessage(actual interface{}) (message string) {
+	return m.Matcher.NegatedFailureMessage(actual) // works beautifully
+}
+
+func (m *NotMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return m.Matcher.FailureMessage(actual) // works beautifully
+}
+
+func (m *NotMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	return oraclematcher.MatchMayChangeInTheFuture(m.Matcher, actual) // just return m.Matcher's value
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/or.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/or.go
new file mode 100644
index 0000000..3bf7998
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/or.go
@@ -0,0 +1,67 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+	"github.com/onsi/gomega/internal/oraclematcher"
+	"github.com/onsi/gomega/types"
+)
+
+type OrMatcher struct {
+	Matchers []types.GomegaMatcher
+
+	// state
+	firstSuccessfulMatcher types.GomegaMatcher
+}
+
+func (m *OrMatcher) Match(actual interface{}) (success bool, err error) {
+	m.firstSuccessfulMatcher = nil
+	for _, matcher := range m.Matchers {
+		success, err := matcher.Match(actual)
+		if err != nil {
+			return false, err
+		}
+		if success {
+			m.firstSuccessfulMatcher = matcher
+			return true, nil
+		}
+	}
+	return false, nil
+}
+
+func (m *OrMatcher) FailureMessage(actual interface{}) (message string) {
+	// not the most beautiful list of matchers, but not bad either...
+	return format.Message(actual, fmt.Sprintf("To satisfy at least one of these matchers: %s", m.Matchers))
+}
+
+func (m *OrMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return m.firstSuccessfulMatcher.NegatedFailureMessage(actual)
+}
+
+func (m *OrMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	/*
+		Example with 3 matchers: A, B, C
+
+		Match evaluates them: F, T, <?>  => T
+		So match is currently T, what should MatchMayChangeInTheFuture() return?
+		Seems like it only depends on B, since currently B MUST change to allow the result to become F
+
+		Match eval: F, F, F  => F
+		So match is currently F, what should MatchMayChangeInTheFuture() return?
+		Seems to depend on ANY of them being able to change to T.
+	*/
+
+	if m.firstSuccessfulMatcher != nil {
+		// one of the matchers succeeded.. it must be able to change in order to affect the result
+		return oraclematcher.MatchMayChangeInTheFuture(m.firstSuccessfulMatcher, actual)
+	} else {
+		// so all matchers failed.. Any one of them changing would change the result.
+		for _, matcher := range m.Matchers {
+			if oraclematcher.MatchMayChangeInTheFuture(matcher, actual) {
+				return true
+			}
+		}
+		return false // none of were going to change
+	}
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/panic_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/panic_matcher.go
new file mode 100644
index 0000000..640f4db
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/panic_matcher.go
@@ -0,0 +1,46 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type PanicMatcher struct {
+	object interface{}
+}
+
+func (matcher *PanicMatcher) Match(actual interface{}) (success bool, err error) {
+	if actual == nil {
+		return false, fmt.Errorf("PanicMatcher expects a non-nil actual.")
+	}
+
+	actualType := reflect.TypeOf(actual)
+	if actualType.Kind() != reflect.Func {
+		return false, fmt.Errorf("PanicMatcher expects a function.  Got:\n%s", format.Object(actual, 1))
+	}
+	if !(actualType.NumIn() == 0 && actualType.NumOut() == 0) {
+		return false, fmt.Errorf("PanicMatcher expects a function with no arguments and no return value.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	success = false
+	defer func() {
+		if e := recover(); e != nil {
+			matcher.object = e
+			success = true
+		}
+	}()
+
+	reflect.ValueOf(actual).Call([]reflect.Value{})
+
+	return
+}
+
+func (matcher *PanicMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to panic")
+}
+
+func (matcher *PanicMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not to panic, but panicked with\n%s", format.Object(matcher.object, 1)))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/receive_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/receive_matcher.go
new file mode 100644
index 0000000..74e9e7e
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/receive_matcher.go
@@ -0,0 +1,122 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type ReceiveMatcher struct {
+	Arg           interface{}
+	receivedValue reflect.Value
+	channelClosed bool
+}
+
+func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isChan(actual) {
+		return false, fmt.Errorf("ReceiveMatcher expects a channel.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	channelType := reflect.TypeOf(actual)
+	channelValue := reflect.ValueOf(actual)
+
+	if channelType.ChanDir() == reflect.SendDir {
+		return false, fmt.Errorf("ReceiveMatcher matcher cannot be passed a send-only channel.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	var subMatcher omegaMatcher
+	var hasSubMatcher bool
+
+	if matcher.Arg != nil {
+		subMatcher, hasSubMatcher = (matcher.Arg).(omegaMatcher)
+		if !hasSubMatcher {
+			argType := reflect.TypeOf(matcher.Arg)
+			if argType.Kind() != reflect.Ptr {
+				return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s\nYou need to pass a pointer!", format.Object(actual, 1), format.Object(matcher.Arg, 1))
+			}
+
+			assignable := channelType.Elem().AssignableTo(argType.Elem())
+			if !assignable {
+				return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s", format.Object(actual, 1), format.Object(matcher.Arg, 1))
+			}
+		}
+	}
+
+	winnerIndex, value, open := reflect.Select([]reflect.SelectCase{
+		reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue},
+		reflect.SelectCase{Dir: reflect.SelectDefault},
+	})
+
+	var closed bool
+	var didReceive bool
+	if winnerIndex == 0 {
+		closed = !open
+		didReceive = open
+	}
+	matcher.channelClosed = closed
+
+	if closed {
+		return false, nil
+	}
+
+	if hasSubMatcher {
+		if didReceive {
+			matcher.receivedValue = value
+			return subMatcher.Match(matcher.receivedValue.Interface())
+		}
+		return false, nil
+	}
+
+	if didReceive {
+		if matcher.Arg != nil {
+			outValue := reflect.ValueOf(matcher.Arg)
+			reflect.Indirect(outValue).Set(value)
+		}
+
+		return true, nil
+	}
+	return false, nil
+}
+
+func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message string) {
+	subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher)
+
+	closedAddendum := ""
+	if matcher.channelClosed {
+		closedAddendum = " The channel is closed."
+	}
+
+	if hasSubMatcher {
+		if matcher.receivedValue.IsValid() {
+			return subMatcher.FailureMessage(matcher.receivedValue.Interface())
+		}
+		return "When passed a matcher, ReceiveMatcher's channel *must* receive something."
+	}
+	return format.Message(actual, "to receive something."+closedAddendum)
+}
+
+func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher)
+
+	closedAddendum := ""
+	if matcher.channelClosed {
+		closedAddendum = " The channel is closed."
+	}
+
+	if hasSubMatcher {
+		if matcher.receivedValue.IsValid() {
+			return subMatcher.NegatedFailureMessage(matcher.receivedValue.Interface())
+		}
+		return "When passed a matcher, ReceiveMatcher's channel *must* receive something."
+	}
+	return format.Message(actual, "not to receive anything."+closedAddendum)
+}
+
+func (matcher *ReceiveMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	if !isChan(actual) {
+		return false
+	}
+
+	return !matcher.channelClosed
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go
new file mode 100644
index 0000000..721ed55
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go
@@ -0,0 +1,33 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type SucceedMatcher struct {
+}
+
+func (matcher *SucceedMatcher) Match(actual interface{}) (success bool, err error) {
+	// is purely nil?
+	if actual == nil {
+		return true, nil
+	}
+
+	// must be an 'error' type
+	if !isError(actual) {
+		return false, fmt.Errorf("Expected an error-type.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	// must be nil (or a pointer to a nil)
+	return isNil(actual), nil
+}
+
+func (matcher *SucceedMatcher) FailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected success, but got an error:\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1))
+}
+
+func (matcher *SucceedMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return "Expected failure, but got no error."
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go
new file mode 100644
index 0000000..81b3771
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go
@@ -0,0 +1,41 @@
+package bipartitegraph
+
+import "errors"
+import "fmt"
+
+import . "github.com/onsi/gomega/matchers/support/goraph/node"
+import . "github.com/onsi/gomega/matchers/support/goraph/edge"
+
+type BipartiteGraph struct {
+	Left  NodeOrderedSet
+	Right NodeOrderedSet
+	Edges EdgeSet
+}
+
+func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(interface{}, interface{}) (bool, error)) (*BipartiteGraph, error) {
+	left := NodeOrderedSet{}
+	for i, _ := range leftValues {
+		left = append(left, Node{Id: i})
+	}
+
+	right := NodeOrderedSet{}
+	for j, _ := range rightValues {
+		right = append(right, Node{Id: j + len(left)})
+	}
+
+	edges := EdgeSet{}
+	for i, leftValue := range leftValues {
+		for j, rightValue := range rightValues {
+			neighbours, err := neighbours(leftValue, rightValue)
+			if err != nil {
+				return nil, errors.New(fmt.Sprintf("error determining adjacency for %v and %v: %s", leftValue, rightValue, err.Error()))
+			}
+
+			if neighbours {
+				edges = append(edges, Edge{Node1: left[i], Node2: right[j]})
+			}
+		}
+	}
+
+	return &BipartiteGraph{left, right, edges}, nil
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go
new file mode 100644
index 0000000..8181f43
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go
@@ -0,0 +1,159 @@
+package bipartitegraph
+
+import . "github.com/onsi/gomega/matchers/support/goraph/node"
+import . "github.com/onsi/gomega/matchers/support/goraph/edge"
+import "github.com/onsi/gomega/matchers/support/goraph/util"
+
+func (bg *BipartiteGraph) LargestMatching() (matching EdgeSet) {
+	paths := bg.maximalDisjointSLAPCollection(matching)
+
+	for len(paths) > 0 {
+		for _, path := range paths {
+			matching = matching.SymmetricDifference(path)
+		}
+		paths = bg.maximalDisjointSLAPCollection(matching)
+	}
+
+	return
+}
+
+func (bg *BipartiteGraph) maximalDisjointSLAPCollection(matching EdgeSet) (result []EdgeSet) {
+	guideLayers := bg.createSLAPGuideLayers(matching)
+	if len(guideLayers) == 0 {
+		return
+	}
+
+	used := make(map[Node]bool)
+
+	for _, u := range guideLayers[len(guideLayers)-1] {
+		slap, found := bg.findDisjointSLAP(u, matching, guideLayers, used)
+		if found {
+			for _, edge := range slap {
+				used[edge.Node1] = true
+				used[edge.Node2] = true
+			}
+			result = append(result, slap)
+		}
+	}
+
+	return
+}
+
+func (bg *BipartiteGraph) findDisjointSLAP(
+	start Node,
+	matching EdgeSet,
+	guideLayers []NodeOrderedSet,
+	used map[Node]bool,
+) ([]Edge, bool) {
+	return bg.findDisjointSLAPHelper(start, EdgeSet{}, len(guideLayers)-1, matching, guideLayers, used)
+}
+
+func (bg *BipartiteGraph) findDisjointSLAPHelper(
+	currentNode Node,
+	currentSLAP EdgeSet,
+	currentLevel int,
+	matching EdgeSet,
+	guideLayers []NodeOrderedSet,
+	used map[Node]bool,
+) (EdgeSet, bool) {
+	used[currentNode] = true
+
+	if currentLevel == 0 {
+		return currentSLAP, true
+	}
+
+	for _, nextNode := range guideLayers[currentLevel-1] {
+		if used[nextNode] {
+			continue
+		}
+
+		edge, found := bg.Edges.FindByNodes(currentNode, nextNode)
+		if !found {
+			continue
+		}
+
+		if matching.Contains(edge) == util.Odd(currentLevel) {
+			continue
+		}
+
+		currentSLAP = append(currentSLAP, edge)
+		slap, found := bg.findDisjointSLAPHelper(nextNode, currentSLAP, currentLevel-1, matching, guideLayers, used)
+		if found {
+			return slap, true
+		}
+		currentSLAP = currentSLAP[:len(currentSLAP)-1]
+	}
+
+	used[currentNode] = false
+	return nil, false
+}
+
+func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers []NodeOrderedSet) {
+	used := make(map[Node]bool)
+	currentLayer := NodeOrderedSet{}
+
+	for _, node := range bg.Left {
+		if matching.Free(node) {
+			used[node] = true
+			currentLayer = append(currentLayer, node)
+		}
+	}
+
+	if len(currentLayer) == 0 {
+		return []NodeOrderedSet{}
+	}
+	guideLayers = append(guideLayers, currentLayer)
+
+	done := false
+
+	for !done {
+		lastLayer := currentLayer
+		currentLayer = NodeOrderedSet{}
+
+		if util.Odd(len(guideLayers)) {
+			for _, leftNode := range lastLayer {
+				for _, rightNode := range bg.Right {
+					if used[rightNode] {
+						continue
+					}
+
+					edge, found := bg.Edges.FindByNodes(leftNode, rightNode)
+					if !found || matching.Contains(edge) {
+						continue
+					}
+
+					currentLayer = append(currentLayer, rightNode)
+					used[rightNode] = true
+
+					if matching.Free(rightNode) {
+						done = true
+					}
+				}
+			}
+		} else {
+			for _, rightNode := range lastLayer {
+				for _, leftNode := range bg.Left {
+					if used[leftNode] {
+						continue
+					}
+
+					edge, found := bg.Edges.FindByNodes(leftNode, rightNode)
+					if !found || !matching.Contains(edge) {
+						continue
+					}
+
+					currentLayer = append(currentLayer, leftNode)
+					used[leftNode] = true
+				}
+			}
+
+		}
+
+		if len(currentLayer) == 0 {
+			return []NodeOrderedSet{}
+		}
+		guideLayers = append(guideLayers, currentLayer)
+	}
+
+	return
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go
new file mode 100644
index 0000000..4fd15cc
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go
@@ -0,0 +1,61 @@
+package edge
+
+import . "github.com/onsi/gomega/matchers/support/goraph/node"
+
+type Edge struct {
+	Node1 Node
+	Node2 Node
+}
+
+type EdgeSet []Edge
+
+func (ec EdgeSet) Free(node Node) bool {
+	for _, e := range ec {
+		if e.Node1 == node || e.Node2 == node {
+			return false
+		}
+	}
+
+	return true
+}
+
+func (ec EdgeSet) Contains(edge Edge) bool {
+	for _, e := range ec {
+		if e == edge {
+			return true
+		}
+	}
+
+	return false
+}
+
+func (ec EdgeSet) FindByNodes(node1, node2 Node) (Edge, bool) {
+	for _, e := range ec {
+		if (e.Node1 == node1 && e.Node2 == node2) || (e.Node1 == node2 && e.Node2 == node1) {
+			return e, true
+		}
+	}
+
+	return Edge{}, false
+}
+
+func (ec EdgeSet) SymmetricDifference(ec2 EdgeSet) EdgeSet {
+	edgesToInclude := make(map[Edge]bool)
+
+	for _, e := range ec {
+		edgesToInclude[e] = true
+	}
+
+	for _, e := range ec2 {
+		edgesToInclude[e] = !edgesToInclude[e]
+	}
+
+	result := EdgeSet{}
+	for e, include := range edgesToInclude {
+		if include {
+			result = append(result, e)
+		}
+	}
+
+	return result
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go
new file mode 100644
index 0000000..800c2ea
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go
@@ -0,0 +1,7 @@
+package node
+
+type Node struct {
+	Id int
+}
+
+type NodeOrderedSet []Node
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/util/util.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/util/util.go
new file mode 100644
index 0000000..d76a1ee
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/util/util.go
@@ -0,0 +1,7 @@
+package util
+
+import "math"
+
+func Odd(n int) bool {
+	return math.Mod(float64(n), 2.0) == 1.0
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/type_support.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/type_support.go
new file mode 100644
index 0000000..b05a5e7
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/type_support.go
@@ -0,0 +1,173 @@
+/*
+Gomega matchers
+
+This package implements the Gomega matchers and does not typically need to be imported.
+See the docs for Gomega for documentation on the matchers
+
+http://onsi.github.io/gomega/
+*/
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+)
+
+type omegaMatcher interface {
+	Match(actual interface{}) (success bool, err error)
+	FailureMessage(actual interface{}) (message string)
+	NegatedFailureMessage(actual interface{}) (message string)
+}
+
+func isBool(a interface{}) bool {
+	return reflect.TypeOf(a).Kind() == reflect.Bool
+}
+
+func isNumber(a interface{}) bool {
+	if a == nil {
+		return false
+	}
+	kind := reflect.TypeOf(a).Kind()
+	return reflect.Int <= kind && kind <= reflect.Float64
+}
+
+func isInteger(a interface{}) bool {
+	kind := reflect.TypeOf(a).Kind()
+	return reflect.Int <= kind && kind <= reflect.Int64
+}
+
+func isUnsignedInteger(a interface{}) bool {
+	kind := reflect.TypeOf(a).Kind()
+	return reflect.Uint <= kind && kind <= reflect.Uint64
+}
+
+func isFloat(a interface{}) bool {
+	kind := reflect.TypeOf(a).Kind()
+	return reflect.Float32 <= kind && kind <= reflect.Float64
+}
+
+func toInteger(a interface{}) int64 {
+	if isInteger(a) {
+		return reflect.ValueOf(a).Int()
+	} else if isUnsignedInteger(a) {
+		return int64(reflect.ValueOf(a).Uint())
+	} else if isFloat(a) {
+		return int64(reflect.ValueOf(a).Float())
+	}
+	panic(fmt.Sprintf("Expected a number!  Got <%T> %#v", a, a))
+}
+
+func toUnsignedInteger(a interface{}) uint64 {
+	if isInteger(a) {
+		return uint64(reflect.ValueOf(a).Int())
+	} else if isUnsignedInteger(a) {
+		return reflect.ValueOf(a).Uint()
+	} else if isFloat(a) {
+		return uint64(reflect.ValueOf(a).Float())
+	}
+	panic(fmt.Sprintf("Expected a number!  Got <%T> %#v", a, a))
+}
+
+func toFloat(a interface{}) float64 {
+	if isInteger(a) {
+		return float64(reflect.ValueOf(a).Int())
+	} else if isUnsignedInteger(a) {
+		return float64(reflect.ValueOf(a).Uint())
+	} else if isFloat(a) {
+		return reflect.ValueOf(a).Float()
+	}
+	panic(fmt.Sprintf("Expected a number!  Got <%T> %#v", a, a))
+}
+
+func isError(a interface{}) bool {
+	_, ok := a.(error)
+	return ok
+}
+
+func isChan(a interface{}) bool {
+	if isNil(a) {
+		return false
+	}
+	return reflect.TypeOf(a).Kind() == reflect.Chan
+}
+
+func isMap(a interface{}) bool {
+	if a == nil {
+		return false
+	}
+	return reflect.TypeOf(a).Kind() == reflect.Map
+}
+
+func isArrayOrSlice(a interface{}) bool {
+	if a == nil {
+		return false
+	}
+	switch reflect.TypeOf(a).Kind() {
+	case reflect.Array, reflect.Slice:
+		return true
+	default:
+		return false
+	}
+}
+
+func isString(a interface{}) bool {
+	if a == nil {
+		return false
+	}
+	return reflect.TypeOf(a).Kind() == reflect.String
+}
+
+func toString(a interface{}) (string, bool) {
+	aString, isString := a.(string)
+	if isString {
+		return aString, true
+	}
+
+	aBytes, isBytes := a.([]byte)
+	if isBytes {
+		return string(aBytes), true
+	}
+
+	aStringer, isStringer := a.(fmt.Stringer)
+	if isStringer {
+		return aStringer.String(), true
+	}
+
+	return "", false
+}
+
+func lengthOf(a interface{}) (int, bool) {
+	if a == nil {
+		return 0, false
+	}
+	switch reflect.TypeOf(a).Kind() {
+	case reflect.Map, reflect.Array, reflect.String, reflect.Chan, reflect.Slice:
+		return reflect.ValueOf(a).Len(), true
+	default:
+		return 0, false
+	}
+}
+func capOf(a interface{}) (int, bool) {
+	if a == nil {
+		return 0, false
+	}
+	switch reflect.TypeOf(a).Kind() {
+	case reflect.Array, reflect.Chan, reflect.Slice:
+		return reflect.ValueOf(a).Cap(), true
+	default:
+		return 0, false
+	}
+}
+
+func isNil(a interface{}) bool {
+	if a == nil {
+		return true
+	}
+
+	switch reflect.TypeOf(a).Kind() {
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+		return reflect.ValueOf(a).IsNil()
+	}
+
+	return false
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/with_transform.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/with_transform.go
new file mode 100644
index 0000000..8e58d8a
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/with_transform.go
@@ -0,0 +1,72 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/internal/oraclematcher"
+	"github.com/onsi/gomega/types"
+)
+
+type WithTransformMatcher struct {
+	// input
+	Transform interface{} // must be a function of one parameter that returns one value
+	Matcher   types.GomegaMatcher
+
+	// cached value
+	transformArgType reflect.Type
+
+	// state
+	transformedValue interface{}
+}
+
+func NewWithTransformMatcher(transform interface{}, matcher types.GomegaMatcher) *WithTransformMatcher {
+	if transform == nil {
+		panic("transform function cannot be nil")
+	}
+	txType := reflect.TypeOf(transform)
+	if txType.NumIn() != 1 {
+		panic("transform function must have 1 argument")
+	}
+	if txType.NumOut() != 1 {
+		panic("transform function must have 1 return value")
+	}
+
+	return &WithTransformMatcher{
+		Transform:        transform,
+		Matcher:          matcher,
+		transformArgType: reflect.TypeOf(transform).In(0),
+	}
+}
+
+func (m *WithTransformMatcher) Match(actual interface{}) (bool, error) {
+	// return error if actual's type is incompatible with Transform function's argument type
+	actualType := reflect.TypeOf(actual)
+	if !actualType.AssignableTo(m.transformArgType) {
+		return false, fmt.Errorf("Transform function expects '%s' but we have '%s'", m.transformArgType, actualType)
+	}
+
+	// call the Transform function with `actual`
+	fn := reflect.ValueOf(m.Transform)
+	result := fn.Call([]reflect.Value{reflect.ValueOf(actual)})
+	m.transformedValue = result[0].Interface() // expect exactly one value
+
+	return m.Matcher.Match(m.transformedValue)
+}
+
+func (m *WithTransformMatcher) FailureMessage(_ interface{}) (message string) {
+	return m.Matcher.FailureMessage(m.transformedValue)
+}
+
+func (m *WithTransformMatcher) NegatedFailureMessage(_ interface{}) (message string) {
+	return m.Matcher.NegatedFailureMessage(m.transformedValue)
+}
+
+func (m *WithTransformMatcher) MatchMayChangeInTheFuture(_ interface{}) bool {
+	// TODO: Maybe this should always just return true? (Only an issue for non-deterministic transformers.)
+	//
+	// Querying the next matcher is fine if the transformer always will return the same value.
+	// But if the transformer is non-deterministic and returns a different value each time, then there
+	// is no point in querying the next matcher, since it can only comment on the last transformed value.
+	return oraclematcher.MatchMayChangeInTheFuture(m.Matcher, m.transformedValue)
+}