diff --git a/Makefile b/Makefile
index ae31832..de5f790 100644
--- a/Makefile
+++ b/Makefile
@@ -54,7 +54,7 @@
 	rw_core
 
 
-.PHONY: $(DIRS) $(DIRS_CLEAN) $(DIRS_FLAKE8) rw_core protos kafka db tests python simulators k8s
+.PHONY: $(DIRS) $(DIRS_CLEAN) $(DIRS_FLAKE8) rw_core protos kafka db tests python simulators k8s afrouter arouterd
 
 # This should to be the first and default target in this Makefile
 help:
@@ -80,30 +80,21 @@
 
 build: containers
 
-containers: rw_core simulated_olt simulated_onu
+containers: rw_core simulated_olt simulated_onu afrouter arouterd
 
-ifneq ($(VOLTHA_BUILD),docker)
+afrouter:
+	docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}arouter:${TAG} -f docker/Dockerfile.arouter .
+
+arouterd:
+	docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}arouterd:${TAG} -f docker/Dockerfile.arouterd .
+
 rw_core:
 	docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}voltha-rw-core:${TAG} -f docker/Dockerfile.rw_core .
-else
-rw_core:
-	docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}voltha-rw-core:${TAG} -f docker/Dockerfile.rw_core_d .
-endif
 
-ifneq ($(VOLTHA_BUILD),docker)
 simulated_olt:
 	docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}voltha-adapter-simulated-olt:${TAG} -f docker/Dockerfile.simulated_olt .
-else
-simulated_olt:
-	docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}voltha-adapter-simulated-olt:${TAG} -f docker/Dockerfile.simulated_olt_d .
-endif
 
-ifneq ($(VOLTHA_BUILD),docker)
 simulated_onu:
 	docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}voltha-adapter-simulated-onu:${TAG} -f docker/Dockerfile.simulated_onu .
-else
-simulated_onu:
-	docker build $(DOCKER_BUILD_ARGS) -t ${REGISTRY}${REPOSITORY}voltha-adapter-simulated-onu:${TAG} -f docker/Dockerfile.simulated_onu_d .
-endif
 
 # end file
diff --git a/docker/Dockerfile.arouter b/docker/Dockerfile.arouter
new file mode 100644
index 0000000..be87905
--- /dev/null
+++ b/docker/Dockerfile.arouter
@@ -0,0 +1,74 @@
+# -------------
+# Build stage
+
+FROM golang:1.10-alpine AS build-env
+
+
+# Install required packages
+RUN apk add --no-cache wget git make build-base protobuf protobuf-dev
+
+RUN git clone https://github.com/googleapis/googleapis.git /usr/local/include/googleapis
+
+# Prepare directory structure
+RUN ["mkdir", "-p", "/src", "src/protos"]
+RUN ["mkdir", "-p", "$GOPATH/src", "$GOPATH/pkg", "$GOPATH/bin"]
+RUN ["mkdir", "-p", "$GOPATH/src/github.com/opencord/voltha/protos/go"]
+
+# Install golang protobuf
+RUN go get github.com/golang/protobuf/protoc-gen-go
+RUN go get google.golang.org/genproto/googleapis/rpc/status
+RUN go get google.golang.org/grpc/binarylog/grpc_binarylog_v1
+
+# Copy files
+ADD rw_core $GOPATH/src/github.com/opencord/voltha-go/rw_core
+ADD common $GOPATH/src/github.com/opencord/voltha-go/common
+ADD db $GOPATH/src/github.com/opencord/voltha-go/db
+ADD kafka $GOPATH/src/github.com/opencord/voltha-go/kafka
+ADD vendor $GOPATH/src/github.com/opencord/voltha-go/vendor
+ADD afrouter $GOPATH/src/github.com/opencord/voltha-go/afrouter
+
+
+# Copy required proto files
+# ... VOLTHA proos
+ADD protos/*.proto /src/protos/
+ADD protos/scripts/* /src/protos/
+ADD afrouter/arouter.json /src
+
+#
+# Copy generated executables here
+WORKDIR $GOPATH/src/github.com/opencord/voltha-go
+
+#RUN ls -ltrR /go/src/github.com/opencord/voltha-go
+
+# Install golang protobuf
+#RUN go get github.com/golang/protobuf/protoc-gen-go
+#RUN go get google.golang.org/genproto/googleapis/rpc/status
+#RUN go get google.golang.org/grpc/binarylog/grpc_binarylog_v1
+RUN go install ./vendor/github.com/golang/protobuf/protoc-gen-go
+
+# Compile protobuf files
+RUN sh /src/protos/build_protos.sh /src/protos
+
+# Build rw_core
+RUN cd afrouter && go build -o /src/afrouter
+
+
+# -------------
+# Image creation stage
+
+FROM alpine:3.6
+
+# Set the working directory
+WORKDIR /app
+
+# Copy required files
+COPY --from=build-env /src/afrouter /app/
+COPY --from=build-env /src/arouter.json /app/
+COPY --from=build-env /src/protos/voltha.pb /app/
+WORKDIR config
+WORKDIR /app
+
+#CMD cd /app && ./arouter -config config/arouter.voltha2.json
+
+# Set the config volume
+
diff --git a/docker/Dockerfile.arouterd b/docker/Dockerfile.arouterd
new file mode 100644
index 0000000..eba62e1
--- /dev/null
+++ b/docker/Dockerfile.arouterd
@@ -0,0 +1,71 @@
+# -------------
+# Build stage
+
+FROM golang:1.10-alpine AS build-env
+
+
+# Install required packages
+RUN apk add --no-cache wget git make build-base protobuf protobuf-dev curl
+
+RUN curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
+
+RUN git clone https://github.com/googleapis/googleapis.git /usr/local/include/googleapis
+
+# Prepare directory structure
+RUN ["mkdir", "-p", "/src", "src/protos"]
+RUN ["mkdir", "-p", "$GOPATH/src", "$GOPATH/pkg", "$GOPATH/bin"]
+RUN ["mkdir", "-p", "$GOPATH/src/github.com/opencord/voltha/protos/go"]
+
+# Install golang protobuf
+RUN go get github.com/golang/protobuf/protoc-gen-go
+RUN go get google.golang.org/genproto/googleapis/rpc/status
+RUN go get google.golang.org/grpc/binarylog/grpc_binarylog_v1
+
+# Copy files
+ADD rw_core $GOPATH/src/github.com/opencord/voltha-go/rw_core
+ADD common $GOPATH/src/github.com/opencord/voltha-go/common
+ADD db $GOPATH/src/github.com/opencord/voltha-go/db
+ADD kafka $GOPATH/src/github.com/opencord/voltha-go/kafka
+ADD vendor $GOPATH/src/github.com/opencord/voltha-go/vendor
+ADD afrouter $GOPATH/src/github.com/opencord/voltha-go/afrouter
+ADD arouterd $GOPATH/src/github.com/opencord/voltha-go/arouterd
+ADD Gopkg.lock $GOPATH/src/github.com/opencord/voltha-go
+ADD Gopkg.toml $GOPATH/src/github.com/opencord/voltha-go
+
+
+# Copy required proto files
+# ... VOLTHA proos
+ADD protos/*.proto /src/protos/
+ADD protos/scripts/* /src/protos/
+ADD afrouter/arouter.json /src
+
+#
+# Copy generated executables here
+WORKDIR $GOPATH/src/github.com/opencord/voltha-go
+#RUN $GOPATH/bin/dep ensure -add github.com/coreos/etcd
+
+#RUN ls -ltrR /go/src/github.com/opencord/voltha-go
+
+# Install golang protobuf
+#RUN go get github.com/golang/protobuf/protoc-gen-go
+#RUN go get google.golang.org/genproto/googleapis/rpc/status
+#RUN go get google.golang.org/grpc/binarylog/grpc_binarylog_v1
+RUN go install ./vendor/github.com/golang/protobuf/protoc-gen-go
+
+# Compile protobuf files
+RUN sh /src/protos/build_protos.sh /src/protos
+
+# Build rw_core
+RUN cd arouterd && go build -o /src/arouterd
+
+
+# -------------
+# Image creation stage
+
+FROM alpine:3.6
+
+# Set the working directory
+WORKDIR /app
+
+# Copy required files
+COPY --from=build-env /src/arouterd /app/
diff --git a/k8s/affinity-router.yml b/k8s/affinity-router.yml
new file mode 100644
index 0000000..28c2623
--- /dev/null
+++ b/k8s/affinity-router.yml
@@ -0,0 +1,52 @@
+# Copyright 2018 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: v1
+kind: Pod
+metadata:
+  name: afrouter
+  namespace: voltha
+  labels:
+    app: afrouter
+  annotations:
+    cni: "calico"
+spec:
+  containers:
+  - name: arouter
+    image: volthacore/afrouter:testing
+    imagePullPolicy: Always
+    volumeMounts:
+    - name: config-volume
+      mountPath: /app/config
+    ports:
+    - containerPort: 55555
+    command: ["/app/afrouter"]
+    args: ["-config", "/app/config/arouter.voltha3.json"]
+  - name: envoy
+    image: volthacore/envoy
+    volumeMounts:
+    - name: config-volume
+      mountPath: /envoy/config
+    ports:
+    - containerPort: 8192
+    - containerPort: 50555
+  - name: arouterd
+    image: volthacore/afrouterd:testing
+    command: ["/app/arouterd"]
+    imagePullPolicy: Always
+  restartPolicy: Never
+  volumes:
+    - name: config-volume
+      configMap:
+        name: afrouter-config
diff --git a/protos/afrouter.proto b/protos/afrouter.proto
new file mode 100644
index 0000000..903e5cc
--- /dev/null
+++ b/protos/afrouter.proto
@@ -0,0 +1,36 @@
+// protoc -I echo/ echo/*.proto --go_out=plugins=grpc:echo
+
+syntax = "proto3";
+
+option go_package = "github.com/opencord/voltha-go/protos/afrouter";
+
+package afrouter;
+
+service Configuration {
+    rpc SetConnection (Conn) returns (Result) {}
+	rpc SetAffinity(Affinity) returns (Result) {}
+}
+
+message Result {
+	bool success = 1;
+	string error = 2;
+}
+
+message Conn {
+	string server = 1;
+	string pkg = 2;
+	string svc = 3;
+	string cluster = 4;
+	string backend = 5;
+	string connection = 6;
+	string addr = 7;
+	uint64 port = 8;
+}
+
+message Affinity {
+	string router = 1;
+	string route = 2;
+	string cluster = 3;
+	string backend = 4;
+	string id = 5;
+}
diff --git a/protos/scripts/build_protos.sh b/protos/scripts/build_protos.sh
index 8702e05..d221fa5 100755
--- a/protos/scripts/build_protos.sh
+++ b/protos/scripts/build_protos.sh
@@ -42,6 +42,7 @@
 export IETF_PB="$SRC_DIR/ietf_interfaces.proto"
 export OF_PB="$SRC_DIR/openflow_13.proto"
 export OMCI_PB="$SRC_DIR/omci*.proto"
+export AFROUTER_PB="$SRC_DIR/afrouter.proto"
 
 export PB_VARS="\
     VOLTHA_PB \
@@ -50,7 +51,11 @@
     SCHEMA_PB \
     IETF_PB \
     OF_PB \
-    OMCI_PB"
+    OMCI_PB \
+    AFROUTER_PB"
+
+export OTHER_INCLUDES="/usr/local/include/googleapis"
+export PROTO_DESC_FILE="${SRC_DIR}/voltha.pb"
 
 for pb_var in $PB_VARS
 do
@@ -58,3 +63,5 @@
     echo "Compiling $pbs"
     protoc --go_out=$MAPS,plugins=grpc:$GOPATH/src $INCS $pbs
 done
+
+protoc -I ${SRC_DIR} -I ${OTHER_INCLUDES} --include_imports --include_source_info --descriptor_set_out=${PROTO_DESC_FILE} ${SRC_DIR}/*.proto
diff --git a/vendor/github.com/beorn7/perks/LICENSE b/vendor/github.com/beorn7/perks/LICENSE
deleted file mode 100644
index 339177b..0000000
--- a/vendor/github.com/beorn7/perks/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (C) 2013 Blake Mizerany
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/beorn7/perks/quantile/exampledata.txt b/vendor/github.com/beorn7/perks/quantile/exampledata.txt
deleted file mode 100644
index 1602287..0000000
--- a/vendor/github.com/beorn7/perks/quantile/exampledata.txt
+++ /dev/null
@@ -1,2388 +0,0 @@
-8
-5
-26
-12
-5
-235
-13
-6
-28
-30
-3
-3
-3
-3
-5
-2
-33
-7
-2
-4
-7
-12
-14
-5
-8
-3
-10
-4
-5
-3
-6
-6
-209
-20
-3
-10
-14
-3
-4
-6
-8
-5
-11
-7
-3
-2
-3
-3
-212
-5
-222
-4
-10
-10
-5
-6
-3
-8
-3
-10
-254
-220
-2
-3
-5
-24
-5
-4
-222
-7
-3
-3
-223
-8
-15
-12
-14
-14
-3
-2
-2
-3
-13
-3
-11
-4
-4
-6
-5
-7
-13
-5
-3
-5
-2
-5
-3
-5
-2
-7
-15
-17
-14
-3
-6
-6
-3
-17
-5
-4
-7
-6
-4
-4
-8
-6
-8
-3
-9
-3
-6
-3
-4
-5
-3
-3
-660
-4
-6
-10
-3
-6
-3
-2
-5
-13
-2
-4
-4
-10
-4
-8
-4
-3
-7
-9
-9
-3
-10
-37
-3
-13
-4
-12
-3
-6
-10
-8
-5
-21
-2
-3
-8
-3
-2
-3
-3
-4
-12
-2
-4
-8
-8
-4
-3
-2
-20
-1
-6
-32
-2
-11
-6
-18
-3
-8
-11
-3
-212
-3
-4
-2
-6
-7
-12
-11
-3
-2
-16
-10
-6
-4
-6
-3
-2
-7
-3
-2
-2
-2
-2
-5
-6
-4
-3
-10
-3
-4
-6
-5
-3
-4
-4
-5
-6
-4
-3
-4
-4
-5
-7
-5
-5
-3
-2
-7
-2
-4
-12
-4
-5
-6
-2
-4
-4
-8
-4
-15
-13
-7
-16
-5
-3
-23
-5
-5
-7
-3
-2
-9
-8
-7
-5
-8
-11
-4
-10
-76
-4
-47
-4
-3
-2
-7
-4
-2
-3
-37
-10
-4
-2
-20
-5
-4
-4
-10
-10
-4
-3
-7
-23
-240
-7
-13
-5
-5
-3
-3
-2
-5
-4
-2
-8
-7
-19
-2
-23
-8
-7
-2
-5
-3
-8
-3
-8
-13
-5
-5
-5
-2
-3
-23
-4
-9
-8
-4
-3
-3
-5
-220
-2
-3
-4
-6
-14
-3
-53
-6
-2
-5
-18
-6
-3
-219
-6
-5
-2
-5
-3
-6
-5
-15
-4
-3
-17
-3
-2
-4
-7
-2
-3
-3
-4
-4
-3
-2
-664
-6
-3
-23
-5
-5
-16
-5
-8
-2
-4
-2
-24
-12
-3
-2
-3
-5
-8
-3
-5
-4
-3
-14
-3
-5
-8
-2
-3
-7
-9
-4
-2
-3
-6
-8
-4
-3
-4
-6
-5
-3
-3
-6
-3
-19
-4
-4
-6
-3
-6
-3
-5
-22
-5
-4
-4
-3
-8
-11
-4
-9
-7
-6
-13
-4
-4
-4
-6
-17
-9
-3
-3
-3
-4
-3
-221
-5
-11
-3
-4
-2
-12
-6
-3
-5
-7
-5
-7
-4
-9
-7
-14
-37
-19
-217
-16
-3
-5
-2
-2
-7
-19
-7
-6
-7
-4
-24
-5
-11
-4
-7
-7
-9
-13
-3
-4
-3
-6
-28
-4
-4
-5
-5
-2
-5
-6
-4
-4
-6
-10
-5
-4
-3
-2
-3
-3
-6
-5
-5
-4
-3
-2
-3
-7
-4
-6
-18
-16
-8
-16
-4
-5
-8
-6
-9
-13
-1545
-6
-215
-6
-5
-6
-3
-45
-31
-5
-2
-2
-4
-3
-3
-2
-5
-4
-3
-5
-7
-7
-4
-5
-8
-5
-4
-749
-2
-31
-9
-11
-2
-11
-5
-4
-4
-7
-9
-11
-4
-5
-4
-7
-3
-4
-6
-2
-15
-3
-4
-3
-4
-3
-5
-2
-13
-5
-5
-3
-3
-23
-4
-4
-5
-7
-4
-13
-2
-4
-3
-4
-2
-6
-2
-7
-3
-5
-5
-3
-29
-5
-4
-4
-3
-10
-2
-3
-79
-16
-6
-6
-7
-7
-3
-5
-5
-7
-4
-3
-7
-9
-5
-6
-5
-9
-6
-3
-6
-4
-17
-2
-10
-9
-3
-6
-2
-3
-21
-22
-5
-11
-4
-2
-17
-2
-224
-2
-14
-3
-4
-4
-2
-4
-4
-4
-4
-5
-3
-4
-4
-10
-2
-6
-3
-3
-5
-7
-2
-7
-5
-6
-3
-218
-2
-2
-5
-2
-6
-3
-5
-222
-14
-6
-33
-3
-2
-5
-3
-3
-3
-9
-5
-3
-3
-2
-7
-4
-3
-4
-3
-5
-6
-5
-26
-4
-13
-9
-7
-3
-221
-3
-3
-4
-4
-4
-4
-2
-18
-5
-3
-7
-9
-6
-8
-3
-10
-3
-11
-9
-5
-4
-17
-5
-5
-6
-6
-3
-2
-4
-12
-17
-6
-7
-218
-4
-2
-4
-10
-3
-5
-15
-3
-9
-4
-3
-3
-6
-29
-3
-3
-4
-5
-5
-3
-8
-5
-6
-6
-7
-5
-3
-5
-3
-29
-2
-31
-5
-15
-24
-16
-5
-207
-4
-3
-3
-2
-15
-4
-4
-13
-5
-5
-4
-6
-10
-2
-7
-8
-4
-6
-20
-5
-3
-4
-3
-12
-12
-5
-17
-7
-3
-3
-3
-6
-10
-3
-5
-25
-80
-4
-9
-3
-2
-11
-3
-3
-2
-3
-8
-7
-5
-5
-19
-5
-3
-3
-12
-11
-2
-6
-5
-5
-5
-3
-3
-3
-4
-209
-14
-3
-2
-5
-19
-4
-4
-3
-4
-14
-5
-6
-4
-13
-9
-7
-4
-7
-10
-2
-9
-5
-7
-2
-8
-4
-6
-5
-5
-222
-8
-7
-12
-5
-216
-3
-4
-4
-6
-3
-14
-8
-7
-13
-4
-3
-3
-3
-3
-17
-5
-4
-3
-33
-6
-6
-33
-7
-5
-3
-8
-7
-5
-2
-9
-4
-2
-233
-24
-7
-4
-8
-10
-3
-4
-15
-2
-16
-3
-3
-13
-12
-7
-5
-4
-207
-4
-2
-4
-27
-15
-2
-5
-2
-25
-6
-5
-5
-6
-13
-6
-18
-6
-4
-12
-225
-10
-7
-5
-2
-2
-11
-4
-14
-21
-8
-10
-3
-5
-4
-232
-2
-5
-5
-3
-7
-17
-11
-6
-6
-23
-4
-6
-3
-5
-4
-2
-17
-3
-6
-5
-8
-3
-2
-2
-14
-9
-4
-4
-2
-5
-5
-3
-7
-6
-12
-6
-10
-3
-6
-2
-2
-19
-5
-4
-4
-9
-2
-4
-13
-3
-5
-6
-3
-6
-5
-4
-9
-6
-3
-5
-7
-3
-6
-6
-4
-3
-10
-6
-3
-221
-3
-5
-3
-6
-4
-8
-5
-3
-6
-4
-4
-2
-54
-5
-6
-11
-3
-3
-4
-4
-4
-3
-7
-3
-11
-11
-7
-10
-6
-13
-223
-213
-15
-231
-7
-3
-7
-228
-2
-3
-4
-4
-5
-6
-7
-4
-13
-3
-4
-5
-3
-6
-4
-6
-7
-2
-4
-3
-4
-3
-3
-6
-3
-7
-3
-5
-18
-5
-6
-8
-10
-3
-3
-3
-2
-4
-2
-4
-4
-5
-6
-6
-4
-10
-13
-3
-12
-5
-12
-16
-8
-4
-19
-11
-2
-4
-5
-6
-8
-5
-6
-4
-18
-10
-4
-2
-216
-6
-6
-6
-2
-4
-12
-8
-3
-11
-5
-6
-14
-5
-3
-13
-4
-5
-4
-5
-3
-28
-6
-3
-7
-219
-3
-9
-7
-3
-10
-6
-3
-4
-19
-5
-7
-11
-6
-15
-19
-4
-13
-11
-3
-7
-5
-10
-2
-8
-11
-2
-6
-4
-6
-24
-6
-3
-3
-3
-3
-6
-18
-4
-11
-4
-2
-5
-10
-8
-3
-9
-5
-3
-4
-5
-6
-2
-5
-7
-4
-4
-14
-6
-4
-4
-5
-5
-7
-2
-4
-3
-7
-3
-3
-6
-4
-5
-4
-4
-4
-3
-3
-3
-3
-8
-14
-2
-3
-5
-3
-2
-4
-5
-3
-7
-3
-3
-18
-3
-4
-4
-5
-7
-3
-3
-3
-13
-5
-4
-8
-211
-5
-5
-3
-5
-2
-5
-4
-2
-655
-6
-3
-5
-11
-2
-5
-3
-12
-9
-15
-11
-5
-12
-217
-2
-6
-17
-3
-3
-207
-5
-5
-4
-5
-9
-3
-2
-8
-5
-4
-3
-2
-5
-12
-4
-14
-5
-4
-2
-13
-5
-8
-4
-225
-4
-3
-4
-5
-4
-3
-3
-6
-23
-9
-2
-6
-7
-233
-4
-4
-6
-18
-3
-4
-6
-3
-4
-4
-2
-3
-7
-4
-13
-227
-4
-3
-5
-4
-2
-12
-9
-17
-3
-7
-14
-6
-4
-5
-21
-4
-8
-9
-2
-9
-25
-16
-3
-6
-4
-7
-8
-5
-2
-3
-5
-4
-3
-3
-5
-3
-3
-3
-2
-3
-19
-2
-4
-3
-4
-2
-3
-4
-4
-2
-4
-3
-3
-3
-2
-6
-3
-17
-5
-6
-4
-3
-13
-5
-3
-3
-3
-4
-9
-4
-2
-14
-12
-4
-5
-24
-4
-3
-37
-12
-11
-21
-3
-4
-3
-13
-4
-2
-3
-15
-4
-11
-4
-4
-3
-8
-3
-4
-4
-12
-8
-5
-3
-3
-4
-2
-220
-3
-5
-223
-3
-3
-3
-10
-3
-15
-4
-241
-9
-7
-3
-6
-6
-23
-4
-13
-7
-3
-4
-7
-4
-9
-3
-3
-4
-10
-5
-5
-1
-5
-24
-2
-4
-5
-5
-6
-14
-3
-8
-2
-3
-5
-13
-13
-3
-5
-2
-3
-15
-3
-4
-2
-10
-4
-4
-4
-5
-5
-3
-5
-3
-4
-7
-4
-27
-3
-6
-4
-15
-3
-5
-6
-6
-5
-4
-8
-3
-9
-2
-6
-3
-4
-3
-7
-4
-18
-3
-11
-3
-3
-8
-9
-7
-24
-3
-219
-7
-10
-4
-5
-9
-12
-2
-5
-4
-4
-4
-3
-3
-19
-5
-8
-16
-8
-6
-22
-3
-23
-3
-242
-9
-4
-3
-3
-5
-7
-3
-3
-5
-8
-3
-7
-5
-14
-8
-10
-3
-4
-3
-7
-4
-6
-7
-4
-10
-4
-3
-11
-3
-7
-10
-3
-13
-6
-8
-12
-10
-5
-7
-9
-3
-4
-7
-7
-10
-8
-30
-9
-19
-4
-3
-19
-15
-4
-13
-3
-215
-223
-4
-7
-4
-8
-17
-16
-3
-7
-6
-5
-5
-4
-12
-3
-7
-4
-4
-13
-4
-5
-2
-5
-6
-5
-6
-6
-7
-10
-18
-23
-9
-3
-3
-6
-5
-2
-4
-2
-7
-3
-3
-2
-5
-5
-14
-10
-224
-6
-3
-4
-3
-7
-5
-9
-3
-6
-4
-2
-5
-11
-4
-3
-3
-2
-8
-4
-7
-4
-10
-7
-3
-3
-18
-18
-17
-3
-3
-3
-4
-5
-3
-3
-4
-12
-7
-3
-11
-13
-5
-4
-7
-13
-5
-4
-11
-3
-12
-3
-6
-4
-4
-21
-4
-6
-9
-5
-3
-10
-8
-4
-6
-4
-4
-6
-5
-4
-8
-6
-4
-6
-4
-4
-5
-9
-6
-3
-4
-2
-9
-3
-18
-2
-4
-3
-13
-3
-6
-6
-8
-7
-9
-3
-2
-16
-3
-4
-6
-3
-2
-33
-22
-14
-4
-9
-12
-4
-5
-6
-3
-23
-9
-4
-3
-5
-5
-3
-4
-5
-3
-5
-3
-10
-4
-5
-5
-8
-4
-4
-6
-8
-5
-4
-3
-4
-6
-3
-3
-3
-5
-9
-12
-6
-5
-9
-3
-5
-3
-2
-2
-2
-18
-3
-2
-21
-2
-5
-4
-6
-4
-5
-10
-3
-9
-3
-2
-10
-7
-3
-6
-6
-4
-4
-8
-12
-7
-3
-7
-3
-3
-9
-3
-4
-5
-4
-4
-5
-5
-10
-15
-4
-4
-14
-6
-227
-3
-14
-5
-216
-22
-5
-4
-2
-2
-6
-3
-4
-2
-9
-9
-4
-3
-28
-13
-11
-4
-5
-3
-3
-2
-3
-3
-5
-3
-4
-3
-5
-23
-26
-3
-4
-5
-6
-4
-6
-3
-5
-5
-3
-4
-3
-2
-2
-2
-7
-14
-3
-6
-7
-17
-2
-2
-15
-14
-16
-4
-6
-7
-13
-6
-4
-5
-6
-16
-3
-3
-28
-3
-6
-15
-3
-9
-2
-4
-6
-3
-3
-22
-4
-12
-6
-7
-2
-5
-4
-10
-3
-16
-6
-9
-2
-5
-12
-7
-5
-5
-5
-5
-2
-11
-9
-17
-4
-3
-11
-7
-3
-5
-15
-4
-3
-4
-211
-8
-7
-5
-4
-7
-6
-7
-6
-3
-6
-5
-6
-5
-3
-4
-4
-26
-4
-6
-10
-4
-4
-3
-2
-3
-3
-4
-5
-9
-3
-9
-4
-4
-5
-5
-8
-2
-4
-2
-3
-8
-4
-11
-19
-5
-8
-6
-3
-5
-6
-12
-3
-2
-4
-16
-12
-3
-4
-4
-8
-6
-5
-6
-6
-219
-8
-222
-6
-16
-3
-13
-19
-5
-4
-3
-11
-6
-10
-4
-7
-7
-12
-5
-3
-3
-5
-6
-10
-3
-8
-2
-5
-4
-7
-2
-4
-4
-2
-12
-9
-6
-4
-2
-40
-2
-4
-10
-4
-223
-4
-2
-20
-6
-7
-24
-5
-4
-5
-2
-20
-16
-6
-5
-13
-2
-3
-3
-19
-3
-2
-4
-5
-6
-7
-11
-12
-5
-6
-7
-7
-3
-5
-3
-5
-3
-14
-3
-4
-4
-2
-11
-1
-7
-3
-9
-6
-11
-12
-5
-8
-6
-221
-4
-2
-12
-4
-3
-15
-4
-5
-226
-7
-218
-7
-5
-4
-5
-18
-4
-5
-9
-4
-4
-2
-9
-18
-18
-9
-5
-6
-6
-3
-3
-7
-3
-5
-4
-4
-4
-12
-3
-6
-31
-5
-4
-7
-3
-6
-5
-6
-5
-11
-2
-2
-11
-11
-6
-7
-5
-8
-7
-10
-5
-23
-7
-4
-3
-5
-34
-2
-5
-23
-7
-3
-6
-8
-4
-4
-4
-2
-5
-3
-8
-5
-4
-8
-25
-2
-3
-17
-8
-3
-4
-8
-7
-3
-15
-6
-5
-7
-21
-9
-5
-6
-6
-5
-3
-2
-3
-10
-3
-6
-3
-14
-7
-4
-4
-8
-7
-8
-2
-6
-12
-4
-213
-6
-5
-21
-8
-2
-5
-23
-3
-11
-2
-3
-6
-25
-2
-3
-6
-7
-6
-6
-4
-4
-6
-3
-17
-9
-7
-6
-4
-3
-10
-7
-2
-3
-3
-3
-11
-8
-3
-7
-6
-4
-14
-36
-3
-4
-3
-3
-22
-13
-21
-4
-2
-7
-4
-4
-17
-15
-3
-7
-11
-2
-4
-7
-6
-209
-6
-3
-2
-2
-24
-4
-9
-4
-3
-3
-3
-29
-2
-2
-4
-3
-3
-5
-4
-6
-3
-3
-2
-4
diff --git a/vendor/github.com/beorn7/perks/quantile/stream.go b/vendor/github.com/beorn7/perks/quantile/stream.go
deleted file mode 100644
index d7d14f8..0000000
--- a/vendor/github.com/beorn7/perks/quantile/stream.go
+++ /dev/null
@@ -1,316 +0,0 @@
-// Package quantile computes approximate quantiles over an unbounded data
-// stream within low memory and CPU bounds.
-//
-// A small amount of accuracy is traded to achieve the above properties.
-//
-// Multiple streams can be merged before calling Query to generate a single set
-// of results. This is meaningful when the streams represent the same type of
-// data. See Merge and Samples.
-//
-// For more detailed information about the algorithm used, see:
-//
-// Effective Computation of Biased Quantiles over Data Streams
-//
-// http://www.cs.rutgers.edu/~muthu/bquant.pdf
-package quantile
-
-import (
-	"math"
-	"sort"
-)
-
-// Sample holds an observed value and meta information for compression. JSON
-// tags have been added for convenience.
-type Sample struct {
-	Value float64 `json:",string"`
-	Width float64 `json:",string"`
-	Delta float64 `json:",string"`
-}
-
-// Samples represents a slice of samples. It implements sort.Interface.
-type Samples []Sample
-
-func (a Samples) Len() int           { return len(a) }
-func (a Samples) Less(i, j int) bool { return a[i].Value < a[j].Value }
-func (a Samples) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
-
-type invariant func(s *stream, r float64) float64
-
-// NewLowBiased returns an initialized Stream for low-biased quantiles
-// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but
-// error guarantees can still be given even for the lower ranks of the data
-// distribution.
-//
-// The provided epsilon is a relative error, i.e. the true quantile of a value
-// returned by a query is guaranteed to be within (1±Epsilon)*Quantile.
-//
-// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error
-// properties.
-func NewLowBiased(epsilon float64) *Stream {
-	ƒ := func(s *stream, r float64) float64 {
-		return 2 * epsilon * r
-	}
-	return newStream(ƒ)
-}
-
-// NewHighBiased returns an initialized Stream for high-biased quantiles
-// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but
-// error guarantees can still be given even for the higher ranks of the data
-// distribution.
-//
-// The provided epsilon is a relative error, i.e. the true quantile of a value
-// returned by a query is guaranteed to be within 1-(1±Epsilon)*(1-Quantile).
-//
-// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error
-// properties.
-func NewHighBiased(epsilon float64) *Stream {
-	ƒ := func(s *stream, r float64) float64 {
-		return 2 * epsilon * (s.n - r)
-	}
-	return newStream(ƒ)
-}
-
-// NewTargeted returns an initialized Stream concerned with a particular set of
-// quantile values that are supplied a priori. Knowing these a priori reduces
-// space and computation time. The targets map maps the desired quantiles to
-// their absolute errors, i.e. the true quantile of a value returned by a query
-// is guaranteed to be within (Quantile±Epsilon).
-//
-// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties.
-func NewTargeted(targetMap map[float64]float64) *Stream {
-	// Convert map to slice to avoid slow iterations on a map.
-	// ƒ is called on the hot path, so converting the map to a slice
-	// beforehand results in significant CPU savings.
-	targets := targetMapToSlice(targetMap)
-
-	ƒ := func(s *stream, r float64) float64 {
-		var m = math.MaxFloat64
-		var f float64
-		for _, t := range targets {
-			if t.quantile*s.n <= r {
-				f = (2 * t.epsilon * r) / t.quantile
-			} else {
-				f = (2 * t.epsilon * (s.n - r)) / (1 - t.quantile)
-			}
-			if f < m {
-				m = f
-			}
-		}
-		return m
-	}
-	return newStream(ƒ)
-}
-
-type target struct {
-	quantile float64
-	epsilon  float64
-}
-
-func targetMapToSlice(targetMap map[float64]float64) []target {
-	targets := make([]target, 0, len(targetMap))
-
-	for quantile, epsilon := range targetMap {
-		t := target{
-			quantile: quantile,
-			epsilon:  epsilon,
-		}
-		targets = append(targets, t)
-	}
-
-	return targets
-}
-
-// Stream computes quantiles for a stream of float64s. It is not thread-safe by
-// design. Take care when using across multiple goroutines.
-type Stream struct {
-	*stream
-	b      Samples
-	sorted bool
-}
-
-func newStream(ƒ invariant) *Stream {
-	x := &stream{ƒ: ƒ}
-	return &Stream{x, make(Samples, 0, 500), true}
-}
-
-// Insert inserts v into the stream.
-func (s *Stream) Insert(v float64) {
-	s.insert(Sample{Value: v, Width: 1})
-}
-
-func (s *Stream) insert(sample Sample) {
-	s.b = append(s.b, sample)
-	s.sorted = false
-	if len(s.b) == cap(s.b) {
-		s.flush()
-	}
-}
-
-// Query returns the computed qth percentiles value. If s was created with
-// NewTargeted, and q is not in the set of quantiles provided a priori, Query
-// will return an unspecified result.
-func (s *Stream) Query(q float64) float64 {
-	if !s.flushed() {
-		// Fast path when there hasn't been enough data for a flush;
-		// this also yields better accuracy for small sets of data.
-		l := len(s.b)
-		if l == 0 {
-			return 0
-		}
-		i := int(math.Ceil(float64(l) * q))
-		if i > 0 {
-			i -= 1
-		}
-		s.maybeSort()
-		return s.b[i].Value
-	}
-	s.flush()
-	return s.stream.query(q)
-}
-
-// Merge merges samples into the underlying streams samples. This is handy when
-// merging multiple streams from separate threads, database shards, etc.
-//
-// ATTENTION: This method is broken and does not yield correct results. The
-// underlying algorithm is not capable of merging streams correctly.
-func (s *Stream) Merge(samples Samples) {
-	sort.Sort(samples)
-	s.stream.merge(samples)
-}
-
-// Reset reinitializes and clears the list reusing the samples buffer memory.
-func (s *Stream) Reset() {
-	s.stream.reset()
-	s.b = s.b[:0]
-}
-
-// Samples returns stream samples held by s.
-func (s *Stream) Samples() Samples {
-	if !s.flushed() {
-		return s.b
-	}
-	s.flush()
-	return s.stream.samples()
-}
-
-// Count returns the total number of samples observed in the stream
-// since initialization.
-func (s *Stream) Count() int {
-	return len(s.b) + s.stream.count()
-}
-
-func (s *Stream) flush() {
-	s.maybeSort()
-	s.stream.merge(s.b)
-	s.b = s.b[:0]
-}
-
-func (s *Stream) maybeSort() {
-	if !s.sorted {
-		s.sorted = true
-		sort.Sort(s.b)
-	}
-}
-
-func (s *Stream) flushed() bool {
-	return len(s.stream.l) > 0
-}
-
-type stream struct {
-	n float64
-	l []Sample
-	ƒ invariant
-}
-
-func (s *stream) reset() {
-	s.l = s.l[:0]
-	s.n = 0
-}
-
-func (s *stream) insert(v float64) {
-	s.merge(Samples{{v, 1, 0}})
-}
-
-func (s *stream) merge(samples Samples) {
-	// TODO(beorn7): This tries to merge not only individual samples, but
-	// whole summaries. The paper doesn't mention merging summaries at
-	// all. Unittests show that the merging is inaccurate. Find out how to
-	// do merges properly.
-	var r float64
-	i := 0
-	for _, sample := range samples {
-		for ; i < len(s.l); i++ {
-			c := s.l[i]
-			if c.Value > sample.Value {
-				// Insert at position i.
-				s.l = append(s.l, Sample{})
-				copy(s.l[i+1:], s.l[i:])
-				s.l[i] = Sample{
-					sample.Value,
-					sample.Width,
-					math.Max(sample.Delta, math.Floor(s.ƒ(s, r))-1),
-					// TODO(beorn7): How to calculate delta correctly?
-				}
-				i++
-				goto inserted
-			}
-			r += c.Width
-		}
-		s.l = append(s.l, Sample{sample.Value, sample.Width, 0})
-		i++
-	inserted:
-		s.n += sample.Width
-		r += sample.Width
-	}
-	s.compress()
-}
-
-func (s *stream) count() int {
-	return int(s.n)
-}
-
-func (s *stream) query(q float64) float64 {
-	t := math.Ceil(q * s.n)
-	t += math.Ceil(s.ƒ(s, t) / 2)
-	p := s.l[0]
-	var r float64
-	for _, c := range s.l[1:] {
-		r += p.Width
-		if r+c.Width+c.Delta > t {
-			return p.Value
-		}
-		p = c
-	}
-	return p.Value
-}
-
-func (s *stream) compress() {
-	if len(s.l) < 2 {
-		return
-	}
-	x := s.l[len(s.l)-1]
-	xi := len(s.l) - 1
-	r := s.n - 1 - x.Width
-
-	for i := len(s.l) - 2; i >= 0; i-- {
-		c := s.l[i]
-		if c.Width+x.Width+x.Delta <= s.ƒ(s, r) {
-			x.Width += c.Width
-			s.l[xi] = x
-			// Remove element at i.
-			copy(s.l[i:], s.l[i+1:])
-			s.l = s.l[:len(s.l)-1]
-			xi -= 1
-		} else {
-			x = c
-			xi = i
-		}
-		r -= c.Width
-	}
-}
-
-func (s *stream) samples() Samples {
-	samples := make(Samples, len(s.l))
-	copy(samples, s.l)
-	return samples
-}
diff --git a/vendor/github.com/coreos/bbolt/.gitignore b/vendor/github.com/coreos/bbolt/.gitignore
deleted file mode 100644
index c7bd2b7..0000000
--- a/vendor/github.com/coreos/bbolt/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-*.prof
-*.test
-*.swp
-/bin/
diff --git a/vendor/github.com/coreos/bbolt/LICENSE b/vendor/github.com/coreos/bbolt/LICENSE
deleted file mode 100644
index 004e77f..0000000
--- a/vendor/github.com/coreos/bbolt/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 Ben Johnson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/coreos/bbolt/Makefile b/vendor/github.com/coreos/bbolt/Makefile
deleted file mode 100644
index e035e63..0000000
--- a/vendor/github.com/coreos/bbolt/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-BRANCH=`git rev-parse --abbrev-ref HEAD`
-COMMIT=`git rev-parse --short HEAD`
-GOLDFLAGS="-X main.branch $(BRANCH) -X main.commit $(COMMIT)"
-
-default: build
-
-race:
-	@go test -v -race -test.run="TestSimulate_(100op|1000op)"
-
-# go get github.com/kisielk/errcheck
-errcheck:
-	@errcheck -ignorepkg=bytes -ignore=os:Remove github.com/boltdb/bolt
-
-test: 
-	@go test -v -cover .
-	@go test -v ./cmd/bolt
-
-.PHONY: fmt test
diff --git a/vendor/github.com/coreos/bbolt/README.md b/vendor/github.com/coreos/bbolt/README.md
deleted file mode 100644
index 8523e33..0000000
--- a/vendor/github.com/coreos/bbolt/README.md
+++ /dev/null
@@ -1,852 +0,0 @@
-Bolt [![Coverage Status](https://coveralls.io/repos/boltdb/bolt/badge.svg?branch=master)](https://coveralls.io/r/boltdb/bolt?branch=master) [![GoDoc](https://godoc.org/github.com/boltdb/bolt?status.svg)](https://godoc.org/github.com/boltdb/bolt) ![Version](https://img.shields.io/badge/version-1.2.1-green.svg)
-====
-
-Bolt is a pure Go key/value store inspired by [Howard Chu's][hyc_symas]
-[LMDB project][lmdb]. The goal of the project is to provide a simple,
-fast, and reliable database for projects that don't require a full database
-server such as Postgres or MySQL.
-
-Since Bolt is meant to be used as such a low-level piece of functionality,
-simplicity is key. The API will be small and only focus on getting values
-and setting values. That's it.
-
-[hyc_symas]: https://twitter.com/hyc_symas
-[lmdb]: http://symas.com/mdb/
-
-## Project Status
-
-Bolt is stable and the API is fixed. Full unit test coverage and randomized
-black box testing are used to ensure database consistency and thread safety.
-Bolt is currently in high-load production environments serving databases as
-large as 1TB. Many companies such as Shopify and Heroku use Bolt-backed
-services every day.
-
-## Table of Contents
-
-- [Getting Started](#getting-started)
-  - [Installing](#installing)
-  - [Opening a database](#opening-a-database)
-  - [Transactions](#transactions)
-    - [Read-write transactions](#read-write-transactions)
-    - [Read-only transactions](#read-only-transactions)
-    - [Batch read-write transactions](#batch-read-write-transactions)
-    - [Managing transactions manually](#managing-transactions-manually)
-  - [Using buckets](#using-buckets)
-  - [Using key/value pairs](#using-keyvalue-pairs)
-  - [Autoincrementing integer for the bucket](#autoincrementing-integer-for-the-bucket)
-  - [Iterating over keys](#iterating-over-keys)
-    - [Prefix scans](#prefix-scans)
-    - [Range scans](#range-scans)
-    - [ForEach()](#foreach)
-  - [Nested buckets](#nested-buckets)
-  - [Database backups](#database-backups)
-  - [Statistics](#statistics)
-  - [Read-Only Mode](#read-only-mode)
-  - [Mobile Use (iOS/Android)](#mobile-use-iosandroid)
-- [Resources](#resources)
-- [Comparison with other databases](#comparison-with-other-databases)
-  - [Postgres, MySQL, & other relational databases](#postgres-mysql--other-relational-databases)
-  - [LevelDB, RocksDB](#leveldb-rocksdb)
-  - [LMDB](#lmdb)
-- [Caveats & Limitations](#caveats--limitations)
-- [Reading the Source](#reading-the-source)
-- [Other Projects Using Bolt](#other-projects-using-bolt)
-
-## Getting Started
-
-### Installing
-
-To start using Bolt, install Go and run `go get`:
-
-```sh
-$ go get github.com/boltdb/bolt/...
-```
-
-This will retrieve the library and install the `bolt` command line utility into
-your `$GOBIN` path.
-
-
-### Opening a database
-
-The top-level object in Bolt is a `DB`. It is represented as a single file on
-your disk and represents a consistent snapshot of your data.
-
-To open your database, simply use the `bolt.Open()` function:
-
-```go
-package main
-
-import (
-	"log"
-
-	"github.com/boltdb/bolt"
-)
-
-func main() {
-	// Open the my.db data file in your current directory.
-	// It will be created if it doesn't exist.
-	db, err := bolt.Open("my.db", 0600, nil)
-	if err != nil {
-		log.Fatal(err)
-	}
-	defer db.Close()
-
-	...
-}
-```
-
-Please note that Bolt obtains a file lock on the data file so multiple processes
-cannot open the same database at the same time. Opening an already open Bolt
-database will cause it to hang until the other process closes it. To prevent
-an indefinite wait you can pass a timeout option to the `Open()` function:
-
-```go
-db, err := bolt.Open("my.db", 0600, &bolt.Options{Timeout: 1 * time.Second})
-```
-
-
-### Transactions
-
-Bolt allows only one read-write transaction at a time but allows as many
-read-only transactions as you want at a time. Each transaction has a consistent
-view of the data as it existed when the transaction started.
-
-Individual transactions and all objects created from them (e.g. buckets, keys)
-are not thread safe. To work with data in multiple goroutines you must start
-a transaction for each one or use locking to ensure only one goroutine accesses
-a transaction at a time. Creating transaction from the `DB` is thread safe.
-
-Read-only transactions and read-write transactions should not depend on one
-another and generally shouldn't be opened simultaneously in the same goroutine.
-This can cause a deadlock as the read-write transaction needs to periodically
-re-map the data file but it cannot do so while a read-only transaction is open.
-
-
-#### Read-write transactions
-
-To start a read-write transaction, you can use the `DB.Update()` function:
-
-```go
-err := db.Update(func(tx *bolt.Tx) error {
-	...
-	return nil
-})
-```
-
-Inside the closure, you have a consistent view of the database. You commit the
-transaction by returning `nil` at the end. You can also rollback the transaction
-at any point by returning an error. All database operations are allowed inside
-a read-write transaction.
-
-Always check the return error as it will report any disk failures that can cause
-your transaction to not complete. If you return an error within your closure
-it will be passed through.
-
-
-#### Read-only transactions
-
-To start a read-only transaction, you can use the `DB.View()` function:
-
-```go
-err := db.View(func(tx *bolt.Tx) error {
-	...
-	return nil
-})
-```
-
-You also get a consistent view of the database within this closure, however,
-no mutating operations are allowed within a read-only transaction. You can only
-retrieve buckets, retrieve values, and copy the database within a read-only
-transaction.
-
-
-#### Batch read-write transactions
-
-Each `DB.Update()` waits for disk to commit the writes. This overhead
-can be minimized by combining multiple updates with the `DB.Batch()`
-function:
-
-```go
-err := db.Batch(func(tx *bolt.Tx) error {
-	...
-	return nil
-})
-```
-
-Concurrent Batch calls are opportunistically combined into larger
-transactions. Batch is only useful when there are multiple goroutines
-calling it.
-
-The trade-off is that `Batch` can call the given
-function multiple times, if parts of the transaction fail. The
-function must be idempotent and side effects must take effect only
-after a successful return from `DB.Batch()`.
-
-For example: don't display messages from inside the function, instead
-set variables in the enclosing scope:
-
-```go
-var id uint64
-err := db.Batch(func(tx *bolt.Tx) error {
-	// Find last key in bucket, decode as bigendian uint64, increment
-	// by one, encode back to []byte, and add new key.
-	...
-	id = newValue
-	return nil
-})
-if err != nil {
-	return ...
-}
-fmt.Println("Allocated ID %d", id)
-```
-
-
-#### Managing transactions manually
-
-The `DB.View()` and `DB.Update()` functions are wrappers around the `DB.Begin()`
-function. These helper functions will start the transaction, execute a function,
-and then safely close your transaction if an error is returned. This is the
-recommended way to use Bolt transactions.
-
-However, sometimes you may want to manually start and end your transactions.
-You can use the `Tx.Begin()` function directly but **please** be sure to close
-the transaction.
-
-```go
-// Start a writable transaction.
-tx, err := db.Begin(true)
-if err != nil {
-    return err
-}
-defer tx.Rollback()
-
-// Use the transaction...
-_, err := tx.CreateBucket([]byte("MyBucket"))
-if err != nil {
-    return err
-}
-
-// Commit the transaction and check for error.
-if err := tx.Commit(); err != nil {
-    return err
-}
-```
-
-The first argument to `DB.Begin()` is a boolean stating if the transaction
-should be writable.
-
-
-### Using buckets
-
-Buckets are collections of key/value pairs within the database. All keys in a
-bucket must be unique. You can create a bucket using the `DB.CreateBucket()`
-function:
-
-```go
-db.Update(func(tx *bolt.Tx) error {
-	b, err := tx.CreateBucket([]byte("MyBucket"))
-	if err != nil {
-		return fmt.Errorf("create bucket: %s", err)
-	}
-	return nil
-})
-```
-
-You can also create a bucket only if it doesn't exist by using the
-`Tx.CreateBucketIfNotExists()` function. It's a common pattern to call this
-function for all your top-level buckets after you open your database so you can
-guarantee that they exist for future transactions.
-
-To delete a bucket, simply call the `Tx.DeleteBucket()` function.
-
-
-### Using key/value pairs
-
-To save a key/value pair to a bucket, use the `Bucket.Put()` function:
-
-```go
-db.Update(func(tx *bolt.Tx) error {
-	b := tx.Bucket([]byte("MyBucket"))
-	err := b.Put([]byte("answer"), []byte("42"))
-	return err
-})
-```
-
-This will set the value of the `"answer"` key to `"42"` in the `MyBucket`
-bucket. To retrieve this value, we can use the `Bucket.Get()` function:
-
-```go
-db.View(func(tx *bolt.Tx) error {
-	b := tx.Bucket([]byte("MyBucket"))
-	v := b.Get([]byte("answer"))
-	fmt.Printf("The answer is: %s\n", v)
-	return nil
-})
-```
-
-The `Get()` function does not return an error because its operation is
-guaranteed to work (unless there is some kind of system failure). If the key
-exists then it will return its byte slice value. If it doesn't exist then it
-will return `nil`. It's important to note that you can have a zero-length value
-set to a key which is different than the key not existing.
-
-Use the `Bucket.Delete()` function to delete a key from the bucket.
-
-Please note that values returned from `Get()` are only valid while the
-transaction is open. If you need to use a value outside of the transaction
-then you must use `copy()` to copy it to another byte slice.
-
-
-### Autoincrementing integer for the bucket
-By using the `NextSequence()` function, you can let Bolt determine a sequence
-which can be used as the unique identifier for your key/value pairs. See the
-example below.
-
-```go
-// CreateUser saves u to the store. The new user ID is set on u once the data is persisted.
-func (s *Store) CreateUser(u *User) error {
-    return s.db.Update(func(tx *bolt.Tx) error {
-        // Retrieve the users bucket.
-        // This should be created when the DB is first opened.
-        b := tx.Bucket([]byte("users"))
-
-        // Generate ID for the user.
-        // This returns an error only if the Tx is closed or not writeable.
-        // That can't happen in an Update() call so I ignore the error check.
-        id, _ := b.NextSequence()
-        u.ID = int(id)
-
-        // Marshal user data into bytes.
-        buf, err := json.Marshal(u)
-        if err != nil {
-            return err
-        }
-
-        // Persist bytes to users bucket.
-        return b.Put(itob(u.ID), buf)
-    })
-}
-
-// itob returns an 8-byte big endian representation of v.
-func itob(v int) []byte {
-    b := make([]byte, 8)
-    binary.BigEndian.PutUint64(b, uint64(v))
-    return b
-}
-
-type User struct {
-    ID int
-    ...
-}
-```
-
-### Iterating over keys
-
-Bolt stores its keys in byte-sorted order within a bucket. This makes sequential
-iteration over these keys extremely fast. To iterate over keys we'll use a
-`Cursor`:
-
-```go
-db.View(func(tx *bolt.Tx) error {
-	// Assume bucket exists and has keys
-	b := tx.Bucket([]byte("MyBucket"))
-
-	c := b.Cursor()
-
-	for k, v := c.First(); k != nil; k, v = c.Next() {
-		fmt.Printf("key=%s, value=%s\n", k, v)
-	}
-
-	return nil
-})
-```
-
-The cursor allows you to move to a specific point in the list of keys and move
-forward or backward through the keys one at a time.
-
-The following functions are available on the cursor:
-
-```
-First()  Move to the first key.
-Last()   Move to the last key.
-Seek()   Move to a specific key.
-Next()   Move to the next key.
-Prev()   Move to the previous key.
-```
-
-Each of those functions has a return signature of `(key []byte, value []byte)`.
-When you have iterated to the end of the cursor then `Next()` will return a
-`nil` key.  You must seek to a position using `First()`, `Last()`, or `Seek()`
-before calling `Next()` or `Prev()`. If you do not seek to a position then
-these functions will return a `nil` key.
-
-During iteration, if the key is non-`nil` but the value is `nil`, that means
-the key refers to a bucket rather than a value.  Use `Bucket.Bucket()` to
-access the sub-bucket.
-
-
-#### Prefix scans
-
-To iterate over a key prefix, you can combine `Seek()` and `bytes.HasPrefix()`:
-
-```go
-db.View(func(tx *bolt.Tx) error {
-	// Assume bucket exists and has keys
-	c := tx.Bucket([]byte("MyBucket")).Cursor()
-
-	prefix := []byte("1234")
-	for k, v := c.Seek(prefix); bytes.HasPrefix(k, prefix); k, v = c.Next() {
-		fmt.Printf("key=%s, value=%s\n", k, v)
-	}
-
-	return nil
-})
-```
-
-#### Range scans
-
-Another common use case is scanning over a range such as a time range. If you
-use a sortable time encoding such as RFC3339 then you can query a specific
-date range like this:
-
-```go
-db.View(func(tx *bolt.Tx) error {
-	// Assume our events bucket exists and has RFC3339 encoded time keys.
-	c := tx.Bucket([]byte("Events")).Cursor()
-
-	// Our time range spans the 90's decade.
-	min := []byte("1990-01-01T00:00:00Z")
-	max := []byte("2000-01-01T00:00:00Z")
-
-	// Iterate over the 90's.
-	for k, v := c.Seek(min); k != nil && bytes.Compare(k, max) <= 0; k, v = c.Next() {
-		fmt.Printf("%s: %s\n", k, v)
-	}
-
-	return nil
-})
-```
-
-Note that, while RFC3339 is sortable, the Golang implementation of RFC3339Nano does not use a fixed number of digits after the decimal point and is therefore not sortable.
-
-
-#### ForEach()
-
-You can also use the function `ForEach()` if you know you'll be iterating over
-all the keys in a bucket:
-
-```go
-db.View(func(tx *bolt.Tx) error {
-	// Assume bucket exists and has keys
-	b := tx.Bucket([]byte("MyBucket"))
-
-	b.ForEach(func(k, v []byte) error {
-		fmt.Printf("key=%s, value=%s\n", k, v)
-		return nil
-	})
-	return nil
-})
-```
-
-
-### Nested buckets
-
-You can also store a bucket in a key to create nested buckets. The API is the
-same as the bucket management API on the `DB` object:
-
-```go
-func (*Bucket) CreateBucket(key []byte) (*Bucket, error)
-func (*Bucket) CreateBucketIfNotExists(key []byte) (*Bucket, error)
-func (*Bucket) DeleteBucket(key []byte) error
-```
-
-
-### Database backups
-
-Bolt is a single file so it's easy to backup. You can use the `Tx.WriteTo()`
-function to write a consistent view of the database to a writer. If you call
-this from a read-only transaction, it will perform a hot backup and not block
-your other database reads and writes.
-
-By default, it will use a regular file handle which will utilize the operating
-system's page cache. See the [`Tx`](https://godoc.org/github.com/boltdb/bolt#Tx)
-documentation for information about optimizing for larger-than-RAM datasets.
-
-One common use case is to backup over HTTP so you can use tools like `cURL` to
-do database backups:
-
-```go
-func BackupHandleFunc(w http.ResponseWriter, req *http.Request) {
-	err := db.View(func(tx *bolt.Tx) error {
-		w.Header().Set("Content-Type", "application/octet-stream")
-		w.Header().Set("Content-Disposition", `attachment; filename="my.db"`)
-		w.Header().Set("Content-Length", strconv.Itoa(int(tx.Size())))
-		_, err := tx.WriteTo(w)
-		return err
-	})
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-	}
-}
-```
-
-Then you can backup using this command:
-
-```sh
-$ curl http://localhost/backup > my.db
-```
-
-Or you can open your browser to `http://localhost/backup` and it will download
-automatically.
-
-If you want to backup to another file you can use the `Tx.CopyFile()` helper
-function.
-
-
-### Statistics
-
-The database keeps a running count of many of the internal operations it
-performs so you can better understand what's going on. By grabbing a snapshot
-of these stats at two points in time we can see what operations were performed
-in that time range.
-
-For example, we could start a goroutine to log stats every 10 seconds:
-
-```go
-go func() {
-	// Grab the initial stats.
-	prev := db.Stats()
-
-	for {
-		// Wait for 10s.
-		time.Sleep(10 * time.Second)
-
-		// Grab the current stats and diff them.
-		stats := db.Stats()
-		diff := stats.Sub(&prev)
-
-		// Encode stats to JSON and print to STDERR.
-		json.NewEncoder(os.Stderr).Encode(diff)
-
-		// Save stats for the next loop.
-		prev = stats
-	}
-}()
-```
-
-It's also useful to pipe these stats to a service such as statsd for monitoring
-or to provide an HTTP endpoint that will perform a fixed-length sample.
-
-
-### Read-Only Mode
-
-Sometimes it is useful to create a shared, read-only Bolt database. To this,
-set the `Options.ReadOnly` flag when opening your database. Read-only mode
-uses a shared lock to allow multiple processes to read from the database but
-it will block any processes from opening the database in read-write mode.
-
-```go
-db, err := bolt.Open("my.db", 0666, &bolt.Options{ReadOnly: true})
-if err != nil {
-	log.Fatal(err)
-}
-```
-
-### Mobile Use (iOS/Android)
-
-Bolt is able to run on mobile devices by leveraging the binding feature of the
-[gomobile](https://github.com/golang/mobile) tool. Create a struct that will
-contain your database logic and a reference to a `*bolt.DB` with a initializing
-constructor that takes in a filepath where the database file will be stored.
-Neither Android nor iOS require extra permissions or cleanup from using this method.
-
-```go
-func NewBoltDB(filepath string) *BoltDB {
-	db, err := bolt.Open(filepath+"/demo.db", 0600, nil)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	return &BoltDB{db}
-}
-
-type BoltDB struct {
-	db *bolt.DB
-	...
-}
-
-func (b *BoltDB) Path() string {
-	return b.db.Path()
-}
-
-func (b *BoltDB) Close() {
-	b.db.Close()
-}
-```
-
-Database logic should be defined as methods on this wrapper struct.
-
-To initialize this struct from the native language (both platforms now sync
-their local storage to the cloud. These snippets disable that functionality for the
-database file):
-
-#### Android
-
-```java
-String path;
-if (android.os.Build.VERSION.SDK_INT >=android.os.Build.VERSION_CODES.LOLLIPOP){
-    path = getNoBackupFilesDir().getAbsolutePath();
-} else{
-    path = getFilesDir().getAbsolutePath();
-}
-Boltmobiledemo.BoltDB boltDB = Boltmobiledemo.NewBoltDB(path)
-```
-
-#### iOS
-
-```objc
-- (void)demo {
-    NSString* path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
-                                                          NSUserDomainMask,
-                                                          YES) objectAtIndex:0];
-	GoBoltmobiledemoBoltDB * demo = GoBoltmobiledemoNewBoltDB(path);
-	[self addSkipBackupAttributeToItemAtPath:demo.path];
-	//Some DB Logic would go here
-	[demo close];
-}
-
-- (BOOL)addSkipBackupAttributeToItemAtPath:(NSString *) filePathString
-{
-    NSURL* URL= [NSURL fileURLWithPath: filePathString];
-    assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);
-
-    NSError *error = nil;
-    BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
-                                  forKey: NSURLIsExcludedFromBackupKey error: &error];
-    if(!success){
-        NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error);
-    }
-    return success;
-}
-
-```
-
-## Resources
-
-For more information on getting started with Bolt, check out the following articles:
-
-* [Intro to BoltDB: Painless Performant Persistence](http://npf.io/2014/07/intro-to-boltdb-painless-performant-persistence/) by [Nate Finch](https://github.com/natefinch).
-* [Bolt -- an embedded key/value database for Go](https://www.progville.com/go/bolt-embedded-db-golang/) by Progville
-
-
-## Comparison with other databases
-
-### Postgres, MySQL, & other relational databases
-
-Relational databases structure data into rows and are only accessible through
-the use of SQL. This approach provides flexibility in how you store and query
-your data but also incurs overhead in parsing and planning SQL statements. Bolt
-accesses all data by a byte slice key. This makes Bolt fast to read and write
-data by key but provides no built-in support for joining values together.
-
-Most relational databases (with the exception of SQLite) are standalone servers
-that run separately from your application. This gives your systems
-flexibility to connect multiple application servers to a single database
-server but also adds overhead in serializing and transporting data over the
-network. Bolt runs as a library included in your application so all data access
-has to go through your application's process. This brings data closer to your
-application but limits multi-process access to the data.
-
-
-### LevelDB, RocksDB
-
-LevelDB and its derivatives (RocksDB, HyperLevelDB) are similar to Bolt in that
-they are libraries bundled into the application, however, their underlying
-structure is a log-structured merge-tree (LSM tree). An LSM tree optimizes
-random writes by using a write ahead log and multi-tiered, sorted files called
-SSTables. Bolt uses a B+tree internally and only a single file. Both approaches
-have trade-offs.
-
-If you require a high random write throughput (>10,000 w/sec) or you need to use
-spinning disks then LevelDB could be a good choice. If your application is
-read-heavy or does a lot of range scans then Bolt could be a good choice.
-
-One other important consideration is that LevelDB does not have transactions.
-It supports batch writing of key/values pairs and it supports read snapshots
-but it will not give you the ability to do a compare-and-swap operation safely.
-Bolt supports fully serializable ACID transactions.
-
-
-### LMDB
-
-Bolt was originally a port of LMDB so it is architecturally similar. Both use
-a B+tree, have ACID semantics with fully serializable transactions, and support
-lock-free MVCC using a single writer and multiple readers.
-
-The two projects have somewhat diverged. LMDB heavily focuses on raw performance
-while Bolt has focused on simplicity and ease of use. For example, LMDB allows
-several unsafe actions such as direct writes for the sake of performance. Bolt
-opts to disallow actions which can leave the database in a corrupted state. The
-only exception to this in Bolt is `DB.NoSync`.
-
-There are also a few differences in API. LMDB requires a maximum mmap size when
-opening an `mdb_env` whereas Bolt will handle incremental mmap resizing
-automatically. LMDB overloads the getter and setter functions with multiple
-flags whereas Bolt splits these specialized cases into their own functions.
-
-
-## Caveats & Limitations
-
-It's important to pick the right tool for the job and Bolt is no exception.
-Here are a few things to note when evaluating and using Bolt:
-
-* Bolt is good for read intensive workloads. Sequential write performance is
-  also fast but random writes can be slow. You can use `DB.Batch()` or add a
-  write-ahead log to help mitigate this issue.
-
-* Bolt uses a B+tree internally so there can be a lot of random page access.
-  SSDs provide a significant performance boost over spinning disks.
-
-* Try to avoid long running read transactions. Bolt uses copy-on-write so
-  old pages cannot be reclaimed while an old transaction is using them.
-
-* Byte slices returned from Bolt are only valid during a transaction. Once the
-  transaction has been committed or rolled back then the memory they point to
-  can be reused by a new page or can be unmapped from virtual memory and you'll
-  see an `unexpected fault address` panic when accessing it.
-
-* Be careful when using `Bucket.FillPercent`. Setting a high fill percent for
-  buckets that have random inserts will cause your database to have very poor
-  page utilization.
-
-* Use larger buckets in general. Smaller buckets causes poor page utilization
-  once they become larger than the page size (typically 4KB).
-
-* Bulk loading a lot of random writes into a new bucket can be slow as the
-  page will not split until the transaction is committed. Randomly inserting
-  more than 100,000 key/value pairs into a single new bucket in a single
-  transaction is not advised.
-
-* Bolt uses a memory-mapped file so the underlying operating system handles the
-  caching of the data. Typically, the OS will cache as much of the file as it
-  can in memory and will release memory as needed to other processes. This means
-  that Bolt can show very high memory usage when working with large databases.
-  However, this is expected and the OS will release memory as needed. Bolt can
-  handle databases much larger than the available physical RAM, provided its
-  memory-map fits in the process virtual address space. It may be problematic
-  on 32-bits systems.
-
-* The data structures in the Bolt database are memory mapped so the data file
-  will be endian specific. This means that you cannot copy a Bolt file from a
-  little endian machine to a big endian machine and have it work. For most
-  users this is not a concern since most modern CPUs are little endian.
-
-* Because of the way pages are laid out on disk, Bolt cannot truncate data files
-  and return free pages back to the disk. Instead, Bolt maintains a free list
-  of unused pages within its data file. These free pages can be reused by later
-  transactions. This works well for many use cases as databases generally tend
-  to grow. However, it's important to note that deleting large chunks of data
-  will not allow you to reclaim that space on disk.
-
-  For more information on page allocation, [see this comment][page-allocation].
-
-[page-allocation]: https://github.com/boltdb/bolt/issues/308#issuecomment-74811638
-
-
-## Reading the Source
-
-Bolt is a relatively small code base (<3KLOC) for an embedded, serializable,
-transactional key/value database so it can be a good starting point for people
-interested in how databases work.
-
-The best places to start are the main entry points into Bolt:
-
-- `Open()` - Initializes the reference to the database. It's responsible for
-  creating the database if it doesn't exist, obtaining an exclusive lock on the
-  file, reading the meta pages, & memory-mapping the file.
-
-- `DB.Begin()` - Starts a read-only or read-write transaction depending on the
-  value of the `writable` argument. This requires briefly obtaining the "meta"
-  lock to keep track of open transactions. Only one read-write transaction can
-  exist at a time so the "rwlock" is acquired during the life of a read-write
-  transaction.
-
-- `Bucket.Put()` - Writes a key/value pair into a bucket. After validating the
-  arguments, a cursor is used to traverse the B+tree to the page and position
-  where they key & value will be written. Once the position is found, the bucket
-  materializes the underlying page and the page's parent pages into memory as
-  "nodes". These nodes are where mutations occur during read-write transactions.
-  These changes get flushed to disk during commit.
-
-- `Bucket.Get()` - Retrieves a key/value pair from a bucket. This uses a cursor
-  to move to the page & position of a key/value pair. During a read-only
-  transaction, the key and value data is returned as a direct reference to the
-  underlying mmap file so there's no allocation overhead. For read-write
-  transactions, this data may reference the mmap file or one of the in-memory
-  node values.
-
-- `Cursor` - This object is simply for traversing the B+tree of on-disk pages
-  or in-memory nodes. It can seek to a specific key, move to the first or last
-  value, or it can move forward or backward. The cursor handles the movement up
-  and down the B+tree transparently to the end user.
-
-- `Tx.Commit()` - Converts the in-memory dirty nodes and the list of free pages
-  into pages to be written to disk. Writing to disk then occurs in two phases.
-  First, the dirty pages are written to disk and an `fsync()` occurs. Second, a
-  new meta page with an incremented transaction ID is written and another
-  `fsync()` occurs. This two phase write ensures that partially written data
-  pages are ignored in the event of a crash since the meta page pointing to them
-  is never written. Partially written meta pages are invalidated because they
-  are written with a checksum.
-
-If you have additional notes that could be helpful for others, please submit
-them via pull request.
-
-
-## Other Projects Using Bolt
-
-Below is a list of public, open source projects that use Bolt:
-
-* [BoltDbWeb](https://github.com/evnix/boltdbweb) - A web based GUI for BoltDB files.
-* [Operation Go: A Routine Mission](http://gocode.io) - An online programming game for Golang using Bolt for user accounts and a leaderboard.
-* [Bazil](https://bazil.org/) - A file system that lets your data reside where it is most convenient for it to reside.
-* [DVID](https://github.com/janelia-flyem/dvid) - Added Bolt as optional storage engine and testing it against Basho-tuned leveldb.
-* [Skybox Analytics](https://github.com/skybox/skybox) - A standalone funnel analysis tool for web analytics.
-* [Scuttlebutt](https://github.com/benbjohnson/scuttlebutt) - Uses Bolt to store and process all Twitter mentions of GitHub projects.
-* [Wiki](https://github.com/peterhellberg/wiki) - A tiny wiki using Goji, BoltDB and Blackfriday.
-* [ChainStore](https://github.com/pressly/chainstore) - Simple key-value interface to a variety of storage engines organized as a chain of operations.
-* [MetricBase](https://github.com/msiebuhr/MetricBase) - Single-binary version of Graphite.
-* [Gitchain](https://github.com/gitchain/gitchain) - Decentralized, peer-to-peer Git repositories aka "Git meets Bitcoin".
-* [event-shuttle](https://github.com/sclasen/event-shuttle) - A Unix system service to collect and reliably deliver messages to Kafka.
-* [ipxed](https://github.com/kelseyhightower/ipxed) - Web interface and api for ipxed.
-* [BoltStore](https://github.com/yosssi/boltstore) - Session store using Bolt.
-* [photosite/session](https://godoc.org/bitbucket.org/kardianos/photosite/session) - Sessions for a photo viewing site.
-* [LedisDB](https://github.com/siddontang/ledisdb) - A high performance NoSQL, using Bolt as optional storage.
-* [ipLocator](https://github.com/AndreasBriese/ipLocator) - A fast ip-geo-location-server using bolt with bloom filters.
-* [cayley](https://github.com/google/cayley) - Cayley is an open-source graph database using Bolt as optional backend.
-* [bleve](http://www.blevesearch.com/) - A pure Go search engine similar to ElasticSearch that uses Bolt as the default storage backend.
-* [tentacool](https://github.com/optiflows/tentacool) - REST api server to manage system stuff (IP, DNS, Gateway...) on a linux server.
-* [Seaweed File System](https://github.com/chrislusf/seaweedfs) - Highly scalable distributed key~file system with O(1) disk read.
-* [InfluxDB](https://influxdata.com) - Scalable datastore for metrics, events, and real-time analytics.
-* [Freehold](http://tshannon.bitbucket.org/freehold/) - An open, secure, and lightweight platform for your files and data.
-* [Prometheus Annotation Server](https://github.com/oliver006/prom_annotation_server) - Annotation server for PromDash & Prometheus service monitoring system.
-* [Consul](https://github.com/hashicorp/consul) - Consul is service discovery and configuration made easy. Distributed, highly available, and datacenter-aware.
-* [Kala](https://github.com/ajvb/kala) - Kala is a modern job scheduler optimized to run on a single node. It is persistent, JSON over HTTP API, ISO 8601 duration notation, and dependent jobs.
-* [drive](https://github.com/odeke-em/drive) - drive is an unofficial Google Drive command line client for \*NIX operating systems.
-* [stow](https://github.com/djherbis/stow) -  a persistence manager for objects
-  backed by boltdb.
-* [buckets](https://github.com/joyrexus/buckets) - a bolt wrapper streamlining
-  simple tx and key scans.
-* [mbuckets](https://github.com/abhigupta912/mbuckets) - A Bolt wrapper that allows easy operations on multi level (nested) buckets.
-* [Request Baskets](https://github.com/darklynx/request-baskets) - A web service to collect arbitrary HTTP requests and inspect them via REST API or simple web UI, similar to [RequestBin](http://requestb.in/) service
-* [Go Report Card](https://goreportcard.com/) - Go code quality report cards as a (free and open source) service.
-* [Boltdb Boilerplate](https://github.com/bobintornado/boltdb-boilerplate) - Boilerplate wrapper around bolt aiming to make simple calls one-liners.
-* [lru](https://github.com/crowdriff/lru) - Easy to use Bolt-backed Least-Recently-Used (LRU) read-through cache with chainable remote stores.
-* [Storm](https://github.com/asdine/storm) - Simple and powerful ORM for BoltDB.
-* [GoWebApp](https://github.com/josephspurrier/gowebapp) - A basic MVC web application in Go using BoltDB.
-* [SimpleBolt](https://github.com/xyproto/simplebolt) - A simple way to use BoltDB. Deals mainly with strings.
-* [Algernon](https://github.com/xyproto/algernon) - A HTTP/2 web server with built-in support for Lua. Uses BoltDB as the default database backend.
-* [MuLiFS](https://github.com/dankomiocevic/mulifs) - Music Library Filesystem creates a filesystem to organise your music files.
-* [GoShort](https://github.com/pankajkhairnar/goShort) - GoShort is a URL shortener written in Golang and BoltDB for persistent key/value storage and for routing it's using high performent HTTPRouter.
-
-If you are using Bolt in a project please send a pull request to add it to the list.
diff --git a/vendor/github.com/coreos/bbolt/appveyor.yml b/vendor/github.com/coreos/bbolt/appveyor.yml
deleted file mode 100644
index 6e26e94..0000000
--- a/vendor/github.com/coreos/bbolt/appveyor.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-version: "{build}"
-
-os: Windows Server 2012 R2
-
-clone_folder: c:\gopath\src\github.com\boltdb\bolt
-
-environment:
-  GOPATH: c:\gopath
-
-install:
-  - echo %PATH%
-  - echo %GOPATH%
-  - go version
-  - go env
-  - go get -v -t ./...
-
-build_script:
-  - go test -v ./...
diff --git a/vendor/github.com/coreos/bbolt/bolt_386.go b/vendor/github.com/coreos/bbolt/bolt_386.go
deleted file mode 100644
index e659bfb..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_386.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package bolt
-
-// maxMapSize represents the largest mmap size supported by Bolt.
-const maxMapSize = 0x7FFFFFFF // 2GB
-
-// maxAllocSize is the size used when creating array pointers.
-const maxAllocSize = 0xFFFFFFF
diff --git a/vendor/github.com/coreos/bbolt/bolt_amd64.go b/vendor/github.com/coreos/bbolt/bolt_amd64.go
deleted file mode 100644
index cca6b7e..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_amd64.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package bolt
-
-// maxMapSize represents the largest mmap size supported by Bolt.
-const maxMapSize = 0xFFFFFFFFFFFF // 256TB
-
-// maxAllocSize is the size used when creating array pointers.
-const maxAllocSize = 0x7FFFFFFF
diff --git a/vendor/github.com/coreos/bbolt/bolt_arm.go b/vendor/github.com/coreos/bbolt/bolt_arm.go
deleted file mode 100644
index e659bfb..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_arm.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package bolt
-
-// maxMapSize represents the largest mmap size supported by Bolt.
-const maxMapSize = 0x7FFFFFFF // 2GB
-
-// maxAllocSize is the size used when creating array pointers.
-const maxAllocSize = 0xFFFFFFF
diff --git a/vendor/github.com/coreos/bbolt/bolt_arm64.go b/vendor/github.com/coreos/bbolt/bolt_arm64.go
deleted file mode 100644
index 6d23093..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_arm64.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build arm64
-
-package bolt
-
-// maxMapSize represents the largest mmap size supported by Bolt.
-const maxMapSize = 0xFFFFFFFFFFFF // 256TB
-
-// maxAllocSize is the size used when creating array pointers.
-const maxAllocSize = 0x7FFFFFFF
diff --git a/vendor/github.com/coreos/bbolt/bolt_linux.go b/vendor/github.com/coreos/bbolt/bolt_linux.go
deleted file mode 100644
index 2b67666..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_linux.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package bolt
-
-import (
-	"syscall"
-)
-
-// fdatasync flushes written data to a file descriptor.
-func fdatasync(db *DB) error {
-	return syscall.Fdatasync(int(db.file.Fd()))
-}
diff --git a/vendor/github.com/coreos/bbolt/bolt_openbsd.go b/vendor/github.com/coreos/bbolt/bolt_openbsd.go
deleted file mode 100644
index 7058c3d..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_openbsd.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package bolt
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-const (
-	msAsync      = 1 << iota // perform asynchronous writes
-	msSync                   // perform synchronous writes
-	msInvalidate             // invalidate cached data
-)
-
-func msync(db *DB) error {
-	_, _, errno := syscall.Syscall(syscall.SYS_MSYNC, uintptr(unsafe.Pointer(db.data)), uintptr(db.datasz), msInvalidate)
-	if errno != 0 {
-		return errno
-	}
-	return nil
-}
-
-func fdatasync(db *DB) error {
-	if db.data != nil {
-		return msync(db)
-	}
-	return db.file.Sync()
-}
diff --git a/vendor/github.com/coreos/bbolt/bolt_ppc.go b/vendor/github.com/coreos/bbolt/bolt_ppc.go
deleted file mode 100644
index 645ddc3..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_ppc.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build ppc
-
-package bolt
-
-// maxMapSize represents the largest mmap size supported by Bolt.
-const maxMapSize = 0x7FFFFFFF // 2GB
-
-// maxAllocSize is the size used when creating array pointers.
-const maxAllocSize = 0xFFFFFFF
diff --git a/vendor/github.com/coreos/bbolt/bolt_ppc64.go b/vendor/github.com/coreos/bbolt/bolt_ppc64.go
deleted file mode 100644
index 2dc6be0..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_ppc64.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build ppc64
-
-package bolt
-
-// maxMapSize represents the largest mmap size supported by Bolt.
-const maxMapSize = 0xFFFFFFFFFFFF // 256TB
-
-// maxAllocSize is the size used when creating array pointers.
-const maxAllocSize = 0x7FFFFFFF
diff --git a/vendor/github.com/coreos/bbolt/bolt_ppc64le.go b/vendor/github.com/coreos/bbolt/bolt_ppc64le.go
deleted file mode 100644
index 8351e12..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_ppc64le.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build ppc64le
-
-package bolt
-
-// maxMapSize represents the largest mmap size supported by Bolt.
-const maxMapSize = 0xFFFFFFFFFFFF // 256TB
-
-// maxAllocSize is the size used when creating array pointers.
-const maxAllocSize = 0x7FFFFFFF
diff --git a/vendor/github.com/coreos/bbolt/bolt_s390x.go b/vendor/github.com/coreos/bbolt/bolt_s390x.go
deleted file mode 100644
index f4dd26b..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_s390x.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build s390x
-
-package bolt
-
-// maxMapSize represents the largest mmap size supported by Bolt.
-const maxMapSize = 0xFFFFFFFFFFFF // 256TB
-
-// maxAllocSize is the size used when creating array pointers.
-const maxAllocSize = 0x7FFFFFFF
diff --git a/vendor/github.com/coreos/bbolt/bolt_unix.go b/vendor/github.com/coreos/bbolt/bolt_unix.go
deleted file mode 100644
index cad62dd..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_unix.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// +build !windows,!plan9,!solaris
-
-package bolt
-
-import (
-	"fmt"
-	"os"
-	"syscall"
-	"time"
-	"unsafe"
-)
-
-// flock acquires an advisory lock on a file descriptor.
-func flock(db *DB, mode os.FileMode, exclusive bool, timeout time.Duration) error {
-	var t time.Time
-	for {
-		// If we're beyond our timeout then return an error.
-		// This can only occur after we've attempted a flock once.
-		if t.IsZero() {
-			t = time.Now()
-		} else if timeout > 0 && time.Since(t) > timeout {
-			return ErrTimeout
-		}
-		flag := syscall.LOCK_SH
-		if exclusive {
-			flag = syscall.LOCK_EX
-		}
-
-		// Otherwise attempt to obtain an exclusive lock.
-		err := syscall.Flock(int(db.file.Fd()), flag|syscall.LOCK_NB)
-		if err == nil {
-			return nil
-		} else if err != syscall.EWOULDBLOCK {
-			return err
-		}
-
-		// Wait for a bit and try again.
-		time.Sleep(50 * time.Millisecond)
-	}
-}
-
-// funlock releases an advisory lock on a file descriptor.
-func funlock(db *DB) error {
-	return syscall.Flock(int(db.file.Fd()), syscall.LOCK_UN)
-}
-
-// mmap memory maps a DB's data file.
-func mmap(db *DB, sz int) error {
-	// Map the data file to memory.
-	b, err := syscall.Mmap(int(db.file.Fd()), 0, sz, syscall.PROT_READ, syscall.MAP_SHARED|db.MmapFlags)
-	if err != nil {
-		return err
-	}
-
-	// Advise the kernel that the mmap is accessed randomly.
-	if err := madvise(b, syscall.MADV_RANDOM); err != nil {
-		return fmt.Errorf("madvise: %s", err)
-	}
-
-	// Save the original byte slice and convert to a byte array pointer.
-	db.dataref = b
-	db.data = (*[maxMapSize]byte)(unsafe.Pointer(&b[0]))
-	db.datasz = sz
-	return nil
-}
-
-// munmap unmaps a DB's data file from memory.
-func munmap(db *DB) error {
-	// Ignore the unmap if we have no mapped data.
-	if db.dataref == nil {
-		return nil
-	}
-
-	// Unmap using the original byte slice.
-	err := syscall.Munmap(db.dataref)
-	db.dataref = nil
-	db.data = nil
-	db.datasz = 0
-	return err
-}
-
-// NOTE: This function is copied from stdlib because it is not available on darwin.
-func madvise(b []byte, advice int) (err error) {
-	_, _, e1 := syscall.Syscall(syscall.SYS_MADVISE, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), uintptr(advice))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/vendor/github.com/coreos/bbolt/bolt_unix_solaris.go b/vendor/github.com/coreos/bbolt/bolt_unix_solaris.go
deleted file mode 100644
index 307bf2b..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_unix_solaris.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package bolt
-
-import (
-	"fmt"
-	"os"
-	"syscall"
-	"time"
-	"unsafe"
-
-	"golang.org/x/sys/unix"
-)
-
-// flock acquires an advisory lock on a file descriptor.
-func flock(db *DB, mode os.FileMode, exclusive bool, timeout time.Duration) error {
-	var t time.Time
-	for {
-		// If we're beyond our timeout then return an error.
-		// This can only occur after we've attempted a flock once.
-		if t.IsZero() {
-			t = time.Now()
-		} else if timeout > 0 && time.Since(t) > timeout {
-			return ErrTimeout
-		}
-		var lock syscall.Flock_t
-		lock.Start = 0
-		lock.Len = 0
-		lock.Pid = 0
-		lock.Whence = 0
-		lock.Pid = 0
-		if exclusive {
-			lock.Type = syscall.F_WRLCK
-		} else {
-			lock.Type = syscall.F_RDLCK
-		}
-		err := syscall.FcntlFlock(db.file.Fd(), syscall.F_SETLK, &lock)
-		if err == nil {
-			return nil
-		} else if err != syscall.EAGAIN {
-			return err
-		}
-
-		// Wait for a bit and try again.
-		time.Sleep(50 * time.Millisecond)
-	}
-}
-
-// funlock releases an advisory lock on a file descriptor.
-func funlock(db *DB) error {
-	var lock syscall.Flock_t
-	lock.Start = 0
-	lock.Len = 0
-	lock.Type = syscall.F_UNLCK
-	lock.Whence = 0
-	return syscall.FcntlFlock(uintptr(db.file.Fd()), syscall.F_SETLK, &lock)
-}
-
-// mmap memory maps a DB's data file.
-func mmap(db *DB, sz int) error {
-	// Map the data file to memory.
-	b, err := unix.Mmap(int(db.file.Fd()), 0, sz, syscall.PROT_READ, syscall.MAP_SHARED|db.MmapFlags)
-	if err != nil {
-		return err
-	}
-
-	// Advise the kernel that the mmap is accessed randomly.
-	if err := unix.Madvise(b, syscall.MADV_RANDOM); err != nil {
-		return fmt.Errorf("madvise: %s", err)
-	}
-
-	// Save the original byte slice and convert to a byte array pointer.
-	db.dataref = b
-	db.data = (*[maxMapSize]byte)(unsafe.Pointer(&b[0]))
-	db.datasz = sz
-	return nil
-}
-
-// munmap unmaps a DB's data file from memory.
-func munmap(db *DB) error {
-	// Ignore the unmap if we have no mapped data.
-	if db.dataref == nil {
-		return nil
-	}
-
-	// Unmap using the original byte slice.
-	err := unix.Munmap(db.dataref)
-	db.dataref = nil
-	db.data = nil
-	db.datasz = 0
-	return err
-}
diff --git a/vendor/github.com/coreos/bbolt/bolt_windows.go b/vendor/github.com/coreos/bbolt/bolt_windows.go
deleted file mode 100644
index d538e6a..0000000
--- a/vendor/github.com/coreos/bbolt/bolt_windows.go
+++ /dev/null
@@ -1,144 +0,0 @@
-package bolt
-
-import (
-	"fmt"
-	"os"
-	"syscall"
-	"time"
-	"unsafe"
-)
-
-// LockFileEx code derived from golang build filemutex_windows.go @ v1.5.1
-var (
-	modkernel32      = syscall.NewLazyDLL("kernel32.dll")
-	procLockFileEx   = modkernel32.NewProc("LockFileEx")
-	procUnlockFileEx = modkernel32.NewProc("UnlockFileEx")
-)
-
-const (
-	lockExt = ".lock"
-
-	// see https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx
-	flagLockExclusive       = 2
-	flagLockFailImmediately = 1
-
-	// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
-	errLockViolation syscall.Errno = 0x21
-)
-
-func lockFileEx(h syscall.Handle, flags, reserved, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
-	r, _, err := procLockFileEx.Call(uintptr(h), uintptr(flags), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)))
-	if r == 0 {
-		return err
-	}
-	return nil
-}
-
-func unlockFileEx(h syscall.Handle, reserved, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
-	r, _, err := procUnlockFileEx.Call(uintptr(h), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)), 0)
-	if r == 0 {
-		return err
-	}
-	return nil
-}
-
-// fdatasync flushes written data to a file descriptor.
-func fdatasync(db *DB) error {
-	return db.file.Sync()
-}
-
-// flock acquires an advisory lock on a file descriptor.
-func flock(db *DB, mode os.FileMode, exclusive bool, timeout time.Duration) error {
-	// Create a separate lock file on windows because a process
-	// cannot share an exclusive lock on the same file. This is
-	// needed during Tx.WriteTo().
-	f, err := os.OpenFile(db.path+lockExt, os.O_CREATE, mode)
-	if err != nil {
-		return err
-	}
-	db.lockfile = f
-
-	var t time.Time
-	for {
-		// If we're beyond our timeout then return an error.
-		// This can only occur after we've attempted a flock once.
-		if t.IsZero() {
-			t = time.Now()
-		} else if timeout > 0 && time.Since(t) > timeout {
-			return ErrTimeout
-		}
-
-		var flag uint32 = flagLockFailImmediately
-		if exclusive {
-			flag |= flagLockExclusive
-		}
-
-		err := lockFileEx(syscall.Handle(db.lockfile.Fd()), flag, 0, 1, 0, &syscall.Overlapped{})
-		if err == nil {
-			return nil
-		} else if err != errLockViolation {
-			return err
-		}
-
-		// Wait for a bit and try again.
-		time.Sleep(50 * time.Millisecond)
-	}
-}
-
-// funlock releases an advisory lock on a file descriptor.
-func funlock(db *DB) error {
-	err := unlockFileEx(syscall.Handle(db.lockfile.Fd()), 0, 1, 0, &syscall.Overlapped{})
-	db.lockfile.Close()
-	os.Remove(db.path+lockExt)
-	return err
-}
-
-// mmap memory maps a DB's data file.
-// Based on: https://github.com/edsrzf/mmap-go
-func mmap(db *DB, sz int) error {
-	if !db.readOnly {
-		// Truncate the database to the size of the mmap.
-		if err := db.file.Truncate(int64(sz)); err != nil {
-			return fmt.Errorf("truncate: %s", err)
-		}
-	}
-
-	// Open a file mapping handle.
-	sizelo := uint32(sz >> 32)
-	sizehi := uint32(sz) & 0xffffffff
-	h, errno := syscall.CreateFileMapping(syscall.Handle(db.file.Fd()), nil, syscall.PAGE_READONLY, sizelo, sizehi, nil)
-	if h == 0 {
-		return os.NewSyscallError("CreateFileMapping", errno)
-	}
-
-	// Create the memory map.
-	addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, uintptr(sz))
-	if addr == 0 {
-		return os.NewSyscallError("MapViewOfFile", errno)
-	}
-
-	// Close mapping handle.
-	if err := syscall.CloseHandle(syscall.Handle(h)); err != nil {
-		return os.NewSyscallError("CloseHandle", err)
-	}
-
-	// Convert to a byte array.
-	db.data = ((*[maxMapSize]byte)(unsafe.Pointer(addr)))
-	db.datasz = sz
-
-	return nil
-}
-
-// munmap unmaps a pointer from a file.
-// Based on: https://github.com/edsrzf/mmap-go
-func munmap(db *DB) error {
-	if db.data == nil {
-		return nil
-	}
-
-	addr := (uintptr)(unsafe.Pointer(&db.data[0]))
-	if err := syscall.UnmapViewOfFile(addr); err != nil {
-		return os.NewSyscallError("UnmapViewOfFile", err)
-	}
-	return nil
-}
diff --git a/vendor/github.com/coreos/bbolt/boltsync_unix.go b/vendor/github.com/coreos/bbolt/boltsync_unix.go
deleted file mode 100644
index f504425..0000000
--- a/vendor/github.com/coreos/bbolt/boltsync_unix.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// +build !windows,!plan9,!linux,!openbsd
-
-package bolt
-
-// fdatasync flushes written data to a file descriptor.
-func fdatasync(db *DB) error {
-	return db.file.Sync()
-}
diff --git a/vendor/github.com/coreos/bbolt/bucket.go b/vendor/github.com/coreos/bbolt/bucket.go
deleted file mode 100644
index d2f8c52..0000000
--- a/vendor/github.com/coreos/bbolt/bucket.go
+++ /dev/null
@@ -1,748 +0,0 @@
-package bolt
-
-import (
-	"bytes"
-	"fmt"
-	"unsafe"
-)
-
-const (
-	// MaxKeySize is the maximum length of a key, in bytes.
-	MaxKeySize = 32768
-
-	// MaxValueSize is the maximum length of a value, in bytes.
-	MaxValueSize = (1 << 31) - 2
-)
-
-const (
-	maxUint = ^uint(0)
-	minUint = 0
-	maxInt  = int(^uint(0) >> 1)
-	minInt  = -maxInt - 1
-)
-
-const bucketHeaderSize = int(unsafe.Sizeof(bucket{}))
-
-const (
-	minFillPercent = 0.1
-	maxFillPercent = 1.0
-)
-
-// DefaultFillPercent is the percentage that split pages are filled.
-// This value can be changed by setting Bucket.FillPercent.
-const DefaultFillPercent = 0.5
-
-// Bucket represents a collection of key/value pairs inside the database.
-type Bucket struct {
-	*bucket
-	tx       *Tx                // the associated transaction
-	buckets  map[string]*Bucket // subbucket cache
-	page     *page              // inline page reference
-	rootNode *node              // materialized node for the root page.
-	nodes    map[pgid]*node     // node cache
-
-	// Sets the threshold for filling nodes when they split. By default,
-	// the bucket will fill to 50% but it can be useful to increase this
-	// amount if you know that your write workloads are mostly append-only.
-	//
-	// This is non-persisted across transactions so it must be set in every Tx.
-	FillPercent float64
-}
-
-// bucket represents the on-file representation of a bucket.
-// This is stored as the "value" of a bucket key. If the bucket is small enough,
-// then its root page can be stored inline in the "value", after the bucket
-// header. In the case of inline buckets, the "root" will be 0.
-type bucket struct {
-	root     pgid   // page id of the bucket's root-level page
-	sequence uint64 // monotonically incrementing, used by NextSequence()
-}
-
-// newBucket returns a new bucket associated with a transaction.
-func newBucket(tx *Tx) Bucket {
-	var b = Bucket{tx: tx, FillPercent: DefaultFillPercent}
-	if tx.writable {
-		b.buckets = make(map[string]*Bucket)
-		b.nodes = make(map[pgid]*node)
-	}
-	return b
-}
-
-// Tx returns the tx of the bucket.
-func (b *Bucket) Tx() *Tx {
-	return b.tx
-}
-
-// Root returns the root of the bucket.
-func (b *Bucket) Root() pgid {
-	return b.root
-}
-
-// Writable returns whether the bucket is writable.
-func (b *Bucket) Writable() bool {
-	return b.tx.writable
-}
-
-// Cursor creates a cursor associated with the bucket.
-// The cursor is only valid as long as the transaction is open.
-// Do not use a cursor after the transaction is closed.
-func (b *Bucket) Cursor() *Cursor {
-	// Update transaction statistics.
-	b.tx.stats.CursorCount++
-
-	// Allocate and return a cursor.
-	return &Cursor{
-		bucket: b,
-		stack:  make([]elemRef, 0),
-	}
-}
-
-// Bucket retrieves a nested bucket by name.
-// Returns nil if the bucket does not exist.
-// The bucket instance is only valid for the lifetime of the transaction.
-func (b *Bucket) Bucket(name []byte) *Bucket {
-	if b.buckets != nil {
-		if child := b.buckets[string(name)]; child != nil {
-			return child
-		}
-	}
-
-	// Move cursor to key.
-	c := b.Cursor()
-	k, v, flags := c.seek(name)
-
-	// Return nil if the key doesn't exist or it is not a bucket.
-	if !bytes.Equal(name, k) || (flags&bucketLeafFlag) == 0 {
-		return nil
-	}
-
-	// Otherwise create a bucket and cache it.
-	var child = b.openBucket(v)
-	if b.buckets != nil {
-		b.buckets[string(name)] = child
-	}
-
-	return child
-}
-
-// Helper method that re-interprets a sub-bucket value
-// from a parent into a Bucket
-func (b *Bucket) openBucket(value []byte) *Bucket {
-	var child = newBucket(b.tx)
-
-	// If this is a writable transaction then we need to copy the bucket entry.
-	// Read-only transactions can point directly at the mmap entry.
-	if b.tx.writable {
-		child.bucket = &bucket{}
-		*child.bucket = *(*bucket)(unsafe.Pointer(&value[0]))
-	} else {
-		child.bucket = (*bucket)(unsafe.Pointer(&value[0]))
-	}
-
-	// Save a reference to the inline page if the bucket is inline.
-	if child.root == 0 {
-		child.page = (*page)(unsafe.Pointer(&value[bucketHeaderSize]))
-	}
-
-	return &child
-}
-
-// CreateBucket creates a new bucket at the given key and returns the new bucket.
-// Returns an error if the key already exists, if the bucket name is blank, or if the bucket name is too long.
-// The bucket instance is only valid for the lifetime of the transaction.
-func (b *Bucket) CreateBucket(key []byte) (*Bucket, error) {
-	if b.tx.db == nil {
-		return nil, ErrTxClosed
-	} else if !b.tx.writable {
-		return nil, ErrTxNotWritable
-	} else if len(key) == 0 {
-		return nil, ErrBucketNameRequired
-	}
-
-	// Move cursor to correct position.
-	c := b.Cursor()
-	k, _, flags := c.seek(key)
-
-	// Return an error if there is an existing key.
-	if bytes.Equal(key, k) {
-		if (flags & bucketLeafFlag) != 0 {
-			return nil, ErrBucketExists
-		} else {
-			return nil, ErrIncompatibleValue
-		}
-	}
-
-	// Create empty, inline bucket.
-	var bucket = Bucket{
-		bucket:      &bucket{},
-		rootNode:    &node{isLeaf: true},
-		FillPercent: DefaultFillPercent,
-	}
-	var value = bucket.write()
-
-	// Insert into node.
-	key = cloneBytes(key)
-	c.node().put(key, key, value, 0, bucketLeafFlag)
-
-	// Since subbuckets are not allowed on inline buckets, we need to
-	// dereference the inline page, if it exists. This will cause the bucket
-	// to be treated as a regular, non-inline bucket for the rest of the tx.
-	b.page = nil
-
-	return b.Bucket(key), nil
-}
-
-// CreateBucketIfNotExists creates a new bucket if it doesn't already exist and returns a reference to it.
-// Returns an error if the bucket name is blank, or if the bucket name is too long.
-// The bucket instance is only valid for the lifetime of the transaction.
-func (b *Bucket) CreateBucketIfNotExists(key []byte) (*Bucket, error) {
-	child, err := b.CreateBucket(key)
-	if err == ErrBucketExists {
-		return b.Bucket(key), nil
-	} else if err != nil {
-		return nil, err
-	}
-	return child, nil
-}
-
-// DeleteBucket deletes a bucket at the given key.
-// Returns an error if the bucket does not exists, or if the key represents a non-bucket value.
-func (b *Bucket) DeleteBucket(key []byte) error {
-	if b.tx.db == nil {
-		return ErrTxClosed
-	} else if !b.Writable() {
-		return ErrTxNotWritable
-	}
-
-	// Move cursor to correct position.
-	c := b.Cursor()
-	k, _, flags := c.seek(key)
-
-	// Return an error if bucket doesn't exist or is not a bucket.
-	if !bytes.Equal(key, k) {
-		return ErrBucketNotFound
-	} else if (flags & bucketLeafFlag) == 0 {
-		return ErrIncompatibleValue
-	}
-
-	// Recursively delete all child buckets.
-	child := b.Bucket(key)
-	err := child.ForEach(func(k, v []byte) error {
-		if v == nil {
-			if err := child.DeleteBucket(k); err != nil {
-				return fmt.Errorf("delete bucket: %s", err)
-			}
-		}
-		return nil
-	})
-	if err != nil {
-		return err
-	}
-
-	// Remove cached copy.
-	delete(b.buckets, string(key))
-
-	// Release all bucket pages to freelist.
-	child.nodes = nil
-	child.rootNode = nil
-	child.free()
-
-	// Delete the node if we have a matching key.
-	c.node().del(key)
-
-	return nil
-}
-
-// Get retrieves the value for a key in the bucket.
-// Returns a nil value if the key does not exist or if the key is a nested bucket.
-// The returned value is only valid for the life of the transaction.
-func (b *Bucket) Get(key []byte) []byte {
-	k, v, flags := b.Cursor().seek(key)
-
-	// Return nil if this is a bucket.
-	if (flags & bucketLeafFlag) != 0 {
-		return nil
-	}
-
-	// If our target node isn't the same key as what's passed in then return nil.
-	if !bytes.Equal(key, k) {
-		return nil
-	}
-	return v
-}
-
-// Put sets the value for a key in the bucket.
-// If the key exist then its previous value will be overwritten.
-// Supplied value must remain valid for the life of the transaction.
-// Returns an error if the bucket was created from a read-only transaction, if the key is blank, if the key is too large, or if the value is too large.
-func (b *Bucket) Put(key []byte, value []byte) error {
-	if b.tx.db == nil {
-		return ErrTxClosed
-	} else if !b.Writable() {
-		return ErrTxNotWritable
-	} else if len(key) == 0 {
-		return ErrKeyRequired
-	} else if len(key) > MaxKeySize {
-		return ErrKeyTooLarge
-	} else if int64(len(value)) > MaxValueSize {
-		return ErrValueTooLarge
-	}
-
-	// Move cursor to correct position.
-	c := b.Cursor()
-	k, _, flags := c.seek(key)
-
-	// Return an error if there is an existing key with a bucket value.
-	if bytes.Equal(key, k) && (flags&bucketLeafFlag) != 0 {
-		return ErrIncompatibleValue
-	}
-
-	// Insert into node.
-	key = cloneBytes(key)
-	c.node().put(key, key, value, 0, 0)
-
-	return nil
-}
-
-// Delete removes a key from the bucket.
-// If the key does not exist then nothing is done and a nil error is returned.
-// Returns an error if the bucket was created from a read-only transaction.
-func (b *Bucket) Delete(key []byte) error {
-	if b.tx.db == nil {
-		return ErrTxClosed
-	} else if !b.Writable() {
-		return ErrTxNotWritable
-	}
-
-	// Move cursor to correct position.
-	c := b.Cursor()
-	_, _, flags := c.seek(key)
-
-	// Return an error if there is already existing bucket value.
-	if (flags & bucketLeafFlag) != 0 {
-		return ErrIncompatibleValue
-	}
-
-	// Delete the node if we have a matching key.
-	c.node().del(key)
-
-	return nil
-}
-
-// NextSequence returns an autoincrementing integer for the bucket.
-func (b *Bucket) NextSequence() (uint64, error) {
-	if b.tx.db == nil {
-		return 0, ErrTxClosed
-	} else if !b.Writable() {
-		return 0, ErrTxNotWritable
-	}
-
-	// Materialize the root node if it hasn't been already so that the
-	// bucket will be saved during commit.
-	if b.rootNode == nil {
-		_ = b.node(b.root, nil)
-	}
-
-	// Increment and return the sequence.
-	b.bucket.sequence++
-	return b.bucket.sequence, nil
-}
-
-// ForEach executes a function for each key/value pair in a bucket.
-// If the provided function returns an error then the iteration is stopped and
-// the error is returned to the caller. The provided function must not modify
-// the bucket; this will result in undefined behavior.
-func (b *Bucket) ForEach(fn func(k, v []byte) error) error {
-	if b.tx.db == nil {
-		return ErrTxClosed
-	}
-	c := b.Cursor()
-	for k, v := c.First(); k != nil; k, v = c.Next() {
-		if err := fn(k, v); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-// Stat returns stats on a bucket.
-func (b *Bucket) Stats() BucketStats {
-	var s, subStats BucketStats
-	pageSize := b.tx.db.pageSize
-	s.BucketN += 1
-	if b.root == 0 {
-		s.InlineBucketN += 1
-	}
-	b.forEachPage(func(p *page, depth int) {
-		if (p.flags & leafPageFlag) != 0 {
-			s.KeyN += int(p.count)
-
-			// used totals the used bytes for the page
-			used := pageHeaderSize
-
-			if p.count != 0 {
-				// If page has any elements, add all element headers.
-				used += leafPageElementSize * int(p.count-1)
-
-				// Add all element key, value sizes.
-				// The computation takes advantage of the fact that the position
-				// of the last element's key/value equals to the total of the sizes
-				// of all previous elements' keys and values.
-				// It also includes the last element's header.
-				lastElement := p.leafPageElement(p.count - 1)
-				used += int(lastElement.pos + lastElement.ksize + lastElement.vsize)
-			}
-
-			if b.root == 0 {
-				// For inlined bucket just update the inline stats
-				s.InlineBucketInuse += used
-			} else {
-				// For non-inlined bucket update all the leaf stats
-				s.LeafPageN++
-				s.LeafInuse += used
-				s.LeafOverflowN += int(p.overflow)
-
-				// Collect stats from sub-buckets.
-				// Do that by iterating over all element headers
-				// looking for the ones with the bucketLeafFlag.
-				for i := uint16(0); i < p.count; i++ {
-					e := p.leafPageElement(i)
-					if (e.flags & bucketLeafFlag) != 0 {
-						// For any bucket element, open the element value
-						// and recursively call Stats on the contained bucket.
-						subStats.Add(b.openBucket(e.value()).Stats())
-					}
-				}
-			}
-		} else if (p.flags & branchPageFlag) != 0 {
-			s.BranchPageN++
-			lastElement := p.branchPageElement(p.count - 1)
-
-			// used totals the used bytes for the page
-			// Add header and all element headers.
-			used := pageHeaderSize + (branchPageElementSize * int(p.count-1))
-
-			// Add size of all keys and values.
-			// Again, use the fact that last element's position equals to
-			// the total of key, value sizes of all previous elements.
-			used += int(lastElement.pos + lastElement.ksize)
-			s.BranchInuse += used
-			s.BranchOverflowN += int(p.overflow)
-		}
-
-		// Keep track of maximum page depth.
-		if depth+1 > s.Depth {
-			s.Depth = (depth + 1)
-		}
-	})
-
-	// Alloc stats can be computed from page counts and pageSize.
-	s.BranchAlloc = (s.BranchPageN + s.BranchOverflowN) * pageSize
-	s.LeafAlloc = (s.LeafPageN + s.LeafOverflowN) * pageSize
-
-	// Add the max depth of sub-buckets to get total nested depth.
-	s.Depth += subStats.Depth
-	// Add the stats for all sub-buckets
-	s.Add(subStats)
-	return s
-}
-
-// forEachPage iterates over every page in a bucket, including inline pages.
-func (b *Bucket) forEachPage(fn func(*page, int)) {
-	// If we have an inline page then just use that.
-	if b.page != nil {
-		fn(b.page, 0)
-		return
-	}
-
-	// Otherwise traverse the page hierarchy.
-	b.tx.forEachPage(b.root, 0, fn)
-}
-
-// forEachPageNode iterates over every page (or node) in a bucket.
-// This also includes inline pages.
-func (b *Bucket) forEachPageNode(fn func(*page, *node, int)) {
-	// If we have an inline page or root node then just use that.
-	if b.page != nil {
-		fn(b.page, nil, 0)
-		return
-	}
-	b._forEachPageNode(b.root, 0, fn)
-}
-
-func (b *Bucket) _forEachPageNode(pgid pgid, depth int, fn func(*page, *node, int)) {
-	var p, n = b.pageNode(pgid)
-
-	// Execute function.
-	fn(p, n, depth)
-
-	// Recursively loop over children.
-	if p != nil {
-		if (p.flags & branchPageFlag) != 0 {
-			for i := 0; i < int(p.count); i++ {
-				elem := p.branchPageElement(uint16(i))
-				b._forEachPageNode(elem.pgid, depth+1, fn)
-			}
-		}
-	} else {
-		if !n.isLeaf {
-			for _, inode := range n.inodes {
-				b._forEachPageNode(inode.pgid, depth+1, fn)
-			}
-		}
-	}
-}
-
-// spill writes all the nodes for this bucket to dirty pages.
-func (b *Bucket) spill() error {
-	// Spill all child buckets first.
-	for name, child := range b.buckets {
-		// If the child bucket is small enough and it has no child buckets then
-		// write it inline into the parent bucket's page. Otherwise spill it
-		// like a normal bucket and make the parent value a pointer to the page.
-		var value []byte
-		if child.inlineable() {
-			child.free()
-			value = child.write()
-		} else {
-			if err := child.spill(); err != nil {
-				return err
-			}
-
-			// Update the child bucket header in this bucket.
-			value = make([]byte, unsafe.Sizeof(bucket{}))
-			var bucket = (*bucket)(unsafe.Pointer(&value[0]))
-			*bucket = *child.bucket
-		}
-
-		// Skip writing the bucket if there are no materialized nodes.
-		if child.rootNode == nil {
-			continue
-		}
-
-		// Update parent node.
-		var c = b.Cursor()
-		k, _, flags := c.seek([]byte(name))
-		if !bytes.Equal([]byte(name), k) {
-			panic(fmt.Sprintf("misplaced bucket header: %x -> %x", []byte(name), k))
-		}
-		if flags&bucketLeafFlag == 0 {
-			panic(fmt.Sprintf("unexpected bucket header flag: %x", flags))
-		}
-		c.node().put([]byte(name), []byte(name), value, 0, bucketLeafFlag)
-	}
-
-	// Ignore if there's not a materialized root node.
-	if b.rootNode == nil {
-		return nil
-	}
-
-	// Spill nodes.
-	if err := b.rootNode.spill(); err != nil {
-		return err
-	}
-	b.rootNode = b.rootNode.root()
-
-	// Update the root node for this bucket.
-	if b.rootNode.pgid >= b.tx.meta.pgid {
-		panic(fmt.Sprintf("pgid (%d) above high water mark (%d)", b.rootNode.pgid, b.tx.meta.pgid))
-	}
-	b.root = b.rootNode.pgid
-
-	return nil
-}
-
-// inlineable returns true if a bucket is small enough to be written inline
-// and if it contains no subbuckets. Otherwise returns false.
-func (b *Bucket) inlineable() bool {
-	var n = b.rootNode
-
-	// Bucket must only contain a single leaf node.
-	if n == nil || !n.isLeaf {
-		return false
-	}
-
-	// Bucket is not inlineable if it contains subbuckets or if it goes beyond
-	// our threshold for inline bucket size.
-	var size = pageHeaderSize
-	for _, inode := range n.inodes {
-		size += leafPageElementSize + len(inode.key) + len(inode.value)
-
-		if inode.flags&bucketLeafFlag != 0 {
-			return false
-		} else if size > b.maxInlineBucketSize() {
-			return false
-		}
-	}
-
-	return true
-}
-
-// Returns the maximum total size of a bucket to make it a candidate for inlining.
-func (b *Bucket) maxInlineBucketSize() int {
-	return b.tx.db.pageSize / 4
-}
-
-// write allocates and writes a bucket to a byte slice.
-func (b *Bucket) write() []byte {
-	// Allocate the appropriate size.
-	var n = b.rootNode
-	var value = make([]byte, bucketHeaderSize+n.size())
-
-	// Write a bucket header.
-	var bucket = (*bucket)(unsafe.Pointer(&value[0]))
-	*bucket = *b.bucket
-
-	// Convert byte slice to a fake page and write the root node.
-	var p = (*page)(unsafe.Pointer(&value[bucketHeaderSize]))
-	n.write(p)
-
-	return value
-}
-
-// rebalance attempts to balance all nodes.
-func (b *Bucket) rebalance() {
-	for _, n := range b.nodes {
-		n.rebalance()
-	}
-	for _, child := range b.buckets {
-		child.rebalance()
-	}
-}
-
-// node creates a node from a page and associates it with a given parent.
-func (b *Bucket) node(pgid pgid, parent *node) *node {
-	_assert(b.nodes != nil, "nodes map expected")
-
-	// Retrieve node if it's already been created.
-	if n := b.nodes[pgid]; n != nil {
-		return n
-	}
-
-	// Otherwise create a node and cache it.
-	n := &node{bucket: b, parent: parent}
-	if parent == nil {
-		b.rootNode = n
-	} else {
-		parent.children = append(parent.children, n)
-	}
-
-	// Use the inline page if this is an inline bucket.
-	var p = b.page
-	if p == nil {
-		p = b.tx.page(pgid)
-	}
-
-	// Read the page into the node and cache it.
-	n.read(p)
-	b.nodes[pgid] = n
-
-	// Update statistics.
-	b.tx.stats.NodeCount++
-
-	return n
-}
-
-// free recursively frees all pages in the bucket.
-func (b *Bucket) free() {
-	if b.root == 0 {
-		return
-	}
-
-	var tx = b.tx
-	b.forEachPageNode(func(p *page, n *node, _ int) {
-		if p != nil {
-			tx.db.freelist.free(tx.meta.txid, p)
-		} else {
-			n.free()
-		}
-	})
-	b.root = 0
-}
-
-// dereference removes all references to the old mmap.
-func (b *Bucket) dereference() {
-	if b.rootNode != nil {
-		b.rootNode.root().dereference()
-	}
-
-	for _, child := range b.buckets {
-		child.dereference()
-	}
-}
-
-// pageNode returns the in-memory node, if it exists.
-// Otherwise returns the underlying page.
-func (b *Bucket) pageNode(id pgid) (*page, *node) {
-	// Inline buckets have a fake page embedded in their value so treat them
-	// differently. We'll return the rootNode (if available) or the fake page.
-	if b.root == 0 {
-		if id != 0 {
-			panic(fmt.Sprintf("inline bucket non-zero page access(2): %d != 0", id))
-		}
-		if b.rootNode != nil {
-			return nil, b.rootNode
-		}
-		return b.page, nil
-	}
-
-	// Check the node cache for non-inline buckets.
-	if b.nodes != nil {
-		if n := b.nodes[id]; n != nil {
-			return nil, n
-		}
-	}
-
-	// Finally lookup the page from the transaction if no node is materialized.
-	return b.tx.page(id), nil
-}
-
-// BucketStats records statistics about resources used by a bucket.
-type BucketStats struct {
-	// Page count statistics.
-	BranchPageN     int // number of logical branch pages
-	BranchOverflowN int // number of physical branch overflow pages
-	LeafPageN       int // number of logical leaf pages
-	LeafOverflowN   int // number of physical leaf overflow pages
-
-	// Tree statistics.
-	KeyN  int // number of keys/value pairs
-	Depth int // number of levels in B+tree
-
-	// Page size utilization.
-	BranchAlloc int // bytes allocated for physical branch pages
-	BranchInuse int // bytes actually used for branch data
-	LeafAlloc   int // bytes allocated for physical leaf pages
-	LeafInuse   int // bytes actually used for leaf data
-
-	// Bucket statistics
-	BucketN           int // total number of buckets including the top bucket
-	InlineBucketN     int // total number on inlined buckets
-	InlineBucketInuse int // bytes used for inlined buckets (also accounted for in LeafInuse)
-}
-
-func (s *BucketStats) Add(other BucketStats) {
-	s.BranchPageN += other.BranchPageN
-	s.BranchOverflowN += other.BranchOverflowN
-	s.LeafPageN += other.LeafPageN
-	s.LeafOverflowN += other.LeafOverflowN
-	s.KeyN += other.KeyN
-	if s.Depth < other.Depth {
-		s.Depth = other.Depth
-	}
-	s.BranchAlloc += other.BranchAlloc
-	s.BranchInuse += other.BranchInuse
-	s.LeafAlloc += other.LeafAlloc
-	s.LeafInuse += other.LeafInuse
-
-	s.BucketN += other.BucketN
-	s.InlineBucketN += other.InlineBucketN
-	s.InlineBucketInuse += other.InlineBucketInuse
-}
-
-// cloneBytes returns a copy of a given slice.
-func cloneBytes(v []byte) []byte {
-	var clone = make([]byte, len(v))
-	copy(clone, v)
-	return clone
-}
diff --git a/vendor/github.com/coreos/bbolt/cursor.go b/vendor/github.com/coreos/bbolt/cursor.go
deleted file mode 100644
index 1be9f35..0000000
--- a/vendor/github.com/coreos/bbolt/cursor.go
+++ /dev/null
@@ -1,400 +0,0 @@
-package bolt
-
-import (
-	"bytes"
-	"fmt"
-	"sort"
-)
-
-// Cursor represents an iterator that can traverse over all key/value pairs in a bucket in sorted order.
-// Cursors see nested buckets with value == nil.
-// Cursors can be obtained from a transaction and are valid as long as the transaction is open.
-//
-// Keys and values returned from the cursor are only valid for the life of the transaction.
-//
-// Changing data while traversing with a cursor may cause it to be invalidated
-// and return unexpected keys and/or values. You must reposition your cursor
-// after mutating data.
-type Cursor struct {
-	bucket *Bucket
-	stack  []elemRef
-}
-
-// Bucket returns the bucket that this cursor was created from.
-func (c *Cursor) Bucket() *Bucket {
-	return c.bucket
-}
-
-// First moves the cursor to the first item in the bucket and returns its key and value.
-// If the bucket is empty then a nil key and value are returned.
-// The returned key and value are only valid for the life of the transaction.
-func (c *Cursor) First() (key []byte, value []byte) {
-	_assert(c.bucket.tx.db != nil, "tx closed")
-	c.stack = c.stack[:0]
-	p, n := c.bucket.pageNode(c.bucket.root)
-	c.stack = append(c.stack, elemRef{page: p, node: n, index: 0})
-	c.first()
-
-	// If we land on an empty page then move to the next value.
-	// https://github.com/boltdb/bolt/issues/450
-	if c.stack[len(c.stack)-1].count() == 0 {
-		c.next()
-	}
-
-	k, v, flags := c.keyValue()
-	if (flags & uint32(bucketLeafFlag)) != 0 {
-		return k, nil
-	}
-	return k, v
-
-}
-
-// Last moves the cursor to the last item in the bucket and returns its key and value.
-// If the bucket is empty then a nil key and value are returned.
-// The returned key and value are only valid for the life of the transaction.
-func (c *Cursor) Last() (key []byte, value []byte) {
-	_assert(c.bucket.tx.db != nil, "tx closed")
-	c.stack = c.stack[:0]
-	p, n := c.bucket.pageNode(c.bucket.root)
-	ref := elemRef{page: p, node: n}
-	ref.index = ref.count() - 1
-	c.stack = append(c.stack, ref)
-	c.last()
-	k, v, flags := c.keyValue()
-	if (flags & uint32(bucketLeafFlag)) != 0 {
-		return k, nil
-	}
-	return k, v
-}
-
-// Next moves the cursor to the next item in the bucket and returns its key and value.
-// If the cursor is at the end of the bucket then a nil key and value are returned.
-// The returned key and value are only valid for the life of the transaction.
-func (c *Cursor) Next() (key []byte, value []byte) {
-	_assert(c.bucket.tx.db != nil, "tx closed")
-	k, v, flags := c.next()
-	if (flags & uint32(bucketLeafFlag)) != 0 {
-		return k, nil
-	}
-	return k, v
-}
-
-// Prev moves the cursor to the previous item in the bucket and returns its key and value.
-// If the cursor is at the beginning of the bucket then a nil key and value are returned.
-// The returned key and value are only valid for the life of the transaction.
-func (c *Cursor) Prev() (key []byte, value []byte) {
-	_assert(c.bucket.tx.db != nil, "tx closed")
-
-	// Attempt to move back one element until we're successful.
-	// Move up the stack as we hit the beginning of each page in our stack.
-	for i := len(c.stack) - 1; i >= 0; i-- {
-		elem := &c.stack[i]
-		if elem.index > 0 {
-			elem.index--
-			break
-		}
-		c.stack = c.stack[:i]
-	}
-
-	// If we've hit the end then return nil.
-	if len(c.stack) == 0 {
-		return nil, nil
-	}
-
-	// Move down the stack to find the last element of the last leaf under this branch.
-	c.last()
-	k, v, flags := c.keyValue()
-	if (flags & uint32(bucketLeafFlag)) != 0 {
-		return k, nil
-	}
-	return k, v
-}
-
-// Seek moves the cursor to a given key and returns it.
-// If the key does not exist then the next key is used. If no keys
-// follow, a nil key is returned.
-// The returned key and value are only valid for the life of the transaction.
-func (c *Cursor) Seek(seek []byte) (key []byte, value []byte) {
-	k, v, flags := c.seek(seek)
-
-	// If we ended up after the last element of a page then move to the next one.
-	if ref := &c.stack[len(c.stack)-1]; ref.index >= ref.count() {
-		k, v, flags = c.next()
-	}
-
-	if k == nil {
-		return nil, nil
-	} else if (flags & uint32(bucketLeafFlag)) != 0 {
-		return k, nil
-	}
-	return k, v
-}
-
-// Delete removes the current key/value under the cursor from the bucket.
-// Delete fails if current key/value is a bucket or if the transaction is not writable.
-func (c *Cursor) Delete() error {
-	if c.bucket.tx.db == nil {
-		return ErrTxClosed
-	} else if !c.bucket.Writable() {
-		return ErrTxNotWritable
-	}
-
-	key, _, flags := c.keyValue()
-	// Return an error if current value is a bucket.
-	if (flags & bucketLeafFlag) != 0 {
-		return ErrIncompatibleValue
-	}
-	c.node().del(key)
-
-	return nil
-}
-
-// seek moves the cursor to a given key and returns it.
-// If the key does not exist then the next key is used.
-func (c *Cursor) seek(seek []byte) (key []byte, value []byte, flags uint32) {
-	_assert(c.bucket.tx.db != nil, "tx closed")
-
-	// Start from root page/node and traverse to correct page.
-	c.stack = c.stack[:0]
-	c.search(seek, c.bucket.root)
-	ref := &c.stack[len(c.stack)-1]
-
-	// If the cursor is pointing to the end of page/node then return nil.
-	if ref.index >= ref.count() {
-		return nil, nil, 0
-	}
-
-	// If this is a bucket then return a nil value.
-	return c.keyValue()
-}
-
-// first moves the cursor to the first leaf element under the last page in the stack.
-func (c *Cursor) first() {
-	for {
-		// Exit when we hit a leaf page.
-		var ref = &c.stack[len(c.stack)-1]
-		if ref.isLeaf() {
-			break
-		}
-
-		// Keep adding pages pointing to the first element to the stack.
-		var pgid pgid
-		if ref.node != nil {
-			pgid = ref.node.inodes[ref.index].pgid
-		} else {
-			pgid = ref.page.branchPageElement(uint16(ref.index)).pgid
-		}
-		p, n := c.bucket.pageNode(pgid)
-		c.stack = append(c.stack, elemRef{page: p, node: n, index: 0})
-	}
-}
-
-// last moves the cursor to the last leaf element under the last page in the stack.
-func (c *Cursor) last() {
-	for {
-		// Exit when we hit a leaf page.
-		ref := &c.stack[len(c.stack)-1]
-		if ref.isLeaf() {
-			break
-		}
-
-		// Keep adding pages pointing to the last element in the stack.
-		var pgid pgid
-		if ref.node != nil {
-			pgid = ref.node.inodes[ref.index].pgid
-		} else {
-			pgid = ref.page.branchPageElement(uint16(ref.index)).pgid
-		}
-		p, n := c.bucket.pageNode(pgid)
-
-		var nextRef = elemRef{page: p, node: n}
-		nextRef.index = nextRef.count() - 1
-		c.stack = append(c.stack, nextRef)
-	}
-}
-
-// next moves to the next leaf element and returns the key and value.
-// If the cursor is at the last leaf element then it stays there and returns nil.
-func (c *Cursor) next() (key []byte, value []byte, flags uint32) {
-	for {
-		// Attempt to move over one element until we're successful.
-		// Move up the stack as we hit the end of each page in our stack.
-		var i int
-		for i = len(c.stack) - 1; i >= 0; i-- {
-			elem := &c.stack[i]
-			if elem.index < elem.count()-1 {
-				elem.index++
-				break
-			}
-		}
-
-		// If we've hit the root page then stop and return. This will leave the
-		// cursor on the last element of the last page.
-		if i == -1 {
-			return nil, nil, 0
-		}
-
-		// Otherwise start from where we left off in the stack and find the
-		// first element of the first leaf page.
-		c.stack = c.stack[:i+1]
-		c.first()
-
-		// If this is an empty page then restart and move back up the stack.
-		// https://github.com/boltdb/bolt/issues/450
-		if c.stack[len(c.stack)-1].count() == 0 {
-			continue
-		}
-
-		return c.keyValue()
-	}
-}
-
-// search recursively performs a binary search against a given page/node until it finds a given key.
-func (c *Cursor) search(key []byte, pgid pgid) {
-	p, n := c.bucket.pageNode(pgid)
-	if p != nil && (p.flags&(branchPageFlag|leafPageFlag)) == 0 {
-		panic(fmt.Sprintf("invalid page type: %d: %x", p.id, p.flags))
-	}
-	e := elemRef{page: p, node: n}
-	c.stack = append(c.stack, e)
-
-	// If we're on a leaf page/node then find the specific node.
-	if e.isLeaf() {
-		c.nsearch(key)
-		return
-	}
-
-	if n != nil {
-		c.searchNode(key, n)
-		return
-	}
-	c.searchPage(key, p)
-}
-
-func (c *Cursor) searchNode(key []byte, n *node) {
-	var exact bool
-	index := sort.Search(len(n.inodes), func(i int) bool {
-		// TODO(benbjohnson): Optimize this range search. It's a bit hacky right now.
-		// sort.Search() finds the lowest index where f() != -1 but we need the highest index.
-		ret := bytes.Compare(n.inodes[i].key, key)
-		if ret == 0 {
-			exact = true
-		}
-		return ret != -1
-	})
-	if !exact && index > 0 {
-		index--
-	}
-	c.stack[len(c.stack)-1].index = index
-
-	// Recursively search to the next page.
-	c.search(key, n.inodes[index].pgid)
-}
-
-func (c *Cursor) searchPage(key []byte, p *page) {
-	// Binary search for the correct range.
-	inodes := p.branchPageElements()
-
-	var exact bool
-	index := sort.Search(int(p.count), func(i int) bool {
-		// TODO(benbjohnson): Optimize this range search. It's a bit hacky right now.
-		// sort.Search() finds the lowest index where f() != -1 but we need the highest index.
-		ret := bytes.Compare(inodes[i].key(), key)
-		if ret == 0 {
-			exact = true
-		}
-		return ret != -1
-	})
-	if !exact && index > 0 {
-		index--
-	}
-	c.stack[len(c.stack)-1].index = index
-
-	// Recursively search to the next page.
-	c.search(key, inodes[index].pgid)
-}
-
-// nsearch searches the leaf node on the top of the stack for a key.
-func (c *Cursor) nsearch(key []byte) {
-	e := &c.stack[len(c.stack)-1]
-	p, n := e.page, e.node
-
-	// If we have a node then search its inodes.
-	if n != nil {
-		index := sort.Search(len(n.inodes), func(i int) bool {
-			return bytes.Compare(n.inodes[i].key, key) != -1
-		})
-		e.index = index
-		return
-	}
-
-	// If we have a page then search its leaf elements.
-	inodes := p.leafPageElements()
-	index := sort.Search(int(p.count), func(i int) bool {
-		return bytes.Compare(inodes[i].key(), key) != -1
-	})
-	e.index = index
-}
-
-// keyValue returns the key and value of the current leaf element.
-func (c *Cursor) keyValue() ([]byte, []byte, uint32) {
-	ref := &c.stack[len(c.stack)-1]
-	if ref.count() == 0 || ref.index >= ref.count() {
-		return nil, nil, 0
-	}
-
-	// Retrieve value from node.
-	if ref.node != nil {
-		inode := &ref.node.inodes[ref.index]
-		return inode.key, inode.value, inode.flags
-	}
-
-	// Or retrieve value from page.
-	elem := ref.page.leafPageElement(uint16(ref.index))
-	return elem.key(), elem.value(), elem.flags
-}
-
-// node returns the node that the cursor is currently positioned on.
-func (c *Cursor) node() *node {
-	_assert(len(c.stack) > 0, "accessing a node with a zero-length cursor stack")
-
-	// If the top of the stack is a leaf node then just return it.
-	if ref := &c.stack[len(c.stack)-1]; ref.node != nil && ref.isLeaf() {
-		return ref.node
-	}
-
-	// Start from root and traverse down the hierarchy.
-	var n = c.stack[0].node
-	if n == nil {
-		n = c.bucket.node(c.stack[0].page.id, nil)
-	}
-	for _, ref := range c.stack[:len(c.stack)-1] {
-		_assert(!n.isLeaf, "expected branch node")
-		n = n.childAt(int(ref.index))
-	}
-	_assert(n.isLeaf, "expected leaf node")
-	return n
-}
-
-// elemRef represents a reference to an element on a given page/node.
-type elemRef struct {
-	page  *page
-	node  *node
-	index int
-}
-
-// isLeaf returns whether the ref is pointing at a leaf page/node.
-func (r *elemRef) isLeaf() bool {
-	if r.node != nil {
-		return r.node.isLeaf
-	}
-	return (r.page.flags & leafPageFlag) != 0
-}
-
-// count returns the number of inodes or page elements.
-func (r *elemRef) count() int {
-	if r.node != nil {
-		return len(r.node.inodes)
-	}
-	return int(r.page.count)
-}
diff --git a/vendor/github.com/coreos/bbolt/db.go b/vendor/github.com/coreos/bbolt/db.go
deleted file mode 100644
index 1223493..0000000
--- a/vendor/github.com/coreos/bbolt/db.go
+++ /dev/null
@@ -1,1036 +0,0 @@
-package bolt
-
-import (
-	"errors"
-	"fmt"
-	"hash/fnv"
-	"log"
-	"os"
-	"runtime"
-	"runtime/debug"
-	"strings"
-	"sync"
-	"time"
-	"unsafe"
-)
-
-// The largest step that can be taken when remapping the mmap.
-const maxMmapStep = 1 << 30 // 1GB
-
-// The data file format version.
-const version = 2
-
-// Represents a marker value to indicate that a file is a Bolt DB.
-const magic uint32 = 0xED0CDAED
-
-// IgnoreNoSync specifies whether the NoSync field of a DB is ignored when
-// syncing changes to a file.  This is required as some operating systems,
-// such as OpenBSD, do not have a unified buffer cache (UBC) and writes
-// must be synchronized using the msync(2) syscall.
-const IgnoreNoSync = runtime.GOOS == "openbsd"
-
-// Default values if not set in a DB instance.
-const (
-	DefaultMaxBatchSize  int = 1000
-	DefaultMaxBatchDelay     = 10 * time.Millisecond
-	DefaultAllocSize         = 16 * 1024 * 1024
-)
-
-// default page size for db is set to the OS page size.
-var defaultPageSize = os.Getpagesize()
-
-// DB represents a collection of buckets persisted to a file on disk.
-// All data access is performed through transactions which can be obtained through the DB.
-// All the functions on DB will return a ErrDatabaseNotOpen if accessed before Open() is called.
-type DB struct {
-	// When enabled, the database will perform a Check() after every commit.
-	// A panic is issued if the database is in an inconsistent state. This
-	// flag has a large performance impact so it should only be used for
-	// debugging purposes.
-	StrictMode bool
-
-	// Setting the NoSync flag will cause the database to skip fsync()
-	// calls after each commit. This can be useful when bulk loading data
-	// into a database and you can restart the bulk load in the event of
-	// a system failure or database corruption. Do not set this flag for
-	// normal use.
-	//
-	// If the package global IgnoreNoSync constant is true, this value is
-	// ignored.  See the comment on that constant for more details.
-	//
-	// THIS IS UNSAFE. PLEASE USE WITH CAUTION.
-	NoSync bool
-
-	// When true, skips the truncate call when growing the database.
-	// Setting this to true is only safe on non-ext3/ext4 systems.
-	// Skipping truncation avoids preallocation of hard drive space and
-	// bypasses a truncate() and fsync() syscall on remapping.
-	//
-	// https://github.com/boltdb/bolt/issues/284
-	NoGrowSync bool
-
-	// If you want to read the entire database fast, you can set MmapFlag to
-	// syscall.MAP_POPULATE on Linux 2.6.23+ for sequential read-ahead.
-	MmapFlags int
-
-	// MaxBatchSize is the maximum size of a batch. Default value is
-	// copied from DefaultMaxBatchSize in Open.
-	//
-	// If <=0, disables batching.
-	//
-	// Do not change concurrently with calls to Batch.
-	MaxBatchSize int
-
-	// MaxBatchDelay is the maximum delay before a batch starts.
-	// Default value is copied from DefaultMaxBatchDelay in Open.
-	//
-	// If <=0, effectively disables batching.
-	//
-	// Do not change concurrently with calls to Batch.
-	MaxBatchDelay time.Duration
-
-	// AllocSize is the amount of space allocated when the database
-	// needs to create new pages. This is done to amortize the cost
-	// of truncate() and fsync() when growing the data file.
-	AllocSize int
-
-	path     string
-	file     *os.File
-	lockfile *os.File // windows only
-	dataref  []byte   // mmap'ed readonly, write throws SEGV
-	data     *[maxMapSize]byte
-	datasz   int
-	filesz   int // current on disk file size
-	meta0    *meta
-	meta1    *meta
-	pageSize int
-	opened   bool
-	rwtx     *Tx
-	txs      []*Tx
-	freelist *freelist
-	stats    Stats
-
-	pagePool sync.Pool
-
-	batchMu sync.Mutex
-	batch   *batch
-
-	rwlock   sync.Mutex   // Allows only one writer at a time.
-	metalock sync.Mutex   // Protects meta page access.
-	mmaplock sync.RWMutex // Protects mmap access during remapping.
-	statlock sync.RWMutex // Protects stats access.
-
-	ops struct {
-		writeAt func(b []byte, off int64) (n int, err error)
-	}
-
-	// Read only mode.
-	// When true, Update() and Begin(true) return ErrDatabaseReadOnly immediately.
-	readOnly bool
-}
-
-// Path returns the path to currently open database file.
-func (db *DB) Path() string {
-	return db.path
-}
-
-// GoString returns the Go string representation of the database.
-func (db *DB) GoString() string {
-	return fmt.Sprintf("bolt.DB{path:%q}", db.path)
-}
-
-// String returns the string representation of the database.
-func (db *DB) String() string {
-	return fmt.Sprintf("DB<%q>", db.path)
-}
-
-// Open creates and opens a database at the given path.
-// If the file does not exist then it will be created automatically.
-// Passing in nil options will cause Bolt to open the database with the default options.
-func Open(path string, mode os.FileMode, options *Options) (*DB, error) {
-	var db = &DB{opened: true}
-
-	// Set default options if no options are provided.
-	if options == nil {
-		options = DefaultOptions
-	}
-	db.NoGrowSync = options.NoGrowSync
-	db.MmapFlags = options.MmapFlags
-
-	// Set default values for later DB operations.
-	db.MaxBatchSize = DefaultMaxBatchSize
-	db.MaxBatchDelay = DefaultMaxBatchDelay
-	db.AllocSize = DefaultAllocSize
-
-	flag := os.O_RDWR
-	if options.ReadOnly {
-		flag = os.O_RDONLY
-		db.readOnly = true
-	}
-
-	// Open data file and separate sync handler for metadata writes.
-	db.path = path
-	var err error
-	if db.file, err = os.OpenFile(db.path, flag|os.O_CREATE, mode); err != nil {
-		_ = db.close()
-		return nil, err
-	}
-
-	// Lock file so that other processes using Bolt in read-write mode cannot
-	// use the database  at the same time. This would cause corruption since
-	// the two processes would write meta pages and free pages separately.
-	// The database file is locked exclusively (only one process can grab the lock)
-	// if !options.ReadOnly.
-	// The database file is locked using the shared lock (more than one process may
-	// hold a lock at the same time) otherwise (options.ReadOnly is set).
-	if err := flock(db, mode, !db.readOnly, options.Timeout); err != nil {
-		_ = db.close()
-		return nil, err
-	}
-
-	// Default values for test hooks
-	db.ops.writeAt = db.file.WriteAt
-
-	// Initialize the database if it doesn't exist.
-	if info, err := db.file.Stat(); err != nil {
-		return nil, err
-	} else if info.Size() == 0 {
-		// Initialize new files with meta pages.
-		if err := db.init(); err != nil {
-			return nil, err
-		}
-	} else {
-		// Read the first meta page to determine the page size.
-		var buf [0x1000]byte
-		if _, err := db.file.ReadAt(buf[:], 0); err == nil {
-			m := db.pageInBuffer(buf[:], 0).meta()
-			if err := m.validate(); err != nil {
-				// If we can't read the page size, we can assume it's the same
-				// as the OS -- since that's how the page size was chosen in the
-				// first place.
-				//
-				// If the first page is invalid and this OS uses a different
-				// page size than what the database was created with then we
-				// are out of luck and cannot access the database.
-				db.pageSize = os.Getpagesize()
-			} else {
-				db.pageSize = int(m.pageSize)
-			}
-		}
-	}
-
-	// Initialize page pool.
-	db.pagePool = sync.Pool{
-		New: func() interface{} {
-			return make([]byte, db.pageSize)
-		},
-	}
-
-	// Memory map the data file.
-	if err := db.mmap(options.InitialMmapSize); err != nil {
-		_ = db.close()
-		return nil, err
-	}
-
-	// Read in the freelist.
-	db.freelist = newFreelist()
-	db.freelist.read(db.page(db.meta().freelist))
-
-	// Mark the database as opened and return.
-	return db, nil
-}
-
-// mmap opens the underlying memory-mapped file and initializes the meta references.
-// minsz is the minimum size that the new mmap can be.
-func (db *DB) mmap(minsz int) error {
-	db.mmaplock.Lock()
-	defer db.mmaplock.Unlock()
-
-	info, err := db.file.Stat()
-	if err != nil {
-		return fmt.Errorf("mmap stat error: %s", err)
-	} else if int(info.Size()) < db.pageSize*2 {
-		return fmt.Errorf("file size too small")
-	}
-
-	// Ensure the size is at least the minimum size.
-	var size = int(info.Size())
-	if size < minsz {
-		size = minsz
-	}
-	size, err = db.mmapSize(size)
-	if err != nil {
-		return err
-	}
-
-	// Dereference all mmap references before unmapping.
-	if db.rwtx != nil {
-		db.rwtx.root.dereference()
-	}
-
-	// Unmap existing data before continuing.
-	if err := db.munmap(); err != nil {
-		return err
-	}
-
-	// Memory-map the data file as a byte slice.
-	if err := mmap(db, size); err != nil {
-		return err
-	}
-
-	// Save references to the meta pages.
-	db.meta0 = db.page(0).meta()
-	db.meta1 = db.page(1).meta()
-
-	// Validate the meta pages. We only return an error if both meta pages fail
-	// validation, since meta0 failing validation means that it wasn't saved
-	// properly -- but we can recover using meta1. And vice-versa.
-	err0 := db.meta0.validate()
-	err1 := db.meta1.validate()
-	if err0 != nil && err1 != nil {
-		return err0
-	}
-
-	return nil
-}
-
-// munmap unmaps the data file from memory.
-func (db *DB) munmap() error {
-	if err := munmap(db); err != nil {
-		return fmt.Errorf("unmap error: " + err.Error())
-	}
-	return nil
-}
-
-// mmapSize determines the appropriate size for the mmap given the current size
-// of the database. The minimum size is 32KB and doubles until it reaches 1GB.
-// Returns an error if the new mmap size is greater than the max allowed.
-func (db *DB) mmapSize(size int) (int, error) {
-	// Double the size from 32KB until 1GB.
-	for i := uint(15); i <= 30; i++ {
-		if size <= 1<<i {
-			return 1 << i, nil
-		}
-	}
-
-	// Verify the requested size is not above the maximum allowed.
-	if size > maxMapSize {
-		return 0, fmt.Errorf("mmap too large")
-	}
-
-	// If larger than 1GB then grow by 1GB at a time.
-	sz := int64(size)
-	if remainder := sz % int64(maxMmapStep); remainder > 0 {
-		sz += int64(maxMmapStep) - remainder
-	}
-
-	// Ensure that the mmap size is a multiple of the page size.
-	// This should always be true since we're incrementing in MBs.
-	pageSize := int64(db.pageSize)
-	if (sz % pageSize) != 0 {
-		sz = ((sz / pageSize) + 1) * pageSize
-	}
-
-	// If we've exceeded the max size then only grow up to the max size.
-	if sz > maxMapSize {
-		sz = maxMapSize
-	}
-
-	return int(sz), nil
-}
-
-// init creates a new database file and initializes its meta pages.
-func (db *DB) init() error {
-	// Set the page size to the OS page size.
-	db.pageSize = os.Getpagesize()
-
-	// Create two meta pages on a buffer.
-	buf := make([]byte, db.pageSize*4)
-	for i := 0; i < 2; i++ {
-		p := db.pageInBuffer(buf[:], pgid(i))
-		p.id = pgid(i)
-		p.flags = metaPageFlag
-
-		// Initialize the meta page.
-		m := p.meta()
-		m.magic = magic
-		m.version = version
-		m.pageSize = uint32(db.pageSize)
-		m.freelist = 2
-		m.root = bucket{root: 3}
-		m.pgid = 4
-		m.txid = txid(i)
-		m.checksum = m.sum64()
-	}
-
-	// Write an empty freelist at page 3.
-	p := db.pageInBuffer(buf[:], pgid(2))
-	p.id = pgid(2)
-	p.flags = freelistPageFlag
-	p.count = 0
-
-	// Write an empty leaf page at page 4.
-	p = db.pageInBuffer(buf[:], pgid(3))
-	p.id = pgid(3)
-	p.flags = leafPageFlag
-	p.count = 0
-
-	// Write the buffer to our data file.
-	if _, err := db.ops.writeAt(buf, 0); err != nil {
-		return err
-	}
-	if err := fdatasync(db); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-// Close releases all database resources.
-// All transactions must be closed before closing the database.
-func (db *DB) Close() error {
-	db.rwlock.Lock()
-	defer db.rwlock.Unlock()
-
-	db.metalock.Lock()
-	defer db.metalock.Unlock()
-
-	db.mmaplock.RLock()
-	defer db.mmaplock.RUnlock()
-
-	return db.close()
-}
-
-func (db *DB) close() error {
-	if !db.opened {
-		return nil
-	}
-
-	db.opened = false
-
-	db.freelist = nil
-
-	// Clear ops.
-	db.ops.writeAt = nil
-
-	// Close the mmap.
-	if err := db.munmap(); err != nil {
-		return err
-	}
-
-	// Close file handles.
-	if db.file != nil {
-		// No need to unlock read-only file.
-		if !db.readOnly {
-			// Unlock the file.
-			if err := funlock(db); err != nil {
-				log.Printf("bolt.Close(): funlock error: %s", err)
-			}
-		}
-
-		// Close the file descriptor.
-		if err := db.file.Close(); err != nil {
-			return fmt.Errorf("db file close: %s", err)
-		}
-		db.file = nil
-	}
-
-	db.path = ""
-	return nil
-}
-
-// Begin starts a new transaction.
-// Multiple read-only transactions can be used concurrently but only one
-// write transaction can be used at a time. Starting multiple write transactions
-// will cause the calls to block and be serialized until the current write
-// transaction finishes.
-//
-// Transactions should not be dependent on one another. Opening a read
-// transaction and a write transaction in the same goroutine can cause the
-// writer to deadlock because the database periodically needs to re-mmap itself
-// as it grows and it cannot do that while a read transaction is open.
-//
-// If a long running read transaction (for example, a snapshot transaction) is
-// needed, you might want to set DB.InitialMmapSize to a large enough value
-// to avoid potential blocking of write transaction.
-//
-// IMPORTANT: You must close read-only transactions after you are finished or
-// else the database will not reclaim old pages.
-func (db *DB) Begin(writable bool) (*Tx, error) {
-	if writable {
-		return db.beginRWTx()
-	}
-	return db.beginTx()
-}
-
-func (db *DB) beginTx() (*Tx, error) {
-	// Lock the meta pages while we initialize the transaction. We obtain
-	// the meta lock before the mmap lock because that's the order that the
-	// write transaction will obtain them.
-	db.metalock.Lock()
-
-	// Obtain a read-only lock on the mmap. When the mmap is remapped it will
-	// obtain a write lock so all transactions must finish before it can be
-	// remapped.
-	db.mmaplock.RLock()
-
-	// Exit if the database is not open yet.
-	if !db.opened {
-		db.mmaplock.RUnlock()
-		db.metalock.Unlock()
-		return nil, ErrDatabaseNotOpen
-	}
-
-	// Create a transaction associated with the database.
-	t := &Tx{}
-	t.init(db)
-
-	// Keep track of transaction until it closes.
-	db.txs = append(db.txs, t)
-	n := len(db.txs)
-
-	// Unlock the meta pages.
-	db.metalock.Unlock()
-
-	// Update the transaction stats.
-	db.statlock.Lock()
-	db.stats.TxN++
-	db.stats.OpenTxN = n
-	db.statlock.Unlock()
-
-	return t, nil
-}
-
-func (db *DB) beginRWTx() (*Tx, error) {
-	// If the database was opened with Options.ReadOnly, return an error.
-	if db.readOnly {
-		return nil, ErrDatabaseReadOnly
-	}
-
-	// Obtain writer lock. This is released by the transaction when it closes.
-	// This enforces only one writer transaction at a time.
-	db.rwlock.Lock()
-
-	// Once we have the writer lock then we can lock the meta pages so that
-	// we can set up the transaction.
-	db.metalock.Lock()
-	defer db.metalock.Unlock()
-
-	// Exit if the database is not open yet.
-	if !db.opened {
-		db.rwlock.Unlock()
-		return nil, ErrDatabaseNotOpen
-	}
-
-	// Create a transaction associated with the database.
-	t := &Tx{writable: true}
-	t.init(db)
-	db.rwtx = t
-
-	// Free any pages associated with closed read-only transactions.
-	var minid txid = 0xFFFFFFFFFFFFFFFF
-	for _, t := range db.txs {
-		if t.meta.txid < minid {
-			minid = t.meta.txid
-		}
-	}
-	if minid > 0 {
-		db.freelist.release(minid - 1)
-	}
-
-	return t, nil
-}
-
-// removeTx removes a transaction from the database.
-func (db *DB) removeTx(tx *Tx) {
-	// Release the read lock on the mmap.
-	db.mmaplock.RUnlock()
-
-	// Use the meta lock to restrict access to the DB object.
-	db.metalock.Lock()
-
-	// Remove the transaction.
-	for i, t := range db.txs {
-		if t == tx {
-			db.txs = append(db.txs[:i], db.txs[i+1:]...)
-			break
-		}
-	}
-	n := len(db.txs)
-
-	// Unlock the meta pages.
-	db.metalock.Unlock()
-
-	// Merge statistics.
-	db.statlock.Lock()
-	db.stats.OpenTxN = n
-	db.stats.TxStats.add(&tx.stats)
-	db.statlock.Unlock()
-}
-
-// Update executes a function within the context of a read-write managed transaction.
-// If no error is returned from the function then the transaction is committed.
-// If an error is returned then the entire transaction is rolled back.
-// Any error that is returned from the function or returned from the commit is
-// returned from the Update() method.
-//
-// Attempting to manually commit or rollback within the function will cause a panic.
-func (db *DB) Update(fn func(*Tx) error) error {
-	t, err := db.Begin(true)
-	if err != nil {
-		return err
-	}
-
-	// Make sure the transaction rolls back in the event of a panic.
-	defer func() {
-		if t.db != nil {
-			t.rollback()
-		}
-	}()
-
-	// Mark as a managed tx so that the inner function cannot manually commit.
-	t.managed = true
-
-	// If an error is returned from the function then rollback and return error.
-	err = fn(t)
-	t.managed = false
-	if err != nil {
-		_ = t.Rollback()
-		return err
-	}
-
-	return t.Commit()
-}
-
-// View executes a function within the context of a managed read-only transaction.
-// Any error that is returned from the function is returned from the View() method.
-//
-// Attempting to manually rollback within the function will cause a panic.
-func (db *DB) View(fn func(*Tx) error) error {
-	t, err := db.Begin(false)
-	if err != nil {
-		return err
-	}
-
-	// Make sure the transaction rolls back in the event of a panic.
-	defer func() {
-		if t.db != nil {
-			t.rollback()
-		}
-	}()
-
-	// Mark as a managed tx so that the inner function cannot manually rollback.
-	t.managed = true
-
-	// If an error is returned from the function then pass it through.
-	err = fn(t)
-	t.managed = false
-	if err != nil {
-		_ = t.Rollback()
-		return err
-	}
-
-	if err := t.Rollback(); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-// Batch calls fn as part of a batch. It behaves similar to Update,
-// except:
-//
-// 1. concurrent Batch calls can be combined into a single Bolt
-// transaction.
-//
-// 2. the function passed to Batch may be called multiple times,
-// regardless of whether it returns error or not.
-//
-// This means that Batch function side effects must be idempotent and
-// take permanent effect only after a successful return is seen in
-// caller.
-//
-// The maximum batch size and delay can be adjusted with DB.MaxBatchSize
-// and DB.MaxBatchDelay, respectively.
-//
-// Batch is only useful when there are multiple goroutines calling it.
-func (db *DB) Batch(fn func(*Tx) error) error {
-	errCh := make(chan error, 1)
-
-	db.batchMu.Lock()
-	if (db.batch == nil) || (db.batch != nil && len(db.batch.calls) >= db.MaxBatchSize) {
-		// There is no existing batch, or the existing batch is full; start a new one.
-		db.batch = &batch{
-			db: db,
-		}
-		db.batch.timer = time.AfterFunc(db.MaxBatchDelay, db.batch.trigger)
-	}
-	db.batch.calls = append(db.batch.calls, call{fn: fn, err: errCh})
-	if len(db.batch.calls) >= db.MaxBatchSize {
-		// wake up batch, it's ready to run
-		go db.batch.trigger()
-	}
-	db.batchMu.Unlock()
-
-	err := <-errCh
-	if err == trySolo {
-		err = db.Update(fn)
-	}
-	return err
-}
-
-type call struct {
-	fn  func(*Tx) error
-	err chan<- error
-}
-
-type batch struct {
-	db    *DB
-	timer *time.Timer
-	start sync.Once
-	calls []call
-}
-
-// trigger runs the batch if it hasn't already been run.
-func (b *batch) trigger() {
-	b.start.Do(b.run)
-}
-
-// run performs the transactions in the batch and communicates results
-// back to DB.Batch.
-func (b *batch) run() {
-	b.db.batchMu.Lock()
-	b.timer.Stop()
-	// Make sure no new work is added to this batch, but don't break
-	// other batches.
-	if b.db.batch == b {
-		b.db.batch = nil
-	}
-	b.db.batchMu.Unlock()
-
-retry:
-	for len(b.calls) > 0 {
-		var failIdx = -1
-		err := b.db.Update(func(tx *Tx) error {
-			for i, c := range b.calls {
-				if err := safelyCall(c.fn, tx); err != nil {
-					failIdx = i
-					return err
-				}
-			}
-			return nil
-		})
-
-		if failIdx >= 0 {
-			// take the failing transaction out of the batch. it's
-			// safe to shorten b.calls here because db.batch no longer
-			// points to us, and we hold the mutex anyway.
-			c := b.calls[failIdx]
-			b.calls[failIdx], b.calls = b.calls[len(b.calls)-1], b.calls[:len(b.calls)-1]
-			// tell the submitter re-run it solo, continue with the rest of the batch
-			c.err <- trySolo
-			continue retry
-		}
-
-		// pass success, or bolt internal errors, to all callers
-		for _, c := range b.calls {
-			if c.err != nil {
-				c.err <- err
-			}
-		}
-		break retry
-	}
-}
-
-// trySolo is a special sentinel error value used for signaling that a
-// transaction function should be re-run. It should never be seen by
-// callers.
-var trySolo = errors.New("batch function returned an error and should be re-run solo")
-
-type panicked struct {
-	reason interface{}
-}
-
-func (p panicked) Error() string {
-	if err, ok := p.reason.(error); ok {
-		return err.Error()
-	}
-	return fmt.Sprintf("panic: %v", p.reason)
-}
-
-func safelyCall(fn func(*Tx) error, tx *Tx) (err error) {
-	defer func() {
-		if p := recover(); p != nil {
-			err = panicked{p}
-		}
-	}()
-	return fn(tx)
-}
-
-// Sync executes fdatasync() against the database file handle.
-//
-// This is not necessary under normal operation, however, if you use NoSync
-// then it allows you to force the database file to sync against the disk.
-func (db *DB) Sync() error { return fdatasync(db) }
-
-// Stats retrieves ongoing performance stats for the database.
-// This is only updated when a transaction closes.
-func (db *DB) Stats() Stats {
-	db.statlock.RLock()
-	defer db.statlock.RUnlock()
-	return db.stats
-}
-
-// This is for internal access to the raw data bytes from the C cursor, use
-// carefully, or not at all.
-func (db *DB) Info() *Info {
-	return &Info{uintptr(unsafe.Pointer(&db.data[0])), db.pageSize}
-}
-
-// page retrieves a page reference from the mmap based on the current page size.
-func (db *DB) page(id pgid) *page {
-	pos := id * pgid(db.pageSize)
-	return (*page)(unsafe.Pointer(&db.data[pos]))
-}
-
-// pageInBuffer retrieves a page reference from a given byte array based on the current page size.
-func (db *DB) pageInBuffer(b []byte, id pgid) *page {
-	return (*page)(unsafe.Pointer(&b[id*pgid(db.pageSize)]))
-}
-
-// meta retrieves the current meta page reference.
-func (db *DB) meta() *meta {
-	// We have to return the meta with the highest txid which doesn't fail
-	// validation. Otherwise, we can cause errors when in fact the database is
-	// in a consistent state. metaA is the one with the higher txid.
-	metaA := db.meta0
-	metaB := db.meta1
-	if db.meta1.txid > db.meta0.txid {
-		metaA = db.meta1
-		metaB = db.meta0
-	}
-
-	// Use higher meta page if valid. Otherwise fallback to previous, if valid.
-	if err := metaA.validate(); err == nil {
-		return metaA
-	} else if err := metaB.validate(); err == nil {
-		return metaB
-	}
-
-	// This should never be reached, because both meta1 and meta0 were validated
-	// on mmap() and we do fsync() on every write.
-	panic("bolt.DB.meta(): invalid meta pages")
-}
-
-// allocate returns a contiguous block of memory starting at a given page.
-func (db *DB) allocate(count int) (*page, error) {
-	// Allocate a temporary buffer for the page.
-	var buf []byte
-	if count == 1 {
-		buf = db.pagePool.Get().([]byte)
-	} else {
-		buf = make([]byte, count*db.pageSize)
-	}
-	p := (*page)(unsafe.Pointer(&buf[0]))
-	p.overflow = uint32(count - 1)
-
-	// Use pages from the freelist if they are available.
-	if p.id = db.freelist.allocate(count); p.id != 0 {
-		return p, nil
-	}
-
-	// Resize mmap() if we're at the end.
-	p.id = db.rwtx.meta.pgid
-	var minsz = int((p.id+pgid(count))+1) * db.pageSize
-	if minsz >= db.datasz {
-		if err := db.mmap(minsz); err != nil {
-			return nil, fmt.Errorf("mmap allocate error: %s", err)
-		}
-	}
-
-	// Move the page id high water mark.
-	db.rwtx.meta.pgid += pgid(count)
-
-	return p, nil
-}
-
-// grow grows the size of the database to the given sz.
-func (db *DB) grow(sz int) error {
-	// Ignore if the new size is less than available file size.
-	if sz <= db.filesz {
-		return nil
-	}
-
-	// If the data is smaller than the alloc size then only allocate what's needed.
-	// Once it goes over the allocation size then allocate in chunks.
-	if db.datasz < db.AllocSize {
-		sz = db.datasz
-	} else {
-		sz += db.AllocSize
-	}
-
-	// Truncate and fsync to ensure file size metadata is flushed.
-	// https://github.com/boltdb/bolt/issues/284
-	if !db.NoGrowSync && !db.readOnly {
-		if runtime.GOOS != "windows" {
-			if err := db.file.Truncate(int64(sz)); err != nil {
-				return fmt.Errorf("file resize error: %s", err)
-			}
-		}
-		if err := db.file.Sync(); err != nil {
-			return fmt.Errorf("file sync error: %s", err)
-		}
-	}
-
-	db.filesz = sz
-	return nil
-}
-
-func (db *DB) IsReadOnly() bool {
-	return db.readOnly
-}
-
-// Options represents the options that can be set when opening a database.
-type Options struct {
-	// Timeout is the amount of time to wait to obtain a file lock.
-	// When set to zero it will wait indefinitely. This option is only
-	// available on Darwin and Linux.
-	Timeout time.Duration
-
-	// Sets the DB.NoGrowSync flag before memory mapping the file.
-	NoGrowSync bool
-
-	// Open database in read-only mode. Uses flock(..., LOCK_SH |LOCK_NB) to
-	// grab a shared lock (UNIX).
-	ReadOnly bool
-
-	// Sets the DB.MmapFlags flag before memory mapping the file.
-	MmapFlags int
-
-	// InitialMmapSize is the initial mmap size of the database
-	// in bytes. Read transactions won't block write transaction
-	// if the InitialMmapSize is large enough to hold database mmap
-	// size. (See DB.Begin for more information)
-	//
-	// If <=0, the initial map size is 0.
-	// If initialMmapSize is smaller than the previous database size,
-	// it takes no effect.
-	InitialMmapSize int
-}
-
-// DefaultOptions represent the options used if nil options are passed into Open().
-// No timeout is used which will cause Bolt to wait indefinitely for a lock.
-var DefaultOptions = &Options{
-	Timeout:    0,
-	NoGrowSync: false,
-}
-
-// Stats represents statistics about the database.
-type Stats struct {
-	// Freelist stats
-	FreePageN     int // total number of free pages on the freelist
-	PendingPageN  int // total number of pending pages on the freelist
-	FreeAlloc     int // total bytes allocated in free pages
-	FreelistInuse int // total bytes used by the freelist
-
-	// Transaction stats
-	TxN     int // total number of started read transactions
-	OpenTxN int // number of currently open read transactions
-
-	TxStats TxStats // global, ongoing stats.
-}
-
-// Sub calculates and returns the difference between two sets of database stats.
-// This is useful when obtaining stats at two different points and time and
-// you need the performance counters that occurred within that time span.
-func (s *Stats) Sub(other *Stats) Stats {
-	if other == nil {
-		return *s
-	}
-	var diff Stats
-	diff.FreePageN = s.FreePageN
-	diff.PendingPageN = s.PendingPageN
-	diff.FreeAlloc = s.FreeAlloc
-	diff.FreelistInuse = s.FreelistInuse
-	diff.TxN = other.TxN - s.TxN
-	diff.TxStats = s.TxStats.Sub(&other.TxStats)
-	return diff
-}
-
-func (s *Stats) add(other *Stats) {
-	s.TxStats.add(&other.TxStats)
-}
-
-type Info struct {
-	Data     uintptr
-	PageSize int
-}
-
-type meta struct {
-	magic    uint32
-	version  uint32
-	pageSize uint32
-	flags    uint32
-	root     bucket
-	freelist pgid
-	pgid     pgid
-	txid     txid
-	checksum uint64
-}
-
-// validate checks the marker bytes and version of the meta page to ensure it matches this binary.
-func (m *meta) validate() error {
-	if m.magic != magic {
-		return ErrInvalid
-	} else if m.version != version {
-		return ErrVersionMismatch
-	} else if m.checksum != 0 && m.checksum != m.sum64() {
-		return ErrChecksum
-	}
-	return nil
-}
-
-// copy copies one meta object to another.
-func (m *meta) copy(dest *meta) {
-	*dest = *m
-}
-
-// write writes the meta onto a page.
-func (m *meta) write(p *page) {
-	if m.root.root >= m.pgid {
-		panic(fmt.Sprintf("root bucket pgid (%d) above high water mark (%d)", m.root.root, m.pgid))
-	} else if m.freelist >= m.pgid {
-		panic(fmt.Sprintf("freelist pgid (%d) above high water mark (%d)", m.freelist, m.pgid))
-	}
-
-	// Page id is either going to be 0 or 1 which we can determine by the transaction ID.
-	p.id = pgid(m.txid % 2)
-	p.flags |= metaPageFlag
-
-	// Calculate the checksum.
-	m.checksum = m.sum64()
-
-	m.copy(p.meta())
-}
-
-// generates the checksum for the meta.
-func (m *meta) sum64() uint64 {
-	var h = fnv.New64a()
-	_, _ = h.Write((*[unsafe.Offsetof(meta{}.checksum)]byte)(unsafe.Pointer(m))[:])
-	return h.Sum64()
-}
-
-// _assert will panic with a given formatted message if the given condition is false.
-func _assert(condition bool, msg string, v ...interface{}) {
-	if !condition {
-		panic(fmt.Sprintf("assertion failed: "+msg, v...))
-	}
-}
-
-func warn(v ...interface{})              { fmt.Fprintln(os.Stderr, v...) }
-func warnf(msg string, v ...interface{}) { fmt.Fprintf(os.Stderr, msg+"\n", v...) }
-
-func printstack() {
-	stack := strings.Join(strings.Split(string(debug.Stack()), "\n")[2:], "\n")
-	fmt.Fprintln(os.Stderr, stack)
-}
diff --git a/vendor/github.com/coreos/bbolt/doc.go b/vendor/github.com/coreos/bbolt/doc.go
deleted file mode 100644
index cc93784..0000000
--- a/vendor/github.com/coreos/bbolt/doc.go
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-Package bolt implements a low-level key/value store in pure Go. It supports
-fully serializable transactions, ACID semantics, and lock-free MVCC with
-multiple readers and a single writer. Bolt can be used for projects that
-want a simple data store without the need to add large dependencies such as
-Postgres or MySQL.
-
-Bolt is a single-level, zero-copy, B+tree data store. This means that Bolt is
-optimized for fast read access and does not require recovery in the event of a
-system crash. Transactions which have not finished committing will simply be
-rolled back in the event of a crash.
-
-The design of Bolt is based on Howard Chu's LMDB database project.
-
-Bolt currently works on Windows, Mac OS X, and Linux.
-
-
-Basics
-
-There are only a few types in Bolt: DB, Bucket, Tx, and Cursor. The DB is
-a collection of buckets and is represented by a single file on disk. A bucket is
-a collection of unique keys that are associated with values.
-
-Transactions provide either read-only or read-write access to the database.
-Read-only transactions can retrieve key/value pairs and can use Cursors to
-iterate over the dataset sequentially. Read-write transactions can create and
-delete buckets and can insert and remove keys. Only one read-write transaction
-is allowed at a time.
-
-
-Caveats
-
-The database uses a read-only, memory-mapped data file to ensure that
-applications cannot corrupt the database, however, this means that keys and
-values returned from Bolt cannot be changed. Writing to a read-only byte slice
-will cause Go to panic.
-
-Keys and values retrieved from the database are only valid for the life of
-the transaction. When used outside the transaction, these byte slices can
-point to different data or can point to invalid memory which will cause a panic.
-
-
-*/
-package bolt
diff --git a/vendor/github.com/coreos/bbolt/errors.go b/vendor/github.com/coreos/bbolt/errors.go
deleted file mode 100644
index a3620a3..0000000
--- a/vendor/github.com/coreos/bbolt/errors.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package bolt
-
-import "errors"
-
-// These errors can be returned when opening or calling methods on a DB.
-var (
-	// ErrDatabaseNotOpen is returned when a DB instance is accessed before it
-	// is opened or after it is closed.
-	ErrDatabaseNotOpen = errors.New("database not open")
-
-	// ErrDatabaseOpen is returned when opening a database that is
-	// already open.
-	ErrDatabaseOpen = errors.New("database already open")
-
-	// ErrInvalid is returned when both meta pages on a database are invalid.
-	// This typically occurs when a file is not a bolt database.
-	ErrInvalid = errors.New("invalid database")
-
-	// ErrVersionMismatch is returned when the data file was created with a
-	// different version of Bolt.
-	ErrVersionMismatch = errors.New("version mismatch")
-
-	// ErrChecksum is returned when either meta page checksum does not match.
-	ErrChecksum = errors.New("checksum error")
-
-	// ErrTimeout is returned when a database cannot obtain an exclusive lock
-	// on the data file after the timeout passed to Open().
-	ErrTimeout = errors.New("timeout")
-)
-
-// These errors can occur when beginning or committing a Tx.
-var (
-	// ErrTxNotWritable is returned when performing a write operation on a
-	// read-only transaction.
-	ErrTxNotWritable = errors.New("tx not writable")
-
-	// ErrTxClosed is returned when committing or rolling back a transaction
-	// that has already been committed or rolled back.
-	ErrTxClosed = errors.New("tx closed")
-
-	// ErrDatabaseReadOnly is returned when a mutating transaction is started on a
-	// read-only database.
-	ErrDatabaseReadOnly = errors.New("database is in read-only mode")
-)
-
-// These errors can occur when putting or deleting a value or a bucket.
-var (
-	// ErrBucketNotFound is returned when trying to access a bucket that has
-	// not been created yet.
-	ErrBucketNotFound = errors.New("bucket not found")
-
-	// ErrBucketExists is returned when creating a bucket that already exists.
-	ErrBucketExists = errors.New("bucket already exists")
-
-	// ErrBucketNameRequired is returned when creating a bucket with a blank name.
-	ErrBucketNameRequired = errors.New("bucket name required")
-
-	// ErrKeyRequired is returned when inserting a zero-length key.
-	ErrKeyRequired = errors.New("key required")
-
-	// ErrKeyTooLarge is returned when inserting a key that is larger than MaxKeySize.
-	ErrKeyTooLarge = errors.New("key too large")
-
-	// ErrValueTooLarge is returned when inserting a value that is larger than MaxValueSize.
-	ErrValueTooLarge = errors.New("value too large")
-
-	// ErrIncompatibleValue is returned when trying create or delete a bucket
-	// on an existing non-bucket key or when trying to create or delete a
-	// non-bucket key on an existing bucket key.
-	ErrIncompatibleValue = errors.New("incompatible value")
-)
diff --git a/vendor/github.com/coreos/bbolt/freelist.go b/vendor/github.com/coreos/bbolt/freelist.go
deleted file mode 100644
index 1b7ba91..0000000
--- a/vendor/github.com/coreos/bbolt/freelist.go
+++ /dev/null
@@ -1,248 +0,0 @@
-package bolt
-
-import (
-	"fmt"
-	"sort"
-	"unsafe"
-)
-
-// freelist represents a list of all pages that are available for allocation.
-// It also tracks pages that have been freed but are still in use by open transactions.
-type freelist struct {
-	ids     []pgid          // all free and available free page ids.
-	pending map[txid][]pgid // mapping of soon-to-be free page ids by tx.
-	cache   map[pgid]bool   // fast lookup of all free and pending page ids.
-}
-
-// newFreelist returns an empty, initialized freelist.
-func newFreelist() *freelist {
-	return &freelist{
-		pending: make(map[txid][]pgid),
-		cache:   make(map[pgid]bool),
-	}
-}
-
-// size returns the size of the page after serialization.
-func (f *freelist) size() int {
-	return pageHeaderSize + (int(unsafe.Sizeof(pgid(0))) * f.count())
-}
-
-// count returns count of pages on the freelist
-func (f *freelist) count() int {
-	return f.free_count() + f.pending_count()
-}
-
-// free_count returns count of free pages
-func (f *freelist) free_count() int {
-	return len(f.ids)
-}
-
-// pending_count returns count of pending pages
-func (f *freelist) pending_count() int {
-	var count int
-	for _, list := range f.pending {
-		count += len(list)
-	}
-	return count
-}
-
-// all returns a list of all free ids and all pending ids in one sorted list.
-func (f *freelist) all() []pgid {
-	m := make(pgids, 0)
-
-	for _, list := range f.pending {
-		m = append(m, list...)
-	}
-
-	sort.Sort(m)
-	return pgids(f.ids).merge(m)
-}
-
-// allocate returns the starting page id of a contiguous list of pages of a given size.
-// If a contiguous block cannot be found then 0 is returned.
-func (f *freelist) allocate(n int) pgid {
-	if len(f.ids) == 0 {
-		return 0
-	}
-
-	var initial, previd pgid
-	for i, id := range f.ids {
-		if id <= 1 {
-			panic(fmt.Sprintf("invalid page allocation: %d", id))
-		}
-
-		// Reset initial page if this is not contiguous.
-		if previd == 0 || id-previd != 1 {
-			initial = id
-		}
-
-		// If we found a contiguous block then remove it and return it.
-		if (id-initial)+1 == pgid(n) {
-			// If we're allocating off the beginning then take the fast path
-			// and just adjust the existing slice. This will use extra memory
-			// temporarily but the append() in free() will realloc the slice
-			// as is necessary.
-			if (i + 1) == n {
-				f.ids = f.ids[i+1:]
-			} else {
-				copy(f.ids[i-n+1:], f.ids[i+1:])
-				f.ids = f.ids[:len(f.ids)-n]
-			}
-
-			// Remove from the free cache.
-			for i := pgid(0); i < pgid(n); i++ {
-				delete(f.cache, initial+i)
-			}
-
-			return initial
-		}
-
-		previd = id
-	}
-	return 0
-}
-
-// free releases a page and its overflow for a given transaction id.
-// If the page is already free then a panic will occur.
-func (f *freelist) free(txid txid, p *page) {
-	if p.id <= 1 {
-		panic(fmt.Sprintf("cannot free page 0 or 1: %d", p.id))
-	}
-
-	// Free page and all its overflow pages.
-	var ids = f.pending[txid]
-	for id := p.id; id <= p.id+pgid(p.overflow); id++ {
-		// Verify that page is not already free.
-		if f.cache[id] {
-			panic(fmt.Sprintf("page %d already freed", id))
-		}
-
-		// Add to the freelist and cache.
-		ids = append(ids, id)
-		f.cache[id] = true
-	}
-	f.pending[txid] = ids
-}
-
-// release moves all page ids for a transaction id (or older) to the freelist.
-func (f *freelist) release(txid txid) {
-	m := make(pgids, 0)
-	for tid, ids := range f.pending {
-		if tid <= txid {
-			// Move transaction's pending pages to the available freelist.
-			// Don't remove from the cache since the page is still free.
-			m = append(m, ids...)
-			delete(f.pending, tid)
-		}
-	}
-	sort.Sort(m)
-	f.ids = pgids(f.ids).merge(m)
-}
-
-// rollback removes the pages from a given pending tx.
-func (f *freelist) rollback(txid txid) {
-	// Remove page ids from cache.
-	for _, id := range f.pending[txid] {
-		delete(f.cache, id)
-	}
-
-	// Remove pages from pending list.
-	delete(f.pending, txid)
-}
-
-// freed returns whether a given page is in the free list.
-func (f *freelist) freed(pgid pgid) bool {
-	return f.cache[pgid]
-}
-
-// read initializes the freelist from a freelist page.
-func (f *freelist) read(p *page) {
-	// If the page.count is at the max uint16 value (64k) then it's considered
-	// an overflow and the size of the freelist is stored as the first element.
-	idx, count := 0, int(p.count)
-	if count == 0xFFFF {
-		idx = 1
-		count = int(((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[0])
-	}
-
-	// Copy the list of page ids from the freelist.
-	if count == 0 {
-		f.ids = nil
-	} else {
-		ids := ((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[idx:count]
-		f.ids = make([]pgid, len(ids))
-		copy(f.ids, ids)
-
-		// Make sure they're sorted.
-		sort.Sort(pgids(f.ids))
-	}
-
-	// Rebuild the page cache.
-	f.reindex()
-}
-
-// write writes the page ids onto a freelist page. All free and pending ids are
-// saved to disk since in the event of a program crash, all pending ids will
-// become free.
-func (f *freelist) write(p *page) error {
-	// Combine the old free pgids and pgids waiting on an open transaction.
-	ids := f.all()
-
-	// Update the header flag.
-	p.flags |= freelistPageFlag
-
-	// The page.count can only hold up to 64k elements so if we overflow that
-	// number then we handle it by putting the size in the first element.
-	if len(ids) == 0 {
-		p.count = uint16(len(ids))
-	} else if len(ids) < 0xFFFF {
-		p.count = uint16(len(ids))
-		copy(((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[:], ids)
-	} else {
-		p.count = 0xFFFF
-		((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[0] = pgid(len(ids))
-		copy(((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[1:], ids)
-	}
-
-	return nil
-}
-
-// reload reads the freelist from a page and filters out pending items.
-func (f *freelist) reload(p *page) {
-	f.read(p)
-
-	// Build a cache of only pending pages.
-	pcache := make(map[pgid]bool)
-	for _, pendingIDs := range f.pending {
-		for _, pendingID := range pendingIDs {
-			pcache[pendingID] = true
-		}
-	}
-
-	// Check each page in the freelist and build a new available freelist
-	// with any pages not in the pending lists.
-	var a []pgid
-	for _, id := range f.ids {
-		if !pcache[id] {
-			a = append(a, id)
-		}
-	}
-	f.ids = a
-
-	// Once the available list is rebuilt then rebuild the free cache so that
-	// it includes the available and pending free pages.
-	f.reindex()
-}
-
-// reindex rebuilds the free cache based on available and pending free lists.
-func (f *freelist) reindex() {
-	f.cache = make(map[pgid]bool)
-	for _, id := range f.ids {
-		f.cache[id] = true
-	}
-	for _, pendingIDs := range f.pending {
-		for _, pendingID := range pendingIDs {
-			f.cache[pendingID] = true
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/bbolt/node.go b/vendor/github.com/coreos/bbolt/node.go
deleted file mode 100644
index 159318b..0000000
--- a/vendor/github.com/coreos/bbolt/node.go
+++ /dev/null
@@ -1,604 +0,0 @@
-package bolt
-
-import (
-	"bytes"
-	"fmt"
-	"sort"
-	"unsafe"
-)
-
-// node represents an in-memory, deserialized page.
-type node struct {
-	bucket     *Bucket
-	isLeaf     bool
-	unbalanced bool
-	spilled    bool
-	key        []byte
-	pgid       pgid
-	parent     *node
-	children   nodes
-	inodes     inodes
-}
-
-// root returns the top-level node this node is attached to.
-func (n *node) root() *node {
-	if n.parent == nil {
-		return n
-	}
-	return n.parent.root()
-}
-
-// minKeys returns the minimum number of inodes this node should have.
-func (n *node) minKeys() int {
-	if n.isLeaf {
-		return 1
-	}
-	return 2
-}
-
-// size returns the size of the node after serialization.
-func (n *node) size() int {
-	sz, elsz := pageHeaderSize, n.pageElementSize()
-	for i := 0; i < len(n.inodes); i++ {
-		item := &n.inodes[i]
-		sz += elsz + len(item.key) + len(item.value)
-	}
-	return sz
-}
-
-// sizeLessThan returns true if the node is less than a given size.
-// This is an optimization to avoid calculating a large node when we only need
-// to know if it fits inside a certain page size.
-func (n *node) sizeLessThan(v int) bool {
-	sz, elsz := pageHeaderSize, n.pageElementSize()
-	for i := 0; i < len(n.inodes); i++ {
-		item := &n.inodes[i]
-		sz += elsz + len(item.key) + len(item.value)
-		if sz >= v {
-			return false
-		}
-	}
-	return true
-}
-
-// pageElementSize returns the size of each page element based on the type of node.
-func (n *node) pageElementSize() int {
-	if n.isLeaf {
-		return leafPageElementSize
-	}
-	return branchPageElementSize
-}
-
-// childAt returns the child node at a given index.
-func (n *node) childAt(index int) *node {
-	if n.isLeaf {
-		panic(fmt.Sprintf("invalid childAt(%d) on a leaf node", index))
-	}
-	return n.bucket.node(n.inodes[index].pgid, n)
-}
-
-// childIndex returns the index of a given child node.
-func (n *node) childIndex(child *node) int {
-	index := sort.Search(len(n.inodes), func(i int) bool { return bytes.Compare(n.inodes[i].key, child.key) != -1 })
-	return index
-}
-
-// numChildren returns the number of children.
-func (n *node) numChildren() int {
-	return len(n.inodes)
-}
-
-// nextSibling returns the next node with the same parent.
-func (n *node) nextSibling() *node {
-	if n.parent == nil {
-		return nil
-	}
-	index := n.parent.childIndex(n)
-	if index >= n.parent.numChildren()-1 {
-		return nil
-	}
-	return n.parent.childAt(index + 1)
-}
-
-// prevSibling returns the previous node with the same parent.
-func (n *node) prevSibling() *node {
-	if n.parent == nil {
-		return nil
-	}
-	index := n.parent.childIndex(n)
-	if index == 0 {
-		return nil
-	}
-	return n.parent.childAt(index - 1)
-}
-
-// put inserts a key/value.
-func (n *node) put(oldKey, newKey, value []byte, pgid pgid, flags uint32) {
-	if pgid >= n.bucket.tx.meta.pgid {
-		panic(fmt.Sprintf("pgid (%d) above high water mark (%d)", pgid, n.bucket.tx.meta.pgid))
-	} else if len(oldKey) <= 0 {
-		panic("put: zero-length old key")
-	} else if len(newKey) <= 0 {
-		panic("put: zero-length new key")
-	}
-
-	// Find insertion index.
-	index := sort.Search(len(n.inodes), func(i int) bool { return bytes.Compare(n.inodes[i].key, oldKey) != -1 })
-
-	// Add capacity and shift nodes if we don't have an exact match and need to insert.
-	exact := (len(n.inodes) > 0 && index < len(n.inodes) && bytes.Equal(n.inodes[index].key, oldKey))
-	if !exact {
-		n.inodes = append(n.inodes, inode{})
-		copy(n.inodes[index+1:], n.inodes[index:])
-	}
-
-	inode := &n.inodes[index]
-	inode.flags = flags
-	inode.key = newKey
-	inode.value = value
-	inode.pgid = pgid
-	_assert(len(inode.key) > 0, "put: zero-length inode key")
-}
-
-// del removes a key from the node.
-func (n *node) del(key []byte) {
-	// Find index of key.
-	index := sort.Search(len(n.inodes), func(i int) bool { return bytes.Compare(n.inodes[i].key, key) != -1 })
-
-	// Exit if the key isn't found.
-	if index >= len(n.inodes) || !bytes.Equal(n.inodes[index].key, key) {
-		return
-	}
-
-	// Delete inode from the node.
-	n.inodes = append(n.inodes[:index], n.inodes[index+1:]...)
-
-	// Mark the node as needing rebalancing.
-	n.unbalanced = true
-}
-
-// read initializes the node from a page.
-func (n *node) read(p *page) {
-	n.pgid = p.id
-	n.isLeaf = ((p.flags & leafPageFlag) != 0)
-	n.inodes = make(inodes, int(p.count))
-
-	for i := 0; i < int(p.count); i++ {
-		inode := &n.inodes[i]
-		if n.isLeaf {
-			elem := p.leafPageElement(uint16(i))
-			inode.flags = elem.flags
-			inode.key = elem.key()
-			inode.value = elem.value()
-		} else {
-			elem := p.branchPageElement(uint16(i))
-			inode.pgid = elem.pgid
-			inode.key = elem.key()
-		}
-		_assert(len(inode.key) > 0, "read: zero-length inode key")
-	}
-
-	// Save first key so we can find the node in the parent when we spill.
-	if len(n.inodes) > 0 {
-		n.key = n.inodes[0].key
-		_assert(len(n.key) > 0, "read: zero-length node key")
-	} else {
-		n.key = nil
-	}
-}
-
-// write writes the items onto one or more pages.
-func (n *node) write(p *page) {
-	// Initialize page.
-	if n.isLeaf {
-		p.flags |= leafPageFlag
-	} else {
-		p.flags |= branchPageFlag
-	}
-
-	if len(n.inodes) >= 0xFFFF {
-		panic(fmt.Sprintf("inode overflow: %d (pgid=%d)", len(n.inodes), p.id))
-	}
-	p.count = uint16(len(n.inodes))
-
-	// Stop here if there are no items to write.
-	if p.count == 0 {
-		return
-	}
-
-	// Loop over each item and write it to the page.
-	b := (*[maxAllocSize]byte)(unsafe.Pointer(&p.ptr))[n.pageElementSize()*len(n.inodes):]
-	for i, item := range n.inodes {
-		_assert(len(item.key) > 0, "write: zero-length inode key")
-
-		// Write the page element.
-		if n.isLeaf {
-			elem := p.leafPageElement(uint16(i))
-			elem.pos = uint32(uintptr(unsafe.Pointer(&b[0])) - uintptr(unsafe.Pointer(elem)))
-			elem.flags = item.flags
-			elem.ksize = uint32(len(item.key))
-			elem.vsize = uint32(len(item.value))
-		} else {
-			elem := p.branchPageElement(uint16(i))
-			elem.pos = uint32(uintptr(unsafe.Pointer(&b[0])) - uintptr(unsafe.Pointer(elem)))
-			elem.ksize = uint32(len(item.key))
-			elem.pgid = item.pgid
-			_assert(elem.pgid != p.id, "write: circular dependency occurred")
-		}
-
-		// If the length of key+value is larger than the max allocation size
-		// then we need to reallocate the byte array pointer.
-		//
-		// See: https://github.com/boltdb/bolt/pull/335
-		klen, vlen := len(item.key), len(item.value)
-		if len(b) < klen+vlen {
-			b = (*[maxAllocSize]byte)(unsafe.Pointer(&b[0]))[:]
-		}
-
-		// Write data for the element to the end of the page.
-		copy(b[0:], item.key)
-		b = b[klen:]
-		copy(b[0:], item.value)
-		b = b[vlen:]
-	}
-
-	// DEBUG ONLY: n.dump()
-}
-
-// split breaks up a node into multiple smaller nodes, if appropriate.
-// This should only be called from the spill() function.
-func (n *node) split(pageSize int) []*node {
-	var nodes []*node
-
-	node := n
-	for {
-		// Split node into two.
-		a, b := node.splitTwo(pageSize)
-		nodes = append(nodes, a)
-
-		// If we can't split then exit the loop.
-		if b == nil {
-			break
-		}
-
-		// Set node to b so it gets split on the next iteration.
-		node = b
-	}
-
-	return nodes
-}
-
-// splitTwo breaks up a node into two smaller nodes, if appropriate.
-// This should only be called from the split() function.
-func (n *node) splitTwo(pageSize int) (*node, *node) {
-	// Ignore the split if the page doesn't have at least enough nodes for
-	// two pages or if the nodes can fit in a single page.
-	if len(n.inodes) <= (minKeysPerPage*2) || n.sizeLessThan(pageSize) {
-		return n, nil
-	}
-
-	// Determine the threshold before starting a new node.
-	var fillPercent = n.bucket.FillPercent
-	if fillPercent < minFillPercent {
-		fillPercent = minFillPercent
-	} else if fillPercent > maxFillPercent {
-		fillPercent = maxFillPercent
-	}
-	threshold := int(float64(pageSize) * fillPercent)
-
-	// Determine split position and sizes of the two pages.
-	splitIndex, _ := n.splitIndex(threshold)
-
-	// Split node into two separate nodes.
-	// If there's no parent then we'll need to create one.
-	if n.parent == nil {
-		n.parent = &node{bucket: n.bucket, children: []*node{n}}
-	}
-
-	// Create a new node and add it to the parent.
-	next := &node{bucket: n.bucket, isLeaf: n.isLeaf, parent: n.parent}
-	n.parent.children = append(n.parent.children, next)
-
-	// Split inodes across two nodes.
-	next.inodes = n.inodes[splitIndex:]
-	n.inodes = n.inodes[:splitIndex]
-
-	// Update the statistics.
-	n.bucket.tx.stats.Split++
-
-	return n, next
-}
-
-// splitIndex finds the position where a page will fill a given threshold.
-// It returns the index as well as the size of the first page.
-// This is only be called from split().
-func (n *node) splitIndex(threshold int) (index, sz int) {
-	sz = pageHeaderSize
-
-	// Loop until we only have the minimum number of keys required for the second page.
-	for i := 0; i < len(n.inodes)-minKeysPerPage; i++ {
-		index = i
-		inode := n.inodes[i]
-		elsize := n.pageElementSize() + len(inode.key) + len(inode.value)
-
-		// If we have at least the minimum number of keys and adding another
-		// node would put us over the threshold then exit and return.
-		if i >= minKeysPerPage && sz+elsize > threshold {
-			break
-		}
-
-		// Add the element size to the total size.
-		sz += elsize
-	}
-
-	return
-}
-
-// spill writes the nodes to dirty pages and splits nodes as it goes.
-// Returns an error if dirty pages cannot be allocated.
-func (n *node) spill() error {
-	var tx = n.bucket.tx
-	if n.spilled {
-		return nil
-	}
-
-	// Spill child nodes first. Child nodes can materialize sibling nodes in
-	// the case of split-merge so we cannot use a range loop. We have to check
-	// the children size on every loop iteration.
-	sort.Sort(n.children)
-	for i := 0; i < len(n.children); i++ {
-		if err := n.children[i].spill(); err != nil {
-			return err
-		}
-	}
-
-	// We no longer need the child list because it's only used for spill tracking.
-	n.children = nil
-
-	// Split nodes into appropriate sizes. The first node will always be n.
-	var nodes = n.split(tx.db.pageSize)
-	for _, node := range nodes {
-		// Add node's page to the freelist if it's not new.
-		if node.pgid > 0 {
-			tx.db.freelist.free(tx.meta.txid, tx.page(node.pgid))
-			node.pgid = 0
-		}
-
-		// Allocate contiguous space for the node.
-		p, err := tx.allocate((node.size() / tx.db.pageSize) + 1)
-		if err != nil {
-			return err
-		}
-
-		// Write the node.
-		if p.id >= tx.meta.pgid {
-			panic(fmt.Sprintf("pgid (%d) above high water mark (%d)", p.id, tx.meta.pgid))
-		}
-		node.pgid = p.id
-		node.write(p)
-		node.spilled = true
-
-		// Insert into parent inodes.
-		if node.parent != nil {
-			var key = node.key
-			if key == nil {
-				key = node.inodes[0].key
-			}
-
-			node.parent.put(key, node.inodes[0].key, nil, node.pgid, 0)
-			node.key = node.inodes[0].key
-			_assert(len(node.key) > 0, "spill: zero-length node key")
-		}
-
-		// Update the statistics.
-		tx.stats.Spill++
-	}
-
-	// If the root node split and created a new root then we need to spill that
-	// as well. We'll clear out the children to make sure it doesn't try to respill.
-	if n.parent != nil && n.parent.pgid == 0 {
-		n.children = nil
-		return n.parent.spill()
-	}
-
-	return nil
-}
-
-// rebalance attempts to combine the node with sibling nodes if the node fill
-// size is below a threshold or if there are not enough keys.
-func (n *node) rebalance() {
-	if !n.unbalanced {
-		return
-	}
-	n.unbalanced = false
-
-	// Update statistics.
-	n.bucket.tx.stats.Rebalance++
-
-	// Ignore if node is above threshold (25%) and has enough keys.
-	var threshold = n.bucket.tx.db.pageSize / 4
-	if n.size() > threshold && len(n.inodes) > n.minKeys() {
-		return
-	}
-
-	// Root node has special handling.
-	if n.parent == nil {
-		// If root node is a branch and only has one node then collapse it.
-		if !n.isLeaf && len(n.inodes) == 1 {
-			// Move root's child up.
-			child := n.bucket.node(n.inodes[0].pgid, n)
-			n.isLeaf = child.isLeaf
-			n.inodes = child.inodes[:]
-			n.children = child.children
-
-			// Reparent all child nodes being moved.
-			for _, inode := range n.inodes {
-				if child, ok := n.bucket.nodes[inode.pgid]; ok {
-					child.parent = n
-				}
-			}
-
-			// Remove old child.
-			child.parent = nil
-			delete(n.bucket.nodes, child.pgid)
-			child.free()
-		}
-
-		return
-	}
-
-	// If node has no keys then just remove it.
-	if n.numChildren() == 0 {
-		n.parent.del(n.key)
-		n.parent.removeChild(n)
-		delete(n.bucket.nodes, n.pgid)
-		n.free()
-		n.parent.rebalance()
-		return
-	}
-
-	_assert(n.parent.numChildren() > 1, "parent must have at least 2 children")
-
-	// Destination node is right sibling if idx == 0, otherwise left sibling.
-	var target *node
-	var useNextSibling = (n.parent.childIndex(n) == 0)
-	if useNextSibling {
-		target = n.nextSibling()
-	} else {
-		target = n.prevSibling()
-	}
-
-	// If both this node and the target node are too small then merge them.
-	if useNextSibling {
-		// Reparent all child nodes being moved.
-		for _, inode := range target.inodes {
-			if child, ok := n.bucket.nodes[inode.pgid]; ok {
-				child.parent.removeChild(child)
-				child.parent = n
-				child.parent.children = append(child.parent.children, child)
-			}
-		}
-
-		// Copy over inodes from target and remove target.
-		n.inodes = append(n.inodes, target.inodes...)
-		n.parent.del(target.key)
-		n.parent.removeChild(target)
-		delete(n.bucket.nodes, target.pgid)
-		target.free()
-	} else {
-		// Reparent all child nodes being moved.
-		for _, inode := range n.inodes {
-			if child, ok := n.bucket.nodes[inode.pgid]; ok {
-				child.parent.removeChild(child)
-				child.parent = target
-				child.parent.children = append(child.parent.children, child)
-			}
-		}
-
-		// Copy over inodes to target and remove node.
-		target.inodes = append(target.inodes, n.inodes...)
-		n.parent.del(n.key)
-		n.parent.removeChild(n)
-		delete(n.bucket.nodes, n.pgid)
-		n.free()
-	}
-
-	// Either this node or the target node was deleted from the parent so rebalance it.
-	n.parent.rebalance()
-}
-
-// removes a node from the list of in-memory children.
-// This does not affect the inodes.
-func (n *node) removeChild(target *node) {
-	for i, child := range n.children {
-		if child == target {
-			n.children = append(n.children[:i], n.children[i+1:]...)
-			return
-		}
-	}
-}
-
-// dereference causes the node to copy all its inode key/value references to heap memory.
-// This is required when the mmap is reallocated so inodes are not pointing to stale data.
-func (n *node) dereference() {
-	if n.key != nil {
-		key := make([]byte, len(n.key))
-		copy(key, n.key)
-		n.key = key
-		_assert(n.pgid == 0 || len(n.key) > 0, "dereference: zero-length node key on existing node")
-	}
-
-	for i := range n.inodes {
-		inode := &n.inodes[i]
-
-		key := make([]byte, len(inode.key))
-		copy(key, inode.key)
-		inode.key = key
-		_assert(len(inode.key) > 0, "dereference: zero-length inode key")
-
-		value := make([]byte, len(inode.value))
-		copy(value, inode.value)
-		inode.value = value
-	}
-
-	// Recursively dereference children.
-	for _, child := range n.children {
-		child.dereference()
-	}
-
-	// Update statistics.
-	n.bucket.tx.stats.NodeDeref++
-}
-
-// free adds the node's underlying page to the freelist.
-func (n *node) free() {
-	if n.pgid != 0 {
-		n.bucket.tx.db.freelist.free(n.bucket.tx.meta.txid, n.bucket.tx.page(n.pgid))
-		n.pgid = 0
-	}
-}
-
-// dump writes the contents of the node to STDERR for debugging purposes.
-/*
-func (n *node) dump() {
-	// Write node header.
-	var typ = "branch"
-	if n.isLeaf {
-		typ = "leaf"
-	}
-	warnf("[NODE %d {type=%s count=%d}]", n.pgid, typ, len(n.inodes))
-
-	// Write out abbreviated version of each item.
-	for _, item := range n.inodes {
-		if n.isLeaf {
-			if item.flags&bucketLeafFlag != 0 {
-				bucket := (*bucket)(unsafe.Pointer(&item.value[0]))
-				warnf("+L %08x -> (bucket root=%d)", trunc(item.key, 4), bucket.root)
-			} else {
-				warnf("+L %08x -> %08x", trunc(item.key, 4), trunc(item.value, 4))
-			}
-		} else {
-			warnf("+B %08x -> pgid=%d", trunc(item.key, 4), item.pgid)
-		}
-	}
-	warn("")
-}
-*/
-
-type nodes []*node
-
-func (s nodes) Len() int           { return len(s) }
-func (s nodes) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s nodes) Less(i, j int) bool { return bytes.Compare(s[i].inodes[0].key, s[j].inodes[0].key) == -1 }
-
-// inode represents an internal node inside of a node.
-// It can be used to point to elements in a page or point
-// to an element which hasn't been added to a page yet.
-type inode struct {
-	flags uint32
-	pgid  pgid
-	key   []byte
-	value []byte
-}
-
-type inodes []inode
diff --git a/vendor/github.com/coreos/bbolt/page.go b/vendor/github.com/coreos/bbolt/page.go
deleted file mode 100644
index 7651a6b..0000000
--- a/vendor/github.com/coreos/bbolt/page.go
+++ /dev/null
@@ -1,178 +0,0 @@
-package bolt
-
-import (
-	"fmt"
-	"os"
-	"sort"
-	"unsafe"
-)
-
-const pageHeaderSize = int(unsafe.Offsetof(((*page)(nil)).ptr))
-
-const minKeysPerPage = 2
-
-const branchPageElementSize = int(unsafe.Sizeof(branchPageElement{}))
-const leafPageElementSize = int(unsafe.Sizeof(leafPageElement{}))
-
-const (
-	branchPageFlag   = 0x01
-	leafPageFlag     = 0x02
-	metaPageFlag     = 0x04
-	freelistPageFlag = 0x10
-)
-
-const (
-	bucketLeafFlag = 0x01
-)
-
-type pgid uint64
-
-type page struct {
-	id       pgid
-	flags    uint16
-	count    uint16
-	overflow uint32
-	ptr      uintptr
-}
-
-// typ returns a human readable page type string used for debugging.
-func (p *page) typ() string {
-	if (p.flags & branchPageFlag) != 0 {
-		return "branch"
-	} else if (p.flags & leafPageFlag) != 0 {
-		return "leaf"
-	} else if (p.flags & metaPageFlag) != 0 {
-		return "meta"
-	} else if (p.flags & freelistPageFlag) != 0 {
-		return "freelist"
-	}
-	return fmt.Sprintf("unknown<%02x>", p.flags)
-}
-
-// meta returns a pointer to the metadata section of the page.
-func (p *page) meta() *meta {
-	return (*meta)(unsafe.Pointer(&p.ptr))
-}
-
-// leafPageElement retrieves the leaf node by index
-func (p *page) leafPageElement(index uint16) *leafPageElement {
-	n := &((*[0x7FFFFFF]leafPageElement)(unsafe.Pointer(&p.ptr)))[index]
-	return n
-}
-
-// leafPageElements retrieves a list of leaf nodes.
-func (p *page) leafPageElements() []leafPageElement {
-	if p.count == 0 {
-		return nil
-	}
-	return ((*[0x7FFFFFF]leafPageElement)(unsafe.Pointer(&p.ptr)))[:]
-}
-
-// branchPageElement retrieves the branch node by index
-func (p *page) branchPageElement(index uint16) *branchPageElement {
-	return &((*[0x7FFFFFF]branchPageElement)(unsafe.Pointer(&p.ptr)))[index]
-}
-
-// branchPageElements retrieves a list of branch nodes.
-func (p *page) branchPageElements() []branchPageElement {
-	if p.count == 0 {
-		return nil
-	}
-	return ((*[0x7FFFFFF]branchPageElement)(unsafe.Pointer(&p.ptr)))[:]
-}
-
-// dump writes n bytes of the page to STDERR as hex output.
-func (p *page) hexdump(n int) {
-	buf := (*[maxAllocSize]byte)(unsafe.Pointer(p))[:n]
-	fmt.Fprintf(os.Stderr, "%x\n", buf)
-}
-
-type pages []*page
-
-func (s pages) Len() int           { return len(s) }
-func (s pages) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s pages) Less(i, j int) bool { return s[i].id < s[j].id }
-
-// branchPageElement represents a node on a branch page.
-type branchPageElement struct {
-	pos   uint32
-	ksize uint32
-	pgid  pgid
-}
-
-// key returns a byte slice of the node key.
-func (n *branchPageElement) key() []byte {
-	buf := (*[maxAllocSize]byte)(unsafe.Pointer(n))
-	return (*[maxAllocSize]byte)(unsafe.Pointer(&buf[n.pos]))[:n.ksize]
-}
-
-// leafPageElement represents a node on a leaf page.
-type leafPageElement struct {
-	flags uint32
-	pos   uint32
-	ksize uint32
-	vsize uint32
-}
-
-// key returns a byte slice of the node key.
-func (n *leafPageElement) key() []byte {
-	buf := (*[maxAllocSize]byte)(unsafe.Pointer(n))
-	return (*[maxAllocSize]byte)(unsafe.Pointer(&buf[n.pos]))[:n.ksize:n.ksize]
-}
-
-// value returns a byte slice of the node value.
-func (n *leafPageElement) value() []byte {
-	buf := (*[maxAllocSize]byte)(unsafe.Pointer(n))
-	return (*[maxAllocSize]byte)(unsafe.Pointer(&buf[n.pos+n.ksize]))[:n.vsize:n.vsize]
-}
-
-// PageInfo represents human readable information about a page.
-type PageInfo struct {
-	ID            int
-	Type          string
-	Count         int
-	OverflowCount int
-}
-
-type pgids []pgid
-
-func (s pgids) Len() int           { return len(s) }
-func (s pgids) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s pgids) Less(i, j int) bool { return s[i] < s[j] }
-
-// merge returns the sorted union of a and b.
-func (a pgids) merge(b pgids) pgids {
-	// Return the opposite slice if one is nil.
-	if len(a) == 0 {
-		return b
-	} else if len(b) == 0 {
-		return a
-	}
-
-	// Create a list to hold all elements from both lists.
-	merged := make(pgids, 0, len(a)+len(b))
-
-	// Assign lead to the slice with a lower starting value, follow to the higher value.
-	lead, follow := a, b
-	if b[0] < a[0] {
-		lead, follow = b, a
-	}
-
-	// Continue while there are elements in the lead.
-	for len(lead) > 0 {
-		// Merge largest prefix of lead that is ahead of follow[0].
-		n := sort.Search(len(lead), func(i int) bool { return lead[i] > follow[0] })
-		merged = append(merged, lead[:n]...)
-		if n >= len(lead) {
-			break
-		}
-
-		// Swap lead and follow.
-		lead, follow = follow, lead[n:]
-	}
-
-	// Append what's left in follow.
-	merged = append(merged, follow...)
-
-	return merged
-}
diff --git a/vendor/github.com/coreos/bbolt/tx.go b/vendor/github.com/coreos/bbolt/tx.go
deleted file mode 100644
index 1cfb4cd..0000000
--- a/vendor/github.com/coreos/bbolt/tx.go
+++ /dev/null
@@ -1,682 +0,0 @@
-package bolt
-
-import (
-	"fmt"
-	"io"
-	"os"
-	"sort"
-	"strings"
-	"time"
-	"unsafe"
-)
-
-// txid represents the internal transaction identifier.
-type txid uint64
-
-// Tx represents a read-only or read/write transaction on the database.
-// Read-only transactions can be used for retrieving values for keys and creating cursors.
-// Read/write transactions can create and remove buckets and create and remove keys.
-//
-// IMPORTANT: You must commit or rollback transactions when you are done with
-// them. Pages can not be reclaimed by the writer until no more transactions
-// are using them. A long running read transaction can cause the database to
-// quickly grow.
-type Tx struct {
-	writable       bool
-	managed        bool
-	db             *DB
-	meta           *meta
-	root           Bucket
-	pages          map[pgid]*page
-	stats          TxStats
-	commitHandlers []func()
-
-	// WriteFlag specifies the flag for write-related methods like WriteTo().
-	// Tx opens the database file with the specified flag to copy the data.
-	//
-	// By default, the flag is unset, which works well for mostly in-memory
-	// workloads. For databases that are much larger than available RAM,
-	// set the flag to syscall.O_DIRECT to avoid trashing the page cache.
-	WriteFlag int
-}
-
-// init initializes the transaction.
-func (tx *Tx) init(db *DB) {
-	tx.db = db
-	tx.pages = nil
-
-	// Copy the meta page since it can be changed by the writer.
-	tx.meta = &meta{}
-	db.meta().copy(tx.meta)
-
-	// Copy over the root bucket.
-	tx.root = newBucket(tx)
-	tx.root.bucket = &bucket{}
-	*tx.root.bucket = tx.meta.root
-
-	// Increment the transaction id and add a page cache for writable transactions.
-	if tx.writable {
-		tx.pages = make(map[pgid]*page)
-		tx.meta.txid += txid(1)
-	}
-}
-
-// ID returns the transaction id.
-func (tx *Tx) ID() int {
-	return int(tx.meta.txid)
-}
-
-// DB returns a reference to the database that created the transaction.
-func (tx *Tx) DB() *DB {
-	return tx.db
-}
-
-// Size returns current database size in bytes as seen by this transaction.
-func (tx *Tx) Size() int64 {
-	return int64(tx.meta.pgid) * int64(tx.db.pageSize)
-}
-
-// Writable returns whether the transaction can perform write operations.
-func (tx *Tx) Writable() bool {
-	return tx.writable
-}
-
-// Cursor creates a cursor associated with the root bucket.
-// All items in the cursor will return a nil value because all root bucket keys point to buckets.
-// The cursor is only valid as long as the transaction is open.
-// Do not use a cursor after the transaction is closed.
-func (tx *Tx) Cursor() *Cursor {
-	return tx.root.Cursor()
-}
-
-// Stats retrieves a copy of the current transaction statistics.
-func (tx *Tx) Stats() TxStats {
-	return tx.stats
-}
-
-// Bucket retrieves a bucket by name.
-// Returns nil if the bucket does not exist.
-// The bucket instance is only valid for the lifetime of the transaction.
-func (tx *Tx) Bucket(name []byte) *Bucket {
-	return tx.root.Bucket(name)
-}
-
-// CreateBucket creates a new bucket.
-// Returns an error if the bucket already exists, if the bucket name is blank, or if the bucket name is too long.
-// The bucket instance is only valid for the lifetime of the transaction.
-func (tx *Tx) CreateBucket(name []byte) (*Bucket, error) {
-	return tx.root.CreateBucket(name)
-}
-
-// CreateBucketIfNotExists creates a new bucket if it doesn't already exist.
-// Returns an error if the bucket name is blank, or if the bucket name is too long.
-// The bucket instance is only valid for the lifetime of the transaction.
-func (tx *Tx) CreateBucketIfNotExists(name []byte) (*Bucket, error) {
-	return tx.root.CreateBucketIfNotExists(name)
-}
-
-// DeleteBucket deletes a bucket.
-// Returns an error if the bucket cannot be found or if the key represents a non-bucket value.
-func (tx *Tx) DeleteBucket(name []byte) error {
-	return tx.root.DeleteBucket(name)
-}
-
-// ForEach executes a function for each bucket in the root.
-// If the provided function returns an error then the iteration is stopped and
-// the error is returned to the caller.
-func (tx *Tx) ForEach(fn func(name []byte, b *Bucket) error) error {
-	return tx.root.ForEach(func(k, v []byte) error {
-		if err := fn(k, tx.root.Bucket(k)); err != nil {
-			return err
-		}
-		return nil
-	})
-}
-
-// OnCommit adds a handler function to be executed after the transaction successfully commits.
-func (tx *Tx) OnCommit(fn func()) {
-	tx.commitHandlers = append(tx.commitHandlers, fn)
-}
-
-// Commit writes all changes to disk and updates the meta page.
-// Returns an error if a disk write error occurs, or if Commit is
-// called on a read-only transaction.
-func (tx *Tx) Commit() error {
-	_assert(!tx.managed, "managed tx commit not allowed")
-	if tx.db == nil {
-		return ErrTxClosed
-	} else if !tx.writable {
-		return ErrTxNotWritable
-	}
-
-	// TODO(benbjohnson): Use vectorized I/O to write out dirty pages.
-
-	// Rebalance nodes which have had deletions.
-	var startTime = time.Now()
-	tx.root.rebalance()
-	if tx.stats.Rebalance > 0 {
-		tx.stats.RebalanceTime += time.Since(startTime)
-	}
-
-	// spill data onto dirty pages.
-	startTime = time.Now()
-	if err := tx.root.spill(); err != nil {
-		tx.rollback()
-		return err
-	}
-	tx.stats.SpillTime += time.Since(startTime)
-
-	// Free the old root bucket.
-	tx.meta.root.root = tx.root.root
-
-	opgid := tx.meta.pgid
-
-	// Free the freelist and allocate new pages for it. This will overestimate
-	// the size of the freelist but not underestimate the size (which would be bad).
-	tx.db.freelist.free(tx.meta.txid, tx.db.page(tx.meta.freelist))
-	p, err := tx.allocate((tx.db.freelist.size() / tx.db.pageSize) + 1)
-	if err != nil {
-		tx.rollback()
-		return err
-	}
-	if err := tx.db.freelist.write(p); err != nil {
-		tx.rollback()
-		return err
-	}
-	tx.meta.freelist = p.id
-
-	// If the high water mark has moved up then attempt to grow the database.
-	if tx.meta.pgid > opgid {
-		if err := tx.db.grow(int(tx.meta.pgid+1) * tx.db.pageSize); err != nil {
-			tx.rollback()
-			return err
-		}
-	}
-
-	// Write dirty pages to disk.
-	startTime = time.Now()
-	if err := tx.write(); err != nil {
-		tx.rollback()
-		return err
-	}
-
-	// If strict mode is enabled then perform a consistency check.
-	// Only the first consistency error is reported in the panic.
-	if tx.db.StrictMode {
-		ch := tx.Check()
-		var errs []string
-		for {
-			err, ok := <-ch
-			if !ok {
-				break
-			}
-			errs = append(errs, err.Error())
-		}
-		if len(errs) > 0 {
-			panic("check fail: " + strings.Join(errs, "\n"))
-		}
-	}
-
-	// Write meta to disk.
-	if err := tx.writeMeta(); err != nil {
-		tx.rollback()
-		return err
-	}
-	tx.stats.WriteTime += time.Since(startTime)
-
-	// Finalize the transaction.
-	tx.close()
-
-	// Execute commit handlers now that the locks have been removed.
-	for _, fn := range tx.commitHandlers {
-		fn()
-	}
-
-	return nil
-}
-
-// Rollback closes the transaction and ignores all previous updates. Read-only
-// transactions must be rolled back and not committed.
-func (tx *Tx) Rollback() error {
-	_assert(!tx.managed, "managed tx rollback not allowed")
-	if tx.db == nil {
-		return ErrTxClosed
-	}
-	tx.rollback()
-	return nil
-}
-
-func (tx *Tx) rollback() {
-	if tx.db == nil {
-		return
-	}
-	if tx.writable {
-		tx.db.freelist.rollback(tx.meta.txid)
-		tx.db.freelist.reload(tx.db.page(tx.db.meta().freelist))
-	}
-	tx.close()
-}
-
-func (tx *Tx) close() {
-	if tx.db == nil {
-		return
-	}
-	if tx.writable {
-		// Grab freelist stats.
-		var freelistFreeN = tx.db.freelist.free_count()
-		var freelistPendingN = tx.db.freelist.pending_count()
-		var freelistAlloc = tx.db.freelist.size()
-
-		// Remove transaction ref & writer lock.
-		tx.db.rwtx = nil
-		tx.db.rwlock.Unlock()
-
-		// Merge statistics.
-		tx.db.statlock.Lock()
-		tx.db.stats.FreePageN = freelistFreeN
-		tx.db.stats.PendingPageN = freelistPendingN
-		tx.db.stats.FreeAlloc = (freelistFreeN + freelistPendingN) * tx.db.pageSize
-		tx.db.stats.FreelistInuse = freelistAlloc
-		tx.db.stats.TxStats.add(&tx.stats)
-		tx.db.statlock.Unlock()
-	} else {
-		tx.db.removeTx(tx)
-	}
-
-	// Clear all references.
-	tx.db = nil
-	tx.meta = nil
-	tx.root = Bucket{tx: tx}
-	tx.pages = nil
-}
-
-// Copy writes the entire database to a writer.
-// This function exists for backwards compatibility. Use WriteTo() instead.
-func (tx *Tx) Copy(w io.Writer) error {
-	_, err := tx.WriteTo(w)
-	return err
-}
-
-// WriteTo writes the entire database to a writer.
-// If err == nil then exactly tx.Size() bytes will be written into the writer.
-func (tx *Tx) WriteTo(w io.Writer) (n int64, err error) {
-	// Attempt to open reader with WriteFlag
-	f, err := os.OpenFile(tx.db.path, os.O_RDONLY|tx.WriteFlag, 0)
-	if err != nil {
-		return 0, err
-	}
-	defer func() { _ = f.Close() }()
-
-	// Generate a meta page. We use the same page data for both meta pages.
-	buf := make([]byte, tx.db.pageSize)
-	page := (*page)(unsafe.Pointer(&buf[0]))
-	page.flags = metaPageFlag
-	*page.meta() = *tx.meta
-
-	// Write meta 0.
-	page.id = 0
-	page.meta().checksum = page.meta().sum64()
-	nn, err := w.Write(buf)
-	n += int64(nn)
-	if err != nil {
-		return n, fmt.Errorf("meta 0 copy: %s", err)
-	}
-
-	// Write meta 1 with a lower transaction id.
-	page.id = 1
-	page.meta().txid -= 1
-	page.meta().checksum = page.meta().sum64()
-	nn, err = w.Write(buf)
-	n += int64(nn)
-	if err != nil {
-		return n, fmt.Errorf("meta 1 copy: %s", err)
-	}
-
-	// Move past the meta pages in the file.
-	if _, err := f.Seek(int64(tx.db.pageSize*2), os.SEEK_SET); err != nil {
-		return n, fmt.Errorf("seek: %s", err)
-	}
-
-	// Copy data pages.
-	wn, err := io.CopyN(w, f, tx.Size()-int64(tx.db.pageSize*2))
-	n += wn
-	if err != nil {
-		return n, err
-	}
-
-	return n, f.Close()
-}
-
-// CopyFile copies the entire database to file at the given path.
-// A reader transaction is maintained during the copy so it is safe to continue
-// using the database while a copy is in progress.
-func (tx *Tx) CopyFile(path string, mode os.FileMode) error {
-	f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode)
-	if err != nil {
-		return err
-	}
-
-	err = tx.Copy(f)
-	if err != nil {
-		_ = f.Close()
-		return err
-	}
-	return f.Close()
-}
-
-// Check performs several consistency checks on the database for this transaction.
-// An error is returned if any inconsistency is found.
-//
-// It can be safely run concurrently on a writable transaction. However, this
-// incurs a high cost for large databases and databases with a lot of subbuckets
-// because of caching. This overhead can be removed if running on a read-only
-// transaction, however, it is not safe to execute other writer transactions at
-// the same time.
-func (tx *Tx) Check() <-chan error {
-	ch := make(chan error)
-	go tx.check(ch)
-	return ch
-}
-
-func (tx *Tx) check(ch chan error) {
-	// Check if any pages are double freed.
-	freed := make(map[pgid]bool)
-	for _, id := range tx.db.freelist.all() {
-		if freed[id] {
-			ch <- fmt.Errorf("page %d: already freed", id)
-		}
-		freed[id] = true
-	}
-
-	// Track every reachable page.
-	reachable := make(map[pgid]*page)
-	reachable[0] = tx.page(0) // meta0
-	reachable[1] = tx.page(1) // meta1
-	for i := uint32(0); i <= tx.page(tx.meta.freelist).overflow; i++ {
-		reachable[tx.meta.freelist+pgid(i)] = tx.page(tx.meta.freelist)
-	}
-
-	// Recursively check buckets.
-	tx.checkBucket(&tx.root, reachable, freed, ch)
-
-	// Ensure all pages below high water mark are either reachable or freed.
-	for i := pgid(0); i < tx.meta.pgid; i++ {
-		_, isReachable := reachable[i]
-		if !isReachable && !freed[i] {
-			ch <- fmt.Errorf("page %d: unreachable unfreed", int(i))
-		}
-	}
-
-	// Close the channel to signal completion.
-	close(ch)
-}
-
-func (tx *Tx) checkBucket(b *Bucket, reachable map[pgid]*page, freed map[pgid]bool, ch chan error) {
-	// Ignore inline buckets.
-	if b.root == 0 {
-		return
-	}
-
-	// Check every page used by this bucket.
-	b.tx.forEachPage(b.root, 0, func(p *page, _ int) {
-		if p.id > tx.meta.pgid {
-			ch <- fmt.Errorf("page %d: out of bounds: %d", int(p.id), int(b.tx.meta.pgid))
-		}
-
-		// Ensure each page is only referenced once.
-		for i := pgid(0); i <= pgid(p.overflow); i++ {
-			var id = p.id + i
-			if _, ok := reachable[id]; ok {
-				ch <- fmt.Errorf("page %d: multiple references", int(id))
-			}
-			reachable[id] = p
-		}
-
-		// We should only encounter un-freed leaf and branch pages.
-		if freed[p.id] {
-			ch <- fmt.Errorf("page %d: reachable freed", int(p.id))
-		} else if (p.flags&branchPageFlag) == 0 && (p.flags&leafPageFlag) == 0 {
-			ch <- fmt.Errorf("page %d: invalid type: %s", int(p.id), p.typ())
-		}
-	})
-
-	// Check each bucket within this bucket.
-	_ = b.ForEach(func(k, v []byte) error {
-		if child := b.Bucket(k); child != nil {
-			tx.checkBucket(child, reachable, freed, ch)
-		}
-		return nil
-	})
-}
-
-// allocate returns a contiguous block of memory starting at a given page.
-func (tx *Tx) allocate(count int) (*page, error) {
-	p, err := tx.db.allocate(count)
-	if err != nil {
-		return nil, err
-	}
-
-	// Save to our page cache.
-	tx.pages[p.id] = p
-
-	// Update statistics.
-	tx.stats.PageCount++
-	tx.stats.PageAlloc += count * tx.db.pageSize
-
-	return p, nil
-}
-
-// write writes any dirty pages to disk.
-func (tx *Tx) write() error {
-	// Sort pages by id.
-	pages := make(pages, 0, len(tx.pages))
-	for _, p := range tx.pages {
-		pages = append(pages, p)
-	}
-	// Clear out page cache early.
-	tx.pages = make(map[pgid]*page)
-	sort.Sort(pages)
-
-	// Write pages to disk in order.
-	for _, p := range pages {
-		size := (int(p.overflow) + 1) * tx.db.pageSize
-		offset := int64(p.id) * int64(tx.db.pageSize)
-
-		// Write out page in "max allocation" sized chunks.
-		ptr := (*[maxAllocSize]byte)(unsafe.Pointer(p))
-		for {
-			// Limit our write to our max allocation size.
-			sz := size
-			if sz > maxAllocSize-1 {
-				sz = maxAllocSize - 1
-			}
-
-			// Write chunk to disk.
-			buf := ptr[:sz]
-			if _, err := tx.db.ops.writeAt(buf, offset); err != nil {
-				return err
-			}
-
-			// Update statistics.
-			tx.stats.Write++
-
-			// Exit inner for loop if we've written all the chunks.
-			size -= sz
-			if size == 0 {
-				break
-			}
-
-			// Otherwise move offset forward and move pointer to next chunk.
-			offset += int64(sz)
-			ptr = (*[maxAllocSize]byte)(unsafe.Pointer(&ptr[sz]))
-		}
-	}
-
-	// Ignore file sync if flag is set on DB.
-	if !tx.db.NoSync || IgnoreNoSync {
-		if err := fdatasync(tx.db); err != nil {
-			return err
-		}
-	}
-
-	// Put small pages back to page pool.
-	for _, p := range pages {
-		// Ignore page sizes over 1 page.
-		// These are allocated using make() instead of the page pool.
-		if int(p.overflow) != 0 {
-			continue
-		}
-
-		buf := (*[maxAllocSize]byte)(unsafe.Pointer(p))[:tx.db.pageSize]
-
-		// See https://go.googlesource.com/go/+/f03c9202c43e0abb130669852082117ca50aa9b1
-		for i := range buf {
-			buf[i] = 0
-		}
-		tx.db.pagePool.Put(buf)
-	}
-
-	return nil
-}
-
-// writeMeta writes the meta to the disk.
-func (tx *Tx) writeMeta() error {
-	// Create a temporary buffer for the meta page.
-	buf := make([]byte, tx.db.pageSize)
-	p := tx.db.pageInBuffer(buf, 0)
-	tx.meta.write(p)
-
-	// Write the meta page to file.
-	if _, err := tx.db.ops.writeAt(buf, int64(p.id)*int64(tx.db.pageSize)); err != nil {
-		return err
-	}
-	if !tx.db.NoSync || IgnoreNoSync {
-		if err := fdatasync(tx.db); err != nil {
-			return err
-		}
-	}
-
-	// Update statistics.
-	tx.stats.Write++
-
-	return nil
-}
-
-// page returns a reference to the page with a given id.
-// If page has been written to then a temporary buffered page is returned.
-func (tx *Tx) page(id pgid) *page {
-	// Check the dirty pages first.
-	if tx.pages != nil {
-		if p, ok := tx.pages[id]; ok {
-			return p
-		}
-	}
-
-	// Otherwise return directly from the mmap.
-	return tx.db.page(id)
-}
-
-// forEachPage iterates over every page within a given page and executes a function.
-func (tx *Tx) forEachPage(pgid pgid, depth int, fn func(*page, int)) {
-	p := tx.page(pgid)
-
-	// Execute function.
-	fn(p, depth)
-
-	// Recursively loop over children.
-	if (p.flags & branchPageFlag) != 0 {
-		for i := 0; i < int(p.count); i++ {
-			elem := p.branchPageElement(uint16(i))
-			tx.forEachPage(elem.pgid, depth+1, fn)
-		}
-	}
-}
-
-// Page returns page information for a given page number.
-// This is only safe for concurrent use when used by a writable transaction.
-func (tx *Tx) Page(id int) (*PageInfo, error) {
-	if tx.db == nil {
-		return nil, ErrTxClosed
-	} else if pgid(id) >= tx.meta.pgid {
-		return nil, nil
-	}
-
-	// Build the page info.
-	p := tx.db.page(pgid(id))
-	info := &PageInfo{
-		ID:            id,
-		Count:         int(p.count),
-		OverflowCount: int(p.overflow),
-	}
-
-	// Determine the type (or if it's free).
-	if tx.db.freelist.freed(pgid(id)) {
-		info.Type = "free"
-	} else {
-		info.Type = p.typ()
-	}
-
-	return info, nil
-}
-
-// TxStats represents statistics about the actions performed by the transaction.
-type TxStats struct {
-	// Page statistics.
-	PageCount int // number of page allocations
-	PageAlloc int // total bytes allocated
-
-	// Cursor statistics.
-	CursorCount int // number of cursors created
-
-	// Node statistics
-	NodeCount int // number of node allocations
-	NodeDeref int // number of node dereferences
-
-	// Rebalance statistics.
-	Rebalance     int           // number of node rebalances
-	RebalanceTime time.Duration // total time spent rebalancing
-
-	// Split/Spill statistics.
-	Split     int           // number of nodes split
-	Spill     int           // number of nodes spilled
-	SpillTime time.Duration // total time spent spilling
-
-	// Write statistics.
-	Write     int           // number of writes performed
-	WriteTime time.Duration // total time spent writing to disk
-}
-
-func (s *TxStats) add(other *TxStats) {
-	s.PageCount += other.PageCount
-	s.PageAlloc += other.PageAlloc
-	s.CursorCount += other.CursorCount
-	s.NodeCount += other.NodeCount
-	s.NodeDeref += other.NodeDeref
-	s.Rebalance += other.Rebalance
-	s.RebalanceTime += other.RebalanceTime
-	s.Split += other.Split
-	s.Spill += other.Spill
-	s.SpillTime += other.SpillTime
-	s.Write += other.Write
-	s.WriteTime += other.WriteTime
-}
-
-// Sub calculates and returns the difference between two sets of transaction stats.
-// This is useful when obtaining stats at two different points and time and
-// you need the performance counters that occurred within that time span.
-func (s *TxStats) Sub(other *TxStats) TxStats {
-	var diff TxStats
-	diff.PageCount = s.PageCount - other.PageCount
-	diff.PageAlloc = s.PageAlloc - other.PageAlloc
-	diff.CursorCount = s.CursorCount - other.CursorCount
-	diff.NodeCount = s.NodeCount - other.NodeCount
-	diff.NodeDeref = s.NodeDeref - other.NodeDeref
-	diff.Rebalance = s.Rebalance - other.Rebalance
-	diff.RebalanceTime = s.RebalanceTime - other.RebalanceTime
-	diff.Split = s.Split - other.Split
-	diff.Spill = s.Spill - other.Spill
-	diff.SpillTime = s.SpillTime - other.SpillTime
-	diff.Write = s.Write - other.Write
-	diff.WriteTime = s.WriteTime - other.WriteTime
-	return diff
-}
diff --git a/vendor/github.com/coreos/etcd/.dockerignore b/vendor/github.com/coreos/etcd/.dockerignore
deleted file mode 100644
index 6b8710a..0000000
--- a/vendor/github.com/coreos/etcd/.dockerignore
+++ /dev/null
@@ -1 +0,0 @@
-.git
diff --git a/vendor/github.com/coreos/etcd/.gitignore b/vendor/github.com/coreos/etcd/.gitignore
deleted file mode 100644
index b055a98..0000000
--- a/vendor/github.com/coreos/etcd/.gitignore
+++ /dev/null
@@ -1,21 +0,0 @@
-/agent-*
-/coverage
-/covdir
-/docs
-/vendor
-/gopath
-/gopath.proto
-/go-bindata
-/release
-/machine*
-/bin
-.vagrant
-*.etcd
-*.log
-/etcd
-*.swp
-/hack/insta-discovery/.env
-*.test
-hack/tls-setup/certs
-.idea
-*.bak
diff --git a/vendor/github.com/coreos/etcd/.godir b/vendor/github.com/coreos/etcd/.godir
deleted file mode 100644
index 00ff6aa..0000000
--- a/vendor/github.com/coreos/etcd/.godir
+++ /dev/null
@@ -1 +0,0 @@
-github.com/coreos/etcd
diff --git a/vendor/github.com/coreos/etcd/.header b/vendor/github.com/coreos/etcd/.header
deleted file mode 100644
index 0446af6..0000000
--- a/vendor/github.com/coreos/etcd/.header
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
diff --git a/vendor/github.com/coreos/etcd/.travis.yml b/vendor/github.com/coreos/etcd/.travis.yml
deleted file mode 100644
index bbe4af7..0000000
--- a/vendor/github.com/coreos/etcd/.travis.yml
+++ /dev/null
@@ -1,73 +0,0 @@
-language: go
-go_import_path: github.com/coreos/etcd
-
-sudo: required
-
-services: docker
-
-go:
-- 1.10.7
-
-notifications:
-  on_success: never
-  on_failure: never
-
-env:
-  matrix:
-  - TARGET=linux-amd64-integration
-  - TARGET=linux-amd64-functional
-  - TARGET=linux-amd64-unit
-  - TARGET=all-build
-  - TARGET=linux-386-unit
-
-matrix:
-  fast_finish: true
-  allow_failures:
-  - go: 1.10.7
-    env: TARGET=linux-386-unit
-  exclude:
-  - go: tip
-    env: TARGET=linux-386-unit
-
-before_install:
-- if [[ $TRAVIS_GO_VERSION == 1.* ]]; then docker pull gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION}; fi
-
-install:
-- pushd cmd/etcd && go get -t -v ./... && popd
-
-script:
- - echo "TRAVIS_GO_VERSION=${TRAVIS_GO_VERSION}"
- - >
-    case "${TARGET}" in
-      linux-amd64-integration)
-        docker run --rm \
-          --volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \
-          /bin/bash -c "GOARCH=amd64 PASSES='integration' ./test"
-        ;;
-      linux-amd64-functional)
-        docker run --rm \
-          --volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \
-          /bin/bash -c "./build && GOARCH=amd64 PASSES='functional' ./test"
-        ;;
-      linux-amd64-unit)
-        docker run --rm \
-          --volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \
-          /bin/bash -c "GOARCH=amd64 PASSES='unit' ./test"
-        ;;
-      all-build)
-        docker run --rm \
-          --volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \
-          /bin/bash -c "GOARCH=amd64 PASSES='build' ./test \
-            && GOARCH=386 PASSES='build' ./test \
-            && GO_BUILD_FLAGS='-v' GOOS=darwin GOARCH=amd64 ./build \
-            && GO_BUILD_FLAGS='-v' GOOS=windows GOARCH=amd64 ./build \
-            && GO_BUILD_FLAGS='-v' GOARCH=arm ./build \
-            && GO_BUILD_FLAGS='-v' GOARCH=arm64 ./build \
-            && GO_BUILD_FLAGS='-v' GOARCH=ppc64le ./build"
-        ;;
-      linux-386-unit)
-        docker run --rm \
-          --volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \
-          /bin/bash -c "GOARCH=386 PASSES='unit' ./test"
-        ;;
-    esac
diff --git a/vendor/github.com/coreos/etcd/.words b/vendor/github.com/coreos/etcd/.words
deleted file mode 100644
index 31fffef..0000000
--- a/vendor/github.com/coreos/etcd/.words
+++ /dev/null
@@ -1,44 +0,0 @@
-DefaultMaxRequestBytes
-ErrCodeEnhanceYourCalm
-ErrTimeout
-GoAway
-KeepAlive
-Keepalive
-MiB
-ResourceExhausted
-RPC
-RPCs
-TODO
-backoff
-blackhole
-blackholed
-cancelable
-cancelation
-cluster_proxy
-defragment
-defragmenting
-etcd
-gRPC
-goroutine
-goroutines
-healthcheck
-iff
-inflight
-keepalive
-keepalives
-keyspace
-linearization
-localhost
-mutex
-prefetching
-protobuf
-prometheus
-rafthttp
-repin
-serializable
-teardown
-too_many_pings
-uncontended
-unprefixed
-unlisting
-
diff --git a/vendor/github.com/coreos/etcd/CHANGELOG.md b/vendor/github.com/coreos/etcd/CHANGELOG.md
deleted file mode 100644
index 603e501..0000000
--- a/vendor/github.com/coreos/etcd/CHANGELOG.md
+++ /dev/null
@@ -1,746 +0,0 @@
-## [v3.3.0](https://github.com/coreos/etcd/releases/tag/v3.3.0)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.0...v3.3.0) and [v3.3 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_3.md) for any breaking changes.
-
-### Improved
-
-- Use [`coreos/bbolt`](https://github.com/coreos/bbolt/releases) to replace [`boltdb/bolt`](https://github.com/boltdb/bolt#project-status).
-  - Fix [etcd database size grows until `mvcc: database space exceeded`](https://github.com/coreos/etcd/issues/8009).
-- [Reduce memory allocation](https://github.com/coreos/etcd/pull/8428) on [Range operations](https://github.com/coreos/etcd/pull/8475).
-- [Rate limit](https://github.com/coreos/etcd/pull/8099) and [randomize](https://github.com/coreos/etcd/pull/8101) lease revoke on restart or leader elections.
-  - Prevent [spikes in Raft proposal rate](https://github.com/coreos/etcd/issues/8096).
-- Support `clientv3` balancer failover under [network faults/partitions](https://github.com/coreos/etcd/issues/8711).
-- Better warning on [mismatched `--initial-cluster`](https://github.com/coreos/etcd/pull/8083) flag.
-
-### Changed(Breaking Changes)
-
-- Require [Go 1.9+](https://github.com/coreos/etcd/issues/6174).
-  - Compile with *Go 1.9.2*.
-  - Deprecate [`golang.org/x/net/context`](https://github.com/coreos/etcd/pull/8511).
-- Require [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) [**`v1.7.4`**](https://github.com/grpc/grpc-go/releases/tag/v1.7.4) or [**`v1.7.5+`**](https://github.com/grpc/grpc-go/releases/tag/v1.7.5):
-  - Deprecate [`metadata.Incoming/OutgoingContext`](https://github.com/coreos/etcd/pull/7896).
-  - Deprecate `grpclog.Logger`, upgrade to [`grpclog.LoggerV2`](https://github.com/coreos/etcd/pull/8533).
-  - Deprecate [`grpc.ErrClientConnTimeout`](https://github.com/coreos/etcd/pull/8505) errors in `clientv3`.
-  - Use [`MaxRecvMsgSize` and `MaxSendMsgSize`](https://github.com/coreos/etcd/pull/8437) to limit message size, in etcd server.
-- Upgrade [`github.com/grpc-ecosystem/grpc-gateway`](https://github.com/grpc-ecosystem/grpc-gateway/releases) `v1.2.2` to `v1.3.0`.
-- Translate [gRPC status error in v3 client `Snapshot` API](https://github.com/coreos/etcd/pull/9038).
-- Upgrade [`github.com/ugorji/go/codec`](https://github.com/ugorji/go) for v2 `client`.
-  - [Regenerated](https://github.com/coreos/etcd/pull/8721) v2 `client` source code with latest `ugorji/go/codec`.
-- Fix [`/health` endpoint JSON output](https://github.com/coreos/etcd/pull/8312).
-- v3 `etcdctl` [`lease timetolive LEASE_ID`](https://github.com/coreos/etcd/issues/9028) on expired lease now prints [`lease LEASE_ID already expired`](https://github.com/coreos/etcd/pull/9047).
-  - <=3.2 prints `lease LEASE_ID granted with TTL(0s), remaining(-1s)`.
-
-### Added(`etcd`)
-
-- Add [`--experimental-enable-v2v3`](https://github.com/coreos/etcd/pull/8407) flag to [emulate v2 API with v3](https://github.com/coreos/etcd/issues/6925).
-- Add [`--experimental-corrupt-check-time`](https://github.com/coreos/etcd/pull/8420) flag to [raise corrupt alarm monitoring](https://github.com/coreos/etcd/issues/7125).
-- Add [`--experimental-initial-corrupt-check`](https://github.com/coreos/etcd/pull/8554) flag to [check database hash before serving client/peer traffic](https://github.com/coreos/etcd/issues/8313).
-- Add [`--max-txn-ops`](https://github.com/coreos/etcd/pull/7976) flag to [configure maximum number operations in transaction](https://github.com/coreos/etcd/issues/7826).
-- Add [`--max-request-bytes`](https://github.com/coreos/etcd/pull/7968) flag to [configure maximum client request size](https://github.com/coreos/etcd/issues/7923).
-  - If not configured, it defaults to 1.5 MiB.
-- Add [`--client-crl-file`, `--peer-crl-file`](https://github.com/coreos/etcd/pull/8124) flags for [Certificate revocation list](https://github.com/coreos/etcd/issues/4034).
-- Add [`--peer-require-cn`](https://github.com/coreos/etcd/pull/8616) flag to support [CN-based auth for inter-peer connection](https://github.com/coreos/etcd/issues/8262).
-- Add [`--listen-metrics-urls`](https://github.com/coreos/etcd/pull/8242) flag for additional `/metrics` endpoints.
-  - Support [additional (non) TLS `/metrics` endpoints for a TLS-enabled cluster](https://github.com/coreos/etcd/pull/8282).
-  - e.g. `--listen-metrics-urls=https://localhost:2378,http://localhost:9379` to serve `/metrics` in secure port 2378 and insecure port 9379.
-  - Useful for [bypassing critical APIs when monitoring etcd](https://github.com/coreos/etcd/issues/8060).
-- Add [`--auto-compaction-mode`](https://github.com/coreos/etcd/pull/8123) flag to [support revision-based compaction](https://github.com/coreos/etcd/issues/8098).
-- Change `--auto-compaction-retention` flag to [accept string values](https://github.com/coreos/etcd/pull/8563) with [finer granularity](https://github.com/coreos/etcd/issues/8503).
-- Add [`--grpc-keepalive-min-time`, `--grpc-keepalive-interval`, `--grpc-keepalive-timeout`](https://github.com/coreos/etcd/pull/8535) flags to configure server-side keepalive policies.
-- Serve [`/health` endpoint as unhealthy](https://github.com/coreos/etcd/pull/8272) when [alarm is raised](https://github.com/coreos/etcd/issues/8207).
-- Provide [error information in `/health`](https://github.com/coreos/etcd/pull/8312).
-  - e.g. `{"health":false,"errors":["NOSPACE"]}`.
-- Move [logging setup to embed package](https://github.com/coreos/etcd/pull/8810)
-  - Disable gRPC server log by default.
-- Use [monotonic time in Go 1.9](https://github.com/coreos/etcd/pull/8507) for `lease` package.
-- Warn on [empty hosts in advertise URLs](https://github.com/coreos/etcd/pull/8384).
-  - Address [advertise client URLs accepts empty hosts](https://github.com/coreos/etcd/issues/8379).
-  - etcd `v3.4` will exit on this error.
-    - e.g. `--advertise-client-urls=http://:2379`.
-- Warn on [shadowed environment variables](https://github.com/coreos/etcd/pull/8385).
-  - Address [error on shadowed environment variables](https://github.com/coreos/etcd/issues/8380).
-  - etcd `v3.4` will exit on this error.
-
-### Added(API)
-
-- Support [ranges in transaction comparisons](https://github.com/coreos/etcd/pull/8025) for [disconnected linearized reads](https://github.com/coreos/etcd/issues/7924).
-- Add [nested transactions](https://github.com/coreos/etcd/pull/8102) to extend [proxy use cases](https://github.com/coreos/etcd/issues/7857).
-- Add [lease comparison target in transaction](https://github.com/coreos/etcd/pull/8324).
-- Add [lease list](https://github.com/coreos/etcd/pull/8358).
-- Add [hash by revision](https://github.com/coreos/etcd/pull/8263) for [better corruption checking against boltdb](https://github.com/coreos/etcd/issues/8016).
-
-### Added(`etcd/clientv3`)
-
-- Add [health balancer](https://github.com/coreos/etcd/pull/8545) to fix [watch API hangs](https://github.com/coreos/etcd/issues/7247), improve [endpoint switch under network faults](https://github.com/coreos/etcd/issues/7941).
-- [Refactor balancer](https://github.com/coreos/etcd/pull/8840) and add [client-side keepalive pings](https://github.com/coreos/etcd/pull/8199) to handle [network partitions](https://github.com/coreos/etcd/issues/8711).
-- Add [`MaxCallSendMsgSize` and `MaxCallRecvMsgSize`](https://github.com/coreos/etcd/pull/9047) fields to [`clientv3.Config`](https://godoc.org/github.com/coreos/etcd/clientv3#Config).
-  - Fix [exceeded response size limit error in client-side](https://github.com/coreos/etcd/issues/9043).
-  - Address [kubernetes#51099](https://github.com/kubernetes/kubernetes/issues/51099).
-  - `MaxCallSendMsgSize` default value is 2 MiB, if not configured.
-  - `MaxCallRecvMsgSize` default value is `math.MaxInt32`, if not configured.
-- Accept [`Compare_LEASE`](https://github.com/coreos/etcd/pull/8324) in [`clientv3.Compare`](https://godoc.org/github.com/coreos/etcd/clientv3#Compare).
-- Add [`LeaseValue` helper](https://github.com/coreos/etcd/pull/8488) to `Cmp` `LeaseID` values in `Txn`.
-- Add [`MoveLeader`](https://github.com/coreos/etcd/pull/8153) to `Maintenance`.
-- Add [`HashKV`](https://github.com/coreos/etcd/pull/8351) to `Maintenance`.
-- Add [`Leases`](https://github.com/coreos/etcd/pull/8358) to `Lease`.
-- Add [`clientv3/ordering`](https://github.com/coreos/etcd/pull/8092) for enforce [ordering in serialized requests](https://github.com/coreos/etcd/issues/7623).
-
-### Added(v2 `etcdctl`)
-
-- Add [`backup --with-v3`](https://github.com/coreos/etcd/pull/8479) flag.
-
-### Added(v3 `etcdctl`)
-
-- Add [`--discovery-srv`](https://github.com/coreos/etcd/pull/8462) flag.
-- Add [`--keepalive-time`, `--keepalive-timeout`](https://github.com/coreos/etcd/pull/8663) flags.
-- Add [`lease list`](https://github.com/coreos/etcd/pull/8358) command.
-- Add [`lease keep-alive --once`](https://github.com/coreos/etcd/pull/8775) flag.
-- Make [`lease timetolive LEASE_ID`](https://github.com/coreos/etcd/issues/9028) on expired lease print [`lease LEASE_ID already expired`](https://github.com/coreos/etcd/pull/9047).
-  - <=3.2 prints `lease LEASE_ID granted with TTL(0s), remaining(-1s)`.
-- Add [`defrag --data-dir`](https://github.com/coreos/etcd/pull/8367) flag.
-- Add [`move-leader`](https://github.com/coreos/etcd/pull/8153) command.
-- Add [`endpoint hashkv`](https://github.com/coreos/etcd/pull/8351) command.
-- Add [`endpoint --cluster`](https://github.com/coreos/etcd/pull/8143) flag, equivalent to [v2 `etcdctl cluster-health`](https://github.com/coreos/etcd/issues/8117).
-- Make `endpoint health` command terminate with [non-zero exit code on unhealthy status](https://github.com/coreos/etcd/pull/8342).
-- Add [`lock --ttl`](https://github.com/coreos/etcd/pull/8370) flag.
-- Support [`watch [key] [range_end] -- [exec-command…]`](https://github.com/coreos/etcd/pull/8919), equivalent to [v2 `etcdctl exec-watch`](https://github.com/coreos/etcd/issues/8814).
-- Enable [`clientv3.WithRequireLeader(context.Context)` for `watch`](https://github.com/coreos/etcd/pull/8672) command.
-- Print [`"del"` instead of `"delete"`](https://github.com/coreos/etcd/pull/8297) in `txn` interactive mode.
-- Print [`ETCD_INITIAL_ADVERTISE_PEER_URLS` in `member add`](https://github.com/coreos/etcd/pull/8332).
-
-### Added(metrics)
-
-- Add [`etcd --listen-metrics-urls`](https://github.com/coreos/etcd/pull/8242) flag for additional `/metrics` endpoints.
-  - Useful for [bypassing critical APIs when monitoring etcd](https://github.com/coreos/etcd/issues/8060).
-- Add [`etcd_server_version`](https://github.com/coreos/etcd/pull/8960) Prometheus metric.
-  - To replace [Kubernetes `etcd-version-monitor`](https://github.com/coreos/etcd/issues/8948).
-- Add [`etcd_debugging_mvcc_db_compaction_keys_total`](https://github.com/coreos/etcd/pull/8280) Prometheus metric.
-- Add [`etcd_debugging_server_lease_expired_total`](https://github.com/coreos/etcd/pull/8064) Prometheus metric.
-  - To improve [lease revoke monitoring](https://github.com/coreos/etcd/issues/8050).
-- Document [Prometheus 2.0 rules](https://github.com/coreos/etcd/pull/8879).
-- Initialize gRPC server [metrics with zero values](https://github.com/coreos/etcd/pull/8878).
-
-### Added(`grpc-proxy`)
-
-- Add [`grpc-proxy start --experimental-leasing-prefix`](https://github.com/coreos/etcd/pull/8341) flag:
-  - For disconnected linearized reads.
-  - Based on [V system leasing](https://github.com/coreos/etcd/issues/6065).
-  - See ["Disconnected consistent reads with etcd" blog post](https://coreos.com/blog/coreos-labs-disconnected-consistent-reads-with-etcd).
-- Add [`grpc-proxy start --experimental-serializable-ordering`](https://github.com/coreos/etcd/pull/8315) flag.
-  - To ensure serializable reads have monotonically increasing store revisions across endpoints.
-- Add [`grpc-proxy start --metrics-addr`](https://github.com/coreos/etcd/pull/8242) flag for an additional `/metrics` endpoint.
-  - Set `--metrics-addr=http://[HOST]:9379` to serve `/metrics` in insecure port 9379.
-- Serve [`/health` endpoint in grpc-proxy](https://github.com/coreos/etcd/pull/8322).
-- Add [`grpc-proxy start --debug`](https://github.com/coreos/etcd/pull/8994) flag.
-
-### Added(gRPC gateway)
-
-- Replace [gRPC gateway](https://github.com/grpc-ecosystem/grpc-gateway) endpoint with [`/v3beta`](https://github.com/coreos/etcd/pull/8880).
-  - To deprecate [`/v3alpha`](https://github.com/coreos/etcd/issues/8125) in `v3.4`.
-- Support ["authorization" token](https://github.com/coreos/etcd/pull/7999).
-- Support [websocket for bi-directional streams](https://github.com/coreos/etcd/pull/8257).
-  - Fix [`Watch` API with gRPC gateway](https://github.com/coreos/etcd/issues/8237).
-- Upgrade gRPC gateway to [v1.3.0](https://github.com/coreos/etcd/issues/8838).
-
-### Added(`etcd/raft`)
-
-- Add [non-voting member](https://github.com/coreos/etcd/pull/8751).
-  - To implement [Raft thesis 4.2.1 Catching up new servers](https://github.com/coreos/etcd/issues/8568).
-  - `Learner` node does not vote or promote itself.
-
-### Added/Fixed(Security/Auth)
-
-- Add [CRL based connection rejection](https://github.com/coreos/etcd/pull/8124) to manage [revoked certs](https://github.com/coreos/etcd/issues/4034).
-- Document [TLS authentication changes](https://github.com/coreos/etcd/pull/8895):
-  - [Server accepts connections if IP matches, without checking DNS entries](https://github.com/coreos/etcd/pull/8223). For instance, if peer cert contains IP addresses and DNS names in Subject Alternative Name (SAN) field, and the remote IP address matches one of those IP addresses, server just accepts connection without further checking the DNS names.
-  - [Server supports reverse-lookup on wildcard DNS `SAN`](https://github.com/coreos/etcd/pull/8281). For instance, if peer cert contains only DNS names (no IP addresses) in Subject Alternative Name (SAN) field, server first reverse-lookups the remote IP address to get a list of names mapping to that address (e.g. `nslookup IPADDR`). Then accepts the connection if those names have a matching name with peer cert's DNS names (either by exact or wildcard match). If none is matched, server forward-lookups each DNS entry in peer cert (e.g. look up `example.default.svc` when the entry is `*.example.default.svc`), and accepts connection only when the host's resolved addresses have the matching IP address with the peer's remote IP address.
-- Add [`etcd --peer-require-cn`](https://github.com/coreos/etcd/pull/8616) flag.
-  - To support [CommonName(CN) based auth](https://github.com/coreos/etcd/issues/8262) for inter peer connection.
-- [Swap priority](https://github.com/coreos/etcd/pull/8594) of cert CommonName(CN) and username + password.
-  - To address ["username and password specified in the request should take priority over CN in the cert"](https://github.com/coreos/etcd/issues/8584).
-- Protect [lease revoke with auth](https://github.com/coreos/etcd/pull/8031).
-- Provide user's role on [auth permission error](https://github.com/coreos/etcd/pull/8164).
-- Fix [auth store panic with disabled token](https://github.com/coreos/etcd/pull/8695).
-- Update `golang.org/x/crypto/bcrypt` (see [golang/crypto@6c586e1](https://github.com/golang/crypto/commit/6c586e17d90a7d08bbbc4069984180dce3b04117)).
-
-### Fixed(v2)
-
-- [Fail-over v2 client](https://github.com/coreos/etcd/pull/8519) to next endpoint on [oneshot failure](https://github.com/coreos/etcd/issues/8515).
-- [Put back `/v2/machines`](https://github.com/coreos/etcd/pull/8062) endpoint for python-etcd wrapper.
-
-### Fixed(v3)
-
-- Fix [range/put/delete operation metrics](https://github.com/coreos/etcd/pull/8054) with transaction:
-  - `etcd_debugging_mvcc_range_total`
-  - `etcd_debugging_mvcc_put_total`
-  - `etcd_debugging_mvcc_delete_total`
-  - `etcd_debugging_mvcc_txn_total`
-- Fix [`etcd_debugging_mvcc_keys_total`](https://github.com/coreos/etcd/pull/8390) on restore.
-- Fix [`etcd_debugging_mvcc_db_total_size_in_bytes`](https://github.com/coreos/etcd/pull/8120) on restore.
-  - Also change to [`prometheus.NewGaugeFunc`](https://github.com/coreos/etcd/pull/8150).
-- Fix [backend database in-memory index corruption](https://github.com/coreos/etcd/pull/8127) issue on restore (only 3.2.0 is affected).
-- Fix [watch restore from snapshot](https://github.com/coreos/etcd/pull/8427).
-- Fix ["put at-most-once" in `clientv3`](https://github.com/coreos/etcd/pull/8335).
-- Handle [empty key permission](https://github.com/coreos/etcd/pull/8514) in `etcdctl`.
-- [Fix server crash](https://github.com/coreos/etcd/pull/8010) on [invalid transaction request from gRPC gateway](https://github.com/coreos/etcd/issues/7889).
-- Fix [`clientv3.WatchResponse.Canceled`](https://github.com/coreos/etcd/pull/8283) on [compacted watch request](https://github.com/coreos/etcd/issues/8231).
-- Handle [WAL renaming failure on Windows](https://github.com/coreos/etcd/pull/8286).
-- Make [peer dial timeout longer](https://github.com/coreos/etcd/pull/8599).
-  - See [coreos/etcd-operator#1300](https://github.com/coreos/etcd-operator/issues/1300) for more detail.
-- Make server [wait up to request time-out](https://github.com/coreos/etcd/pull/8267) with [pending RPCs](https://github.com/coreos/etcd/issues/8224).
-- Fix [`grpc.Server` panic on `GracefulStop`](https://github.com/coreos/etcd/pull/8987) with [TLS-enabled server](https://github.com/coreos/etcd/issues/8916).
-- Fix ["multiple peer URLs cannot start" issue](https://github.com/coreos/etcd/issues/8383).
-- Fix server-side auth so [concurrent auth operations do not return old revision error](https://github.com/coreos/etcd/pull/8442).
-- Fix [`concurrency/stm` `Put` with serializable snapshot](https://github.com/coreos/etcd/pull/8439).
-  - Use store revision from first fetch to resolve write conflicts instead of modified revision.
-- Fix [`grpc-proxy` Snapshot API error handling](https://github.com/coreos/etcd/commit/dbd16d52fbf81e5fd806d21ff5e9148d5bf203ab).
-- Fix [`grpc-proxy` KV API `PrevKv` flag handling](https://github.com/coreos/etcd/pull/8366).
-- Fix [`grpc-proxy` KV API `KeysOnly` flag handling](https://github.com/coreos/etcd/pull/8552).
-- Upgrade [`coreos/go-systemd`](https://github.com/coreos/go-systemd/releases) to `v15` (see https://github.com/coreos/go-systemd/releases/tag/v15).
-
-### Other
-
-- Support previous two minor versions (see our [new release policy](https://github.com/coreos/etcd/pull/8805)).
-- `v3.3.x` is the last release cycle that supports `ACI`:
-  - AppC was [officially suspended](https://github.com/appc/spec#-disclaimer-), as of late 2016.
-  - [`acbuild`](https://github.com/containers/build#this-project-is-currently-unmaintained) is not maintained anymore.
-  - `*.aci` files won't be available from etcd `v3.4` release.
-- Add container registry [`gcr.io/etcd-development/etcd`](https://gcr.io/etcd-development/etcd).
-  - [quay.io/coreos/etcd](https://quay.io/coreos/etcd) is still supported as secondary.
-
-
-## [v3.2.12](https://github.com/coreos/etcd/releases/tag/v3.2.12) (2017-12-20)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.11...v3.2.12) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Fixed
-
-- Fix [error message of `Revision` compactor](https://github.com/coreos/etcd/pull/8999) in server-side.
-
-### Added(`etcd/clientv3`,`etcdctl/v3`)
-
-- Add [`MaxCallSendMsgSize` and `MaxCallRecvMsgSize`](https://github.com/coreos/etcd/pull/9047) fields to [`clientv3.Config`](https://godoc.org/github.com/coreos/etcd/clientv3#Config).
-  - Fix [exceeded response size limit error in client-side](https://github.com/coreos/etcd/issues/9043).
-  - Address [kubernetes#51099](https://github.com/kubernetes/kubernetes/issues/51099).
-  - `MaxCallSendMsgSize` default value is 2 MiB, if not configured.
-  - `MaxCallRecvMsgSize` default value is `math.MaxInt32`, if not configured.
-
-### Other
-
-- Pin [grpc v1.7.5](https://github.com/grpc/grpc-go/releases/tag/v1.7.5), [grpc-gateway v1.3.0](https://github.com/grpc-ecosystem/grpc-gateway/releases/tag/v1.3.0).
-  - No code change, just to be explicit about recommended versions.
-
-
-## [v3.2.11](https://github.com/coreos/etcd/releases/tag/v3.2.11) (2017-12-05)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.10...v3.2.11) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Fixed
-
-- Fix racey grpc-go's server handler transport `WriteStatus` call to prevent [TLS-enabled etcd server crash](https://github.com/coreos/etcd/issues/8904):
-  - Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) `v1.7.3` to `v1.7.4`.
-  - Add [gRPC RPC failure warnings](https://github.com/coreos/etcd/pull/8939) to help debug such issues in the future.
-- Remove `--listen-metrics-urls` flag in monitoring document (non-released in `v3.2.x`, planned for `v3.3.x`).
-
-### Added
-
-- Provide [more cert details](https://github.com/coreos/etcd/pull/8952/files) on TLS handshake failures.
-
-
-## [v3.1.11](https://github.com/coreos/etcd/releases/tag/v3.1.11) (2017-11-28)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.10...v3.1.11) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Fixed
-
-- [#8411](https://github.com/coreos/etcd/issues/8411),[#8806](https://github.com/coreos/etcd/pull/8806) mvcc: fix watch restore from snapshot
-- [#8009](https://github.com/coreos/etcd/issues/8009),[#8902](https://github.com/coreos/etcd/pull/8902) backport coreos/bbolt v1.3.1-coreos.5
-
-
-## [v3.2.10](https://github.com/coreos/etcd/releases/tag/v3.2.10) (2017-11-16)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.9...v3.2.10) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Fixed
-
-- Replace backend key-value database `boltdb/bolt` with [`coreos/bbolt`](https://github.com/coreos/bbolt/releases) to address [backend database size issue](https://github.com/coreos/etcd/issues/8009).
-- Fix `clientv3` balancer to handle [network partitions](https://github.com/coreos/etcd/issues/8711):
-  - Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) `v1.2.1` to `v1.7.3`.
-  - Upgrade [`github.com/grpc-ecosystem/grpc-gateway`](https://github.com/grpc-ecosystem/grpc-gateway/releases) `v1.2` to `v1.3`.
-- Revert [discovery SRV auth `ServerName` with `*.{ROOT_DOMAIN}`](https://github.com/coreos/etcd/pull/8651) to support non-wildcard subject alternative names in the certs (see [issue #8445](https://github.com/coreos/etcd/issues/8445) for more contexts).
-  - For instance, `etcd --discovery-srv=etcd.local` will only authenticate peers/clients when the provided certs have root domain `etcd.local` (**not `*.etcd.local`**) as an entry in Subject Alternative Name (SAN) field.
-
-
-## [v3.2.9](https://github.com/coreos/etcd/releases/tag/v3.2.9) (2017-10-06)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.8...v3.2.9) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Fixed(Security)
-
-- Compile with [Go 1.8.4](https://groups.google.com/d/msg/golang-nuts/sHfMg4gZNps/a-HDgDDDAAAJ).
-- Update `golang.org/x/crypto/bcrypt` (see [golang/crypto@6c586e1](https://github.com/golang/crypto/commit/6c586e17d90a7d08bbbc4069984180dce3b04117)).
-- Fix discovery SRV bootstrapping to [authenticate `ServerName` with `*.{ROOT_DOMAIN}`](https://github.com/coreos/etcd/pull/8651), in order to support sub-domain wildcard matching (see [issue #8445](https://github.com/coreos/etcd/issues/8445) for more contexts).
-  - For instance, `etcd --discovery-srv=etcd.local` will only authenticate peers/clients when the provided certs have root domain `*.etcd.local` as an entry in Subject Alternative Name (SAN) field.
-
-
-## [v3.2.8](https://github.com/coreos/etcd/releases/tag/v3.2.8) (2017-09-29)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.7...v3.2.8) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Fixed
-
-- Fix v2 client failover to next endpoint on mutable operation.
-- Fix grpc-proxy to respect `KeysOnly` flag.
-
-
-## [v3.2.7](https://github.com/coreos/etcd/releases/tag/v3.2.7) (2017-09-01)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.6...v3.2.7) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Fixed
-
-- Fix server-side auth so concurrent auth operations do not return old revision error.
-- Fix concurrency/stm Put with serializable snapshot
-  - Use store revision from first fetch to resolve write conflicts instead of modified revision.
-
-
-## [v3.2.6](https://github.com/coreos/etcd/releases/tag/v3.2.6) (2017-08-21)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.5...v3.2.6).
-
-### Fixed
-
-- Fix watch restore from snapshot.
-- Fix `etcd_debugging_mvcc_keys_total` inconsistency.
-- Fix multiple URLs for `--listen-peer-urls` flag.
-- Add `--enable-pprof` flag to etcd configuration file format.
-
-
-## [v3.2.5](https://github.com/coreos/etcd/releases/tag/v3.2.5) (2017-08-04)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.4...v3.2.5) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Changed
-
-- Use reverse lookup to match wildcard DNS SAN.
-- Return non-zero exit code on unhealthy `endpoint health`.
-
-### Fixed
-
-- Fix unreachable /metrics endpoint when `--enable-v2=false`.
-- Fix grpc-proxy to respect `PrevKv` flag.
-
-### Added
-
-- Add container registry `gcr.io/etcd-development/etcd`.
-
-
-## [v3.2.4](https://github.com/coreos/etcd/releases/tag/v3.2.4) (2017-07-19)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.3...v3.2.4) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Fixed
-
-- Do not block on active client stream when stopping server
-- Fix gRPC proxy Snapshot RPC error handling
-
-
-## [v3.2.3](https://github.com/coreos/etcd/releases/tag/v3.2.3) (2017-07-14)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.2...v3.2.3) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Fixed
-
-- Let clients establish unlimited streams
-
-### Added
-
-- Tag docker images with minor versions
-  - e.g. `docker pull quay.io/coreos/etcd:v3.2` to fetch latest v3.2 versions
-
-
-## [v3.1.10](https://github.com/coreos/etcd/releases/tag/v3.1.10) (2017-07-14)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.9...v3.1.10) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-### Changed
-
-- Compile with Go 1.8.3 to fix panic on `net/http.CloseNotify`
-
-### Added
-
-- Tag docker images with minor versions.
-  - e.g. `docker pull quay.io/coreos/etcd:v3.1` to fetch latest v3.1 versions.
-
-
-## [v3.2.2](https://github.com/coreos/etcd/releases/tag/v3.2.2) (2017-07-07)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.1...v3.2.2) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Improved
-
-- Rate-limit lease revoke on expiration.
-- Extend leases on promote to avoid queueing effect on lease expiration.
-
-### Fixed
-
-- Use user-provided listen address to connect to gRPC gateway:
-  - `net.Listener` rewrites IPv4 0.0.0.0 to IPv6 [::], breaking IPv6 disabled hosts.
-  - Only v3.2.0, v3.2.1 are affected.
-- Accept connection with matched IP SAN but no DNS match.
-  - Don't check DNS entries in certs if there's a matching IP.
-- Fix 'tools/benchmark' watch command.
-
-
-## [v3.2.1](https://github.com/coreos/etcd/releases/tag/v3.2.1) (2017-06-23)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.2.0...v3.2.1) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Fixed
-
-- Fix backend database in-memory index corruption issue on restore (only 3.2.0 is affected).
-- Fix gRPC gateway Txn marshaling issue.
-- Fix backend database size debugging metrics.
-
-
-## [v3.2.0](https://github.com/coreos/etcd/releases/tag/v3.2.0) (2017-06-09)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.0...v3.2.0) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
-
-### Improved
-
-- Improve backend read concurrency.
-
-### Added
-
-- Embedded etcd
-  - `Etcd.Peers` field is now `[]*peerListener`.
-- RPCs
-  - Add Election, Lock service.
-- Native client etcdserver/api/v3client
-  - client "embedded" in the server.
-- gRPC proxy
-  - Proxy endpoint discovery.
-  - Namespaces.
-  - Coalesce lease requests.
-- v3 client
-  - STM prefetching.
-  - Add namespace feature.
-  - Add `ErrOldCluster` with server version checking.
-  - Translate `WithPrefix()` into `WithFromKey()` for empty key.
-- v3 etcdctl
-  - Add `check perf` command.
-  - Add `--from-key` flag to role grant-permission command.
-  - `lock` command takes an optional command to execute.
-- etcd flags
-  - Add `--enable-v2` flag to configure v2 backend (enabled by default).
-  - Add `--auth-token` flag.
-- `etcd gateway`
-  - Support DNS SRV priority.
-- Auth
-  - Support Watch API.
-  - JWT tokens.
-- Logging, monitoring
-  - Server warns large snapshot operations.
-  - Add `etcd_debugging_server_lease_expired_total` metrics.
-- Security
-  - Deny incoming peer certs with wrong IP SAN.
-  - Resolve TLS `DNSNames` when SAN checking.
-  - Reload TLS certificates on every client connection.
-- Release
-  - Annotate acbuild with supports-systemd-notify.
-  - Add `nsswitch.conf` to Docker container image.
-  - Add ppc64le, arm64(experimental) builds.
-  - Compile with `Go 1.8.3`.
-
-### Changed
-
-- v3 client
-  - `LeaseTimeToLive` returns TTL=-1 resp on lease not found.
-  - `clientv3.NewFromConfigFile` is moved to `clientv3/yaml.NewConfig`.
-  - concurrency package's elections updated to match RPC interfaces.
-  - let client dial endpoints not in the balancer.
-- Dependencies
-  - Update [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) to `v1.2.1`.
-  - Update [`github.com/grpc-ecosystem/grpc-gateway`](https://github.com/grpc-ecosystem/grpc-gateway/releases) to `v1.2.0`.
-
-### Fixed
-
-- Allow v2 snapshot over 512MB.
-
-
-## [v3.1.9](https://github.com/coreos/etcd/releases/tag/v3.1.9) (2017-06-09)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.8...v3.1.9) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-### Fixed
-
-- Allow v2 snapshot over 512MB.
-
-
-## [v3.1.8](https://github.com/coreos/etcd/releases/tag/v3.1.8) (2017-05-19)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.7...v3.1.8) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-
-## [v3.1.7](https://github.com/coreos/etcd/releases/tag/v3.1.7) (2017-04-28)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.6...v3.1.7) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-
-## [v3.1.6](https://github.com/coreos/etcd/releases/tag/v3.1.6) (2017-04-19)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.5...v3.1.6) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-### Changed
-
-- Remove auth check in Status API.
-
-### Fixed
-
-- Fill in Auth API response header.
-
-
-## [v3.1.5](https://github.com/coreos/etcd/releases/tag/v3.1.5) (2017-03-27)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.4...v3.1.5) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-### Added
-
-- Add `/etc/nsswitch.conf` file to alpine-based Docker image.
-
-### Fixed
-
-- Fix raft memory leak issue.
-- Fix Windows file path issues.
-
-
-## [v3.1.4](https://github.com/coreos/etcd/releases/tag/v3.1.4) (2017-03-22)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.3...v3.1.4) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-
-## [v3.1.3](https://github.com/coreos/etcd/releases/tag/v3.1.3) (2017-03-10)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.2...v3.1.3) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-### Changed
-
-- Use machine default host when advertise URLs are default values(`localhost:2379,2380`) AND if listen URL is `0.0.0.0`.
-
-### Fixed
-
-- Fix `etcd gateway` schema handling in DNS discovery.
-- Fix sd_notify behaviors in `gateway`, `grpc-proxy`.
-
-
-## [v3.1.2](https://github.com/coreos/etcd/releases/tag/v3.1.2) (2017-02-24)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.1...v3.1.2) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-### Changed
-
-- Use IPv4 default host, by default (when IPv4 and IPv6 are available).
-
-### Fixed
-
-- Fix `etcd gateway` with multiple endpoints.
-
-
-## [v3.1.1](https://github.com/coreos/etcd/releases/tag/v3.1.1) (2017-02-17)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.1.0...v3.1.1) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-### Changed
-
-- Compile with `Go 1.7.5`.
-
-
-## [v2.3.8](https://github.com/coreos/etcd/releases/tag/v2.3.8) (2017-02-17)
-
-See [code changes](https://github.com/coreos/etcd/compare/v2.3.7...v2.3.8).
-
-### Changed
-
-- Compile with `Go 1.7.5`.
-
-
-## [v3.1.0](https://github.com/coreos/etcd/releases/tag/v3.1.0) (2017-01-20)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.0...v3.1.0) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
-
-### Improved
-
-- Faster linearizable reads (implements Raft read-index).
-- v3 authentication API is now stable.
-
-### Added
-
-- Automatic leadership transfer when leader steps down.
-- etcd flags
-  - `--strict-reconfig-check` flag is set by default.
-  - Add `--log-output` flag.
-  - Add `--metrics` flag.
-- v3 client
-  - Add `SetEndpoints` method; update endpoints at runtime.
-  - Add `Sync` method; auto-update endpoints at runtime.
-  - Add `Lease TimeToLive` API; fetch lease information.
-  - replace Config.Logger field with global logger.
-  - Get API responses are sorted in ascending order by default.
-- v3 etcdctl
-  - Add `lease timetolive` command.
-  - Add `--print-value-only` flag to get command.
-  - Add `--dest-prefix` flag to make-mirror command.
-  - `get` command responses are sorted in ascending order by default.
-- `recipes` now conform to sessions defined in `clientv3/concurrency`.
-- ACI has symlinks to `/usr/local/bin/etcd*`.
-- Experimental gRPC proxy feature.
-
-### Changed
-
-- Deprecated following gRPC metrics in favor of [go-grpc-prometheus](https://github.com/grpc-ecosystem/go-grpc-prometheus):
-  - `etcd_grpc_requests_total`
-  - `etcd_grpc_requests_failed_total`
-  - `etcd_grpc_active_streams`
-  - `etcd_grpc_unary_requests_duration_seconds`
-- etcd uses default route IP if advertise URL is not given.
-- Cluster rejects removing members if quorum will be lost.
-- SRV records (e.g., infra1.example.com) must match the discovery domain (i.e., example.com) if no custom certificate authority is given.
-  - `TLSConfig.ServerName` is ignored with user-provided certificates for backwards compatibility; to be deprecated.
-  - For example, `etcd --discovery-srv=example.com` will only authenticate peers/clients when the provided certs have root domain `example.com` as an entry in Subject Alternative Name (SAN) field.
-- Discovery now has upper limit for waiting on retries.
-- Warn on binding listeners through domain names; to be deprecated.
-
-
-## [v3.0.16](https://github.com/coreos/etcd/releases/tag/v3.0.16) (2016-11-13)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.15...v3.0.16) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-
-## [v3.0.15](https://github.com/coreos/etcd/releases/tag/v3.0.15) (2016-11-11)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.14...v3.0.15) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-### Fixed
-
-- Fix cancel watch request with wrong range end.
-
-
-## [v3.0.14](https://github.com/coreos/etcd/releases/tag/v3.0.14) (2016-11-04)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.13...v3.0.14) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-### Added
-
-- v3 `etcdctl migrate` command now supports `--no-ttl` flag to discard keys on transform.
-
-
-## [v3.0.13](https://github.com/coreos/etcd/releases/tag/v3.0.13) (2016-10-24)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.12...v3.0.13) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-
-## [v3.0.12](https://github.com/coreos/etcd/releases/tag/v3.0.12) (2016-10-07)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.11...v3.0.12) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-
-## [v3.0.11](https://github.com/coreos/etcd/releases/tag/v3.0.11) (2016-10-07)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.10...v3.0.11) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-### Added
-
-- Server returns previous key-value (optional)
-  - `clientv3.WithPrevKV` option
-  - v3 etcdctl `put,watch,del --prev-kv` flag
-
-
-## [v3.0.10](https://github.com/coreos/etcd/releases/tag/v3.0.10) (2016-09-23)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.9...v3.0.10) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-
-## [v3.0.9](https://github.com/coreos/etcd/releases/tag/v3.0.9) (2016-09-15)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.8...v3.0.9) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-### Added
-
-- Warn on domain names on listen URLs (v3.2 will reject domain names).
-
-
-## [v3.0.8](https://github.com/coreos/etcd/releases/tag/v3.0.8) (2016-09-09)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.7...v3.0.8) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-### Changed
-
-- Allow only IP addresses in listen URLs (domain names are rejected).
-
-
-## [v3.0.7](https://github.com/coreos/etcd/releases/tag/v3.0.7) (2016-08-31)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.6...v3.0.7) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-### Changed
-
-- SRV records only allow A records (RFC 2052).
-
-
-## [v3.0.6](https://github.com/coreos/etcd/releases/tag/v3.0.6) (2016-08-19)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.5...v3.0.6) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-
-## [v3.0.5](https://github.com/coreos/etcd/releases/tag/v3.0.5) (2016-08-19)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.4...v3.0.5) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-### Changed
-
-- SRV records (e.g., infra1.example.com) must match the discovery domain (i.e., example.com) if no custom certificate authority is given.
-
-
-## [v3.0.4](https://github.com/coreos/etcd/releases/tag/v3.0.4) (2016-07-27)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.3...v3.0.4) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-### Changed
-
-- v2 auth can now use common name from TLS certificate when `--client-cert-auth` is enabled.
-
-### Added
-
-- v2 `etcdctl ls` command now supports `--output=json`.
-- Add /var/lib/etcd directory to etcd official Docker image.
-
-
-## [v3.0.3](https://github.com/coreos/etcd/releases/tag/v3.0.3) (2016-07-15)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.2...v3.0.3) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-### Changed
-
-- Revert Dockerfile to use `CMD`, instead of `ENTRYPOINT`, to support `etcdctl` run.
-  - Docker commands for v3.0.2 won't work without specifying executable binary paths.
-- v3 etcdctl default endpoints are now `127.0.0.1:2379`.
-
-
-## [v3.0.2](https://github.com/coreos/etcd/releases/tag/v3.0.2) (2016-07-08)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.1...v3.0.2) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-### Changed
-
-- Dockerfile uses `ENTRYPOINT`, instead of `CMD`, to run etcd without binary path specified.
-
-
-## [v3.0.1](https://github.com/coreos/etcd/releases/tag/v3.0.1) (2016-07-01)
-
-See [code changes](https://github.com/coreos/etcd/compare/v3.0.0...v3.0.1) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
-
-
-## [v3.0.0](https://github.com/coreos/etcd/releases/tag/v3.0.0) (2016-06-30)
-
-See [code changes](https://github.com/coreos/etcd/compare/v2.3.0...v3.0.0) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
diff --git a/vendor/github.com/coreos/etcd/CODE_OF_CONDUCT.md b/vendor/github.com/coreos/etcd/CODE_OF_CONDUCT.md
deleted file mode 100644
index c0c20dd..0000000
--- a/vendor/github.com/coreos/etcd/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,63 +0,0 @@
-## CoreOS Community Code of Conduct
-
-### Contributor Code of Conduct
-
-As contributors and maintainers of this project, and in the interest of
-fostering an open and welcoming community, we pledge to respect all people who
-contribute through reporting issues, posting feature requests, updating
-documentation, submitting pull requests or patches, and other activities.
-
-We are committed to making participation in this project a harassment-free
-experience for everyone, regardless of level of experience, gender, gender
-identity and expression, sexual orientation, disability, personal appearance,
-body size, race, ethnicity, age, religion, or nationality.
-
-Examples of unacceptable behavior by participants include:
-
-* The use of sexualized language or imagery
-* Personal attacks
-* Trolling or insulting/derogatory comments
-* Public or private harassment
-* Publishing others' private information, such as physical or electronic addresses, without explicit permission
-* Other unethical or unprofessional conduct.
-
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct. By adopting this Code of Conduct,
-project maintainers commit themselves to fairly and consistently applying these
-principles to every aspect of managing this project. Project maintainers who do
-not follow or enforce the Code of Conduct may be permanently removed from the
-project team.
-
-This code of conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community.
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting a project maintainer, Brandon Philips
-<brandon.philips@coreos.com>, and/or Meghan Schofield
-<meghan.schofield@coreos.com>.
-
-This Code of Conduct is adapted from the Contributor Covenant
-(http://contributor-covenant.org), version 1.2.0, available at
-http://contributor-covenant.org/version/1/2/0/
-
-### CoreOS Events Code of Conduct
-
-CoreOS events are working conferences intended for professional networking and
-collaboration in the CoreOS community. Attendees are expected to behave
-according to professional standards and in accordance with their employer’s
-policies on appropriate workplace behavior.
-
-While at CoreOS events or related social networking opportunities, attendees
-should not engage in discriminatory or offensive speech or actions including
-but not limited to gender, sexuality, race, age, disability, or religion.
-Speakers should be especially aware of these concerns.
-
-CoreOS does not condone any statements by speakers contrary to these standards.
-CoreOS reserves the right to deny entrance and/or eject from an event (without
-refund) any individual found to be engaging in discriminatory or offensive
-speech or actions.
-
-Please bring any concerns to the immediate attention of designated on-site
-staff, Brandon Philips <brandon.philips@coreos.com>, and/or Meghan Schofield
-<meghan.schofield@coreos.com>.
diff --git a/vendor/github.com/coreos/etcd/CONTRIBUTING.md b/vendor/github.com/coreos/etcd/CONTRIBUTING.md
deleted file mode 100644
index 31cef1f..0000000
--- a/vendor/github.com/coreos/etcd/CONTRIBUTING.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# How to contribute
-
-etcd is Apache 2.0 licensed and accepts contributions via GitHub pull requests. This document outlines some of the conventions on commit message formatting, contact points for developers, and other resources to help get contributions into etcd.
-
-# Email and chat
-
-- Email: [etcd-dev](https://groups.google.com/forum/?hl=en#!forum/etcd-dev)
-- IRC: #[etcd](irc://irc.freenode.org:6667/#etcd) IRC channel on freenode.org
-
-## Getting started
-
-- Fork the repository on GitHub
-- Read the README.md for build instructions
-
-## Reporting bugs and creating issues
-
-Reporting bugs is one of the best ways to contribute. However, a good bug report has some very specific qualities, so please read over our short document on [reporting bugs](https://github.com/coreos/etcd/blob/master/Documentation/reporting_bugs.md) before submitting a bug report. This document might contain links to known issues, another good reason to take a look there before reporting a bug.
-
-## Contribution flow
-
-This is a rough outline of what a contributor's workflow looks like:
-
-- Create a topic branch from where to base the contribution. This is usually master.
-- Make commits of logical units.
-- Make sure commit messages are in the proper format (see below).
-- Push changes in a topic branch to a personal fork of the repository.
-- Submit a pull request to coreos/etcd.
-- The PR must receive a LGTM from two maintainers found in the MAINTAINERS file.
-
-Thanks for contributing!
-
-### Code style
-
-The coding style suggested by the Golang community is used in etcd. See the [style doc](https://github.com/golang/go/wiki/CodeReviewComments) for details.
-
-Please follow this style to make etcd easy to review, maintain and develop.
-
-### Format of the commit message
-
-We follow a rough convention for commit messages that is designed to answer two
-questions: what changed and why. The subject line should feature the what and
-the body of the commit should describe the why.
-
-```
-scripts: add the test-cluster command
-
-this uses tmux to setup a test cluster that can easily be killed and started for debugging.
-
-Fixes #38
-```
-
-The format can be described more formally as follows:
-
-```
-<subsystem>: <what changed>
-<BLANK LINE>
-<why this change was made>
-<BLANK LINE>
-<footer>
-```
-
-The first line is the subject and should be no longer than 70 characters, the second line is always blank, and other lines should be wrapped at 80 characters. This allows the message to be easier to read on GitHub as well as in various git tools.
diff --git a/vendor/github.com/coreos/etcd/DCO b/vendor/github.com/coreos/etcd/DCO
deleted file mode 100644
index 716561d..0000000
--- a/vendor/github.com/coreos/etcd/DCO
+++ /dev/null
@@ -1,36 +0,0 @@
-Developer Certificate of Origin
-Version 1.1
-
-Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
-660 York Street, Suite 102,
-San Francisco, CA 94110 USA
-
-Everyone is permitted to copy and distribute verbatim copies of this
-license document, but changing it is not allowed.
-
-
-Developer's Certificate of Origin 1.1
-
-By making a contribution to this project, I certify that:
-
-(a) The contribution was created in whole or in part by me and I
-    have the right to submit it under the open source license
-    indicated in the file; or
-
-(b) The contribution is based upon previous work that, to the best
-    of my knowledge, is covered under an appropriate open source
-    license and I have the right under that license to submit that
-    work with modifications, whether created in whole or in part
-    by me, under the same open source license (unless I am
-    permitted to submit under a different license), as indicated
-    in the file; or
-
-(c) The contribution was provided directly to me by some other
-    person who certified (a), (b) or (c) and I have not modified
-    it.
-
-(d) I understand and agree that this project and the contribution
-    are public and that a record of the contribution (including all
-    personal information I submit with it, including my sign-off) is
-    maintained indefinitely and may be redistributed consistent with
-    this project or the open source license(s) involved.
diff --git a/vendor/github.com/coreos/etcd/Dockerfile b/vendor/github.com/coreos/etcd/Dockerfile
deleted file mode 100644
index c653734..0000000
--- a/vendor/github.com/coreos/etcd/Dockerfile
+++ /dev/null
@@ -1,6 +0,0 @@
-FROM golang
-ADD . /go/src/github.com/coreos/etcd
-ADD cmd/vendor /go/src/github.com/coreos/etcd/vendor
-RUN go install github.com/coreos/etcd
-EXPOSE 2379 2380
-ENTRYPOINT ["etcd"]
diff --git a/vendor/github.com/coreos/etcd/Dockerfile-functional-tester b/vendor/github.com/coreos/etcd/Dockerfile-functional-tester
deleted file mode 100644
index cfd8086..0000000
--- a/vendor/github.com/coreos/etcd/Dockerfile-functional-tester
+++ /dev/null
@@ -1,53 +0,0 @@
-FROM ubuntu:17.10
-
-RUN rm /bin/sh && ln -s /bin/bash /bin/sh
-RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
-
-RUN apt-get -y update \
-  && apt-get -y install \
-  build-essential \
-  gcc \
-  apt-utils \
-  pkg-config \
-  software-properties-common \
-  apt-transport-https \
-  libssl-dev \
-  sudo \
-  bash \
-  curl \
-  wget \
-  tar \
-  git \
-  && apt-get -y update \
-  && apt-get -y upgrade \
-  && apt-get -y autoremove \
-  && apt-get -y autoclean
-
-ENV GOROOT /usr/local/go
-ENV GOPATH /go
-ENV PATH ${GOPATH}/bin:${GOROOT}/bin:${PATH}
-ENV GO_VERSION REPLACE_ME_GO_VERSION
-ENV GO_DOWNLOAD_URL https://storage.googleapis.com/golang
-RUN rm -rf ${GOROOT} \
-  && curl -s ${GO_DOWNLOAD_URL}/go${GO_VERSION}.linux-amd64.tar.gz | tar -v -C /usr/local/ -xz \
-  && mkdir -p ${GOPATH}/src ${GOPATH}/bin \
-  && go version
-
-RUN mkdir -p ${GOPATH}/src/github.com/coreos/etcd
-ADD . ${GOPATH}/src/github.com/coreos/etcd
-
-RUN go get -v github.com/coreos/gofail \
-  && pushd ${GOPATH}/src/github.com/coreos/etcd \
-  && GO_BUILD_FLAGS="-v" ./build \
-  && cp ./bin/etcd /etcd \
-  && cp ./bin/etcdctl /etcdctl \
-  && GO_BUILD_FLAGS="-v" FAILPOINTS=1 ./build \
-  && cp ./bin/etcd /etcd-failpoints \
-  && ./tools/functional-tester/build \
-  && cp ./bin/etcd-agent /etcd-agent \
-  && cp ./bin/etcd-tester /etcd-tester \
-  && cp ./bin/etcd-runner /etcd-runner \
-  && go build -v -o /benchmark ./cmd/tools/benchmark \
-  && go build -v -o /etcd-test-proxy ./cmd/tools/etcd-test-proxy \
-  && popd \
-  && rm -rf ${GOPATH}/src/github.com/coreos/etcd
diff --git a/vendor/github.com/coreos/etcd/Dockerfile-release b/vendor/github.com/coreos/etcd/Dockerfile-release
deleted file mode 100644
index 736445f..0000000
--- a/vendor/github.com/coreos/etcd/Dockerfile-release
+++ /dev/null
@@ -1,17 +0,0 @@
-FROM alpine:latest
-
-ADD etcd /usr/local/bin/
-ADD etcdctl /usr/local/bin/
-RUN mkdir -p /var/etcd/
-RUN mkdir -p /var/lib/etcd/
-
-# Alpine Linux doesn't use pam, which means that there is no /etc/nsswitch.conf,
-# but Golang relies on /etc/nsswitch.conf to check the order of DNS resolving
-# (see https://github.com/golang/go/commit/9dee7771f561cf6aee081c0af6658cc81fac3918)
-# To fix this we just create /etc/nsswitch.conf and add the following line:
-RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
-
-EXPOSE 2379 2380
-
-# Define default command.
-CMD ["/usr/local/bin/etcd"]
diff --git a/vendor/github.com/coreos/etcd/Dockerfile-release.arm64 b/vendor/github.com/coreos/etcd/Dockerfile-release.arm64
deleted file mode 100644
index d8816e5..0000000
--- a/vendor/github.com/coreos/etcd/Dockerfile-release.arm64
+++ /dev/null
@@ -1,11 +0,0 @@
-FROM aarch64/ubuntu:16.04
-
-ADD etcd /usr/local/bin/
-ADD etcdctl /usr/local/bin/
-ADD var/etcd /var/etcd
-ADD var/lib/etcd /var/lib/etcd
-
-EXPOSE 2379 2380
-
-# Define default command.
-CMD ["/usr/local/bin/etcd"]
diff --git a/vendor/github.com/coreos/etcd/Dockerfile-release.ppc64le b/vendor/github.com/coreos/etcd/Dockerfile-release.ppc64le
deleted file mode 100644
index 2fb02c4..0000000
--- a/vendor/github.com/coreos/etcd/Dockerfile-release.ppc64le
+++ /dev/null
@@ -1,11 +0,0 @@
-FROM ppc64le/ubuntu:16.04
-
-ADD etcd /usr/local/bin/
-ADD etcdctl /usr/local/bin/
-ADD var/etcd /var/etcd
-ADD var/lib/etcd /var/lib/etcd
-
-EXPOSE 2379 2380
-
-# Define default command.
-CMD ["/usr/local/bin/etcd"]
diff --git a/vendor/github.com/coreos/etcd/Dockerfile-test b/vendor/github.com/coreos/etcd/Dockerfile-test
deleted file mode 100644
index dea3ab0..0000000
--- a/vendor/github.com/coreos/etcd/Dockerfile-test
+++ /dev/null
@@ -1,58 +0,0 @@
-FROM ubuntu:16.10
-
-RUN rm /bin/sh && ln -s /bin/bash /bin/sh
-RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
-
-RUN apt-get -y update \
-  && apt-get -y install \
-  build-essential \
-  gcc \
-  apt-utils \
-  pkg-config \
-  software-properties-common \
-  apt-transport-https \
-  libssl-dev \
-  sudo \
-  bash \
-  curl \
-  wget \
-  tar \
-  git \
-  netcat \
-  libaspell-dev \
-  libhunspell-dev \
-  hunspell-en-us \
-  aspell-en \
-  shellcheck \
-  && apt-get -y update \
-  && apt-get -y upgrade \
-  && apt-get -y autoremove \
-  && apt-get -y autoclean
-
-ENV GOROOT /usr/local/go
-ENV GOPATH /go
-ENV PATH ${GOPATH}/bin:${GOROOT}/bin:${PATH}
-ENV GO_VERSION REPLACE_ME_GO_VERSION
-ENV GO_DOWNLOAD_URL https://storage.googleapis.com/golang
-RUN rm -rf ${GOROOT} \
-  && curl -s ${GO_DOWNLOAD_URL}/go${GO_VERSION}.linux-amd64.tar.gz | tar -v -C /usr/local/ -xz \
-  && mkdir -p ${GOPATH}/src ${GOPATH}/bin \
-  && go version
-
-RUN mkdir -p ${GOPATH}/src/github.com/coreos/etcd
-WORKDIR ${GOPATH}/src/github.com/coreos/etcd
-
-ADD ./scripts/install-marker.sh /tmp/install-marker.sh
-
-RUN go get -v -u -tags spell github.com/chzchzchz/goword \
-  && go get -v -u github.com/coreos/license-bill-of-materials \
-  && go get -v -u honnef.co/go/tools/cmd/gosimple \
-  && go get -v -u honnef.co/go/tools/cmd/unused \
-  && go get -v -u honnef.co/go/tools/cmd/staticcheck \
-  && go get -v -u github.com/gyuho/gocovmerge \
-  && go get -v -u github.com/gordonklaus/ineffassign \
-  && go get -v -u github.com/alexkohler/nakedret \
-  && /tmp/install-marker.sh amd64 \
-  && rm -f /tmp/install-marker.sh \
-  && curl -s https://codecov.io/bash >/codecov \
-  && chmod 700 /codecov
diff --git a/vendor/github.com/coreos/etcd/MAINTAINERS b/vendor/github.com/coreos/etcd/MAINTAINERS
deleted file mode 100644
index 9983e3c..0000000
--- a/vendor/github.com/coreos/etcd/MAINTAINERS
+++ /dev/null
@@ -1,8 +0,0 @@
-Anthony Romano <anthony.romano@coreos.com> (@heyitsanthony) pkg:*
-Brandon Philips <brandon.philips@coreos.com> (@philips) pkg:*
-Fanmin Shi <fanmin.shi@coreos.com> (@fanminshi) pkg:*
-Gyu-Ho Lee <gyu_ho.lee@coreos.com> (@gyuho) pkg:*
-Xiang Li <xiang.li@coreos.com> (@xiang90) pkg:*
-
-Ben Darnell <ben@cockroachlabs.com> (@bdarnell) pkg:github.com/coreos/etcd/raft
-Hitoshi Mitake <mitake.hitoshi@lab.ntt.co.jp> (@mitake) pkg:github.com/coreos/etcd/auth
diff --git a/vendor/github.com/coreos/etcd/Makefile b/vendor/github.com/coreos/etcd/Makefile
deleted file mode 100644
index a8eceef..0000000
--- a/vendor/github.com/coreos/etcd/Makefile
+++ /dev/null
@@ -1,517 +0,0 @@
-# run from repository root
-
-
-
-# Example:
-#   make build
-#   make clean
-#   make docker-clean
-#   make docker-start
-#   make docker-kill
-#   make docker-remove
-
-.PHONY: build
-build:
-	GO_BUILD_FLAGS="-v" ./build
-	./bin/etcd --version
-	ETCDCTL_API=3 ./bin/etcdctl version
-
-clean:
-	rm -f ./codecov
-	rm -rf ./agent-*
-	rm -rf ./covdir
-	rm -f ./*.coverprofile
-	rm -f ./*.log
-	rm -f ./bin/Dockerfile-release
-	rm -rf ./bin/*.etcd
-	rm -rf ./default.etcd
-	rm -rf ./tests/e2e/default.etcd
-	rm -rf ./gopath
-	rm -rf ./gopath.proto
-	rm -rf ./release
-	rm -f ./snapshot/localhost:*
-	rm -f ./integration/127.0.0.1:* ./integration/localhost:*
-	rm -f ./clientv3/integration/127.0.0.1:* ./clientv3/integration/localhost:*
-	rm -f ./clientv3/ordering/127.0.0.1:* ./clientv3/ordering/localhost:*
-
-docker-clean:
-	docker images
-	docker image prune --force
-
-docker-start:
-	service docker restart
-
-docker-kill:
-	docker kill `docker ps -q` || true
-
-docker-remove:
-	docker rm --force `docker ps -a -q` || true
-	docker rmi --force `docker images -q` || true
-
-
-
-GO_VERSION ?= 1.10.3
-ETCD_VERSION ?= $(shell git rev-parse --short HEAD || echo "GitNotFound")
-
-TEST_SUFFIX = $(shell date +%s | base64 | head -c 15)
-TEST_OPTS ?= PASSES='unit'
-
-TMP_DIR_MOUNT_FLAG = --mount type=tmpfs,destination=/tmp
-ifdef HOST_TMP_DIR
-	TMP_DIR_MOUNT_FLAG = --mount type=bind,source=$(HOST_TMP_DIR),destination=/tmp
-endif
-
-
-
-# Example:
-#   GO_VERSION=1.8.7 make build-docker-test
-#   make build-docker-test
-#
-#   gcloud docker -- login -u _json_key -p "$(cat /etc/gcp-key-etcd-development.json)" https://gcr.io
-#   GO_VERSION=1.8.7 make push-docker-test
-#   make push-docker-test
-#
-#   gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com
-#   make pull-docker-test
-
-build-docker-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	@sed -i.bak 's|REPLACE_ME_GO_VERSION|$(GO_VERSION)|g' ./tests/Dockerfile
-	docker build \
-	  --tag gcr.io/etcd-development/etcd-test:go$(GO_VERSION) \
-	  --file ./tests/Dockerfile .
-	@mv ./tests/Dockerfile.bak ./tests/Dockerfile
-
-push-docker-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	gcloud docker -- push gcr.io/etcd-development/etcd-test:go$(GO_VERSION)
-
-pull-docker-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	docker pull gcr.io/etcd-development/etcd-test:go$(GO_VERSION)
-
-
-
-# Example:
-#   make build-docker-test
-#   make compile-with-docker-test
-#   make compile-setup-gopath-with-docker-test
-
-compile-with-docker-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	docker run \
-	  --rm \
-	  --mount type=bind,source=`pwd`,destination=/go/src/github.com/coreos/etcd \
-	  gcr.io/etcd-development/etcd-test:go$(GO_VERSION) \
-	  /bin/bash -c "GO_BUILD_FLAGS=-v ./build && ./bin/etcd --version"
-
-compile-setup-gopath-with-docker-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	docker run \
-	  --rm \
-	  --mount type=bind,source=`pwd`,destination=/etcd \
-	  gcr.io/etcd-development/etcd-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && ETCD_SETUP_GOPATH=1 GO_BUILD_FLAGS=-v ./build && ./bin/etcd --version && rm -rf ./gopath"
-
-
-
-# Example:
-#
-# Local machine:
-#   TEST_OPTS="PASSES='fmt'" make test
-#   TEST_OPTS="PASSES='fmt bom dep build unit'" make test
-#   TEST_OPTS="PASSES='build unit release integration_e2e functional'" make test
-#   TEST_OPTS="PASSES='build grpcproxy'" make test
-#
-# Example (test with docker):
-#   make pull-docker-test
-#   TEST_OPTS="PASSES='fmt'" make docker-test
-#   TEST_OPTS="VERBOSE=2 PASSES='unit'" make docker-test
-#
-# Travis CI (test with docker):
-#   TEST_OPTS="PASSES='fmt bom dep build unit'" make docker-test
-#
-# Semaphore CI (test with docker):
-#   TEST_OPTS="PASSES='build unit release integration_e2e functional'" make docker-test
-#   HOST_TMP_DIR=/tmp TEST_OPTS="PASSES='build unit release integration_e2e functional'" make docker-test
-#   TEST_OPTS="GOARCH=386 PASSES='build unit integration_e2e'" make docker-test
-#
-# grpc-proxy tests (test with docker):
-#   TEST_OPTS="PASSES='build grpcproxy'" make docker-test
-#   HOST_TMP_DIR=/tmp TEST_OPTS="PASSES='build grpcproxy'" make docker-test
-
-.PHONY: test
-test:
-	$(info TEST_OPTS: $(TEST_OPTS))
-	$(info log-file: test-$(TEST_SUFFIX).log)
-	$(TEST_OPTS) ./test 2>&1 | tee test-$(TEST_SUFFIX).log
-	! egrep "(--- FAIL:|panic: test timed out|appears to have leaked)" -B50 -A10 test-$(TEST_SUFFIX).log
-
-docker-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info ETCD_VERSION: $(ETCD_VERSION))
-	$(info TEST_OPTS: $(TEST_OPTS))
-	$(info log-file: test-$(TEST_SUFFIX).log)
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`,destination=/go/src/github.com/coreos/etcd \
-	  gcr.io/etcd-development/etcd-test:go$(GO_VERSION) \
-	  /bin/bash -c "$(TEST_OPTS) ./test 2>&1 | tee test-$(TEST_SUFFIX).log"
-	! egrep "(--- FAIL:|panic: test timed out|appears to have leaked)" -B50 -A10 test-$(TEST_SUFFIX).log
-
-docker-test-coverage:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info ETCD_VERSION: $(ETCD_VERSION))
-	$(info log-file: docker-test-coverage-$(TEST_SUFFIX).log)
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`,destination=/go/src/github.com/coreos/etcd \
-	  gcr.io/etcd-development/etcd-test:go$(GO_VERSION) \
-	  /bin/bash -c "COVERDIR=covdir PASSES='build build_cov cov' ./test 2>&1 | tee docker-test-coverage-$(TEST_SUFFIX).log && /codecov -t 6040de41-c073-4d6f-bbf8-d89256ef31e1"
-	! egrep "(--- FAIL:|panic: test timed out|appears to have leaked)" -B50 -A10 docker-test-coverage-$(TEST_SUFFIX).log
-
-
-
-# Example:
-#   make compile-with-docker-test
-#   ETCD_VERSION=v3-test make build-docker-release-master
-#   ETCD_VERSION=v3-test make push-docker-release-master
-#   gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com
-
-build-docker-release-master:
-	$(info ETCD_VERSION: $(ETCD_VERSION))
-	cp ./Dockerfile-release ./bin/Dockerfile-release
-	docker build \
-	  --tag gcr.io/etcd-development/etcd:$(ETCD_VERSION) \
-	  --file ./bin/Dockerfile-release \
-	  ./bin
-	rm -f ./bin/Dockerfile-release
-
-	docker run \
-	  --rm \
-	  gcr.io/etcd-development/etcd:$(ETCD_VERSION) \
-	  /bin/sh -c "/usr/local/bin/etcd --version && ETCDCTL_API=3 /usr/local/bin/etcdctl version"
-
-push-docker-release-master:
-	$(info ETCD_VERSION: $(ETCD_VERSION))
-	gcloud docker -- push gcr.io/etcd-development/etcd:$(ETCD_VERSION)
-
-
-
-# Example:
-#   make build-docker-test
-#   make compile-with-docker-test
-#   make build-docker-static-ip-test
-#
-#   gcloud docker -- login -u _json_key -p "$(cat /etc/gcp-key-etcd-development.json)" https://gcr.io
-#   make push-docker-static-ip-test
-#
-#   gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com
-#   make pull-docker-static-ip-test
-#
-#   make docker-static-ip-test-certs-run
-#   make docker-static-ip-test-certs-metrics-proxy-run
-
-build-docker-static-ip-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	@sed -i.bak 's|REPLACE_ME_GO_VERSION|$(GO_VERSION)|g' ./tests/docker-static-ip/Dockerfile
-	docker build \
-	  --tag gcr.io/etcd-development/etcd-static-ip-test:go$(GO_VERSION) \
-	  --file ./tests/docker-static-ip/Dockerfile \
-	  ./tests/docker-static-ip
-	@mv ./tests/docker-static-ip/Dockerfile.bak ./tests/docker-static-ip/Dockerfile
-
-push-docker-static-ip-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	gcloud docker -- push gcr.io/etcd-development/etcd-static-ip-test:go$(GO_VERSION)
-
-pull-docker-static-ip-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	docker pull gcr.io/etcd-development/etcd-static-ip-test:go$(GO_VERSION)
-
-docker-static-ip-test-certs-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-static-ip/certs,destination=/certs \
-	  gcr.io/etcd-development/etcd-static-ip-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /certs/run.sh && rm -rf m*.etcd"
-
-docker-static-ip-test-certs-metrics-proxy-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-static-ip/certs-metrics-proxy,destination=/certs-metrics-proxy \
-	  gcr.io/etcd-development/etcd-static-ip-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /certs-metrics-proxy/run.sh && rm -rf m*.etcd"
-
-
-
-# Example:
-#   make build-docker-test
-#   make compile-with-docker-test
-#   make build-docker-dns-test
-#
-#   gcloud docker -- login -u _json_key -p "$(cat /etc/gcp-key-etcd-development.json)" https://gcr.io
-#   make push-docker-dns-test
-#
-#   gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com
-#   make pull-docker-dns-test
-#
-#   make docker-dns-test-insecure-run
-#   make docker-dns-test-certs-run
-#   make docker-dns-test-certs-gateway-run
-#   make docker-dns-test-certs-wildcard-run
-#   make docker-dns-test-certs-common-name-auth-run
-#   make docker-dns-test-certs-common-name-multi-run
-
-build-docker-dns-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	@sed -i.bak 's|REPLACE_ME_GO_VERSION|$(GO_VERSION)|g' ./tests/docker-dns/Dockerfile
-	docker build \
-	  --tag gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
-	  --file ./tests/docker-dns/Dockerfile \
-	  ./tests/docker-dns
-	@mv ./tests/docker-dns/Dockerfile.bak ./tests/docker-dns/Dockerfile
-
-	docker run \
-	  --rm \
-	  --dns 127.0.0.1 \
-	  gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
-	  /bin/bash -c "/etc/init.d/bind9 start && cat /dev/null >/etc/hosts && dig etcd.local"
-
-push-docker-dns-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	gcloud docker -- push gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION)
-
-pull-docker-dns-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	docker pull gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION)
-
-docker-dns-test-insecure-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  --dns 127.0.0.1 \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-dns/insecure,destination=/insecure \
-	  gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /insecure/run.sh && rm -rf m*.etcd"
-
-docker-dns-test-certs-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  --dns 127.0.0.1 \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-dns/certs,destination=/certs \
-	  gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /certs/run.sh && rm -rf m*.etcd"
-
-docker-dns-test-certs-gateway-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  --dns 127.0.0.1 \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-dns/certs-gateway,destination=/certs-gateway \
-	  gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /certs-gateway/run.sh && rm -rf m*.etcd"
-
-docker-dns-test-certs-wildcard-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  --dns 127.0.0.1 \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-dns/certs-wildcard,destination=/certs-wildcard \
-	  gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /certs-wildcard/run.sh && rm -rf m*.etcd"
-
-docker-dns-test-certs-common-name-auth-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  --dns 127.0.0.1 \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-dns/certs-common-name-auth,destination=/certs-common-name-auth \
-	  gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /certs-common-name-auth/run.sh && rm -rf m*.etcd"
-
-docker-dns-test-certs-common-name-multi-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  --dns 127.0.0.1 \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-dns/certs-common-name-multi,destination=/certs-common-name-multi \
-	  gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /certs-common-name-multi/run.sh && rm -rf m*.etcd"
-
-
-
-# Example:
-#   make build-docker-test
-#   make compile-with-docker-test
-#   make build-docker-dns-srv-test
-#   gcloud docker -- login -u _json_key -p "$(cat /etc/gcp-key-etcd-development.json)" https://gcr.io
-#   make push-docker-dns-srv-test
-#   gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com
-#   make pull-docker-dns-srv-test
-#   make docker-dns-srv-test-certs-run
-#   make docker-dns-srv-test-certs-gateway-run
-#   make docker-dns-srv-test-certs-wildcard-run
-
-build-docker-dns-srv-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	@sed -i.bak 's|REPLACE_ME_GO_VERSION|$(GO_VERSION)|g' ./tests/docker-dns-srv/Dockerfile
-	docker build \
-	  --tag gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION) \
-	  --file ./tests/docker-dns-srv/Dockerfile \
-	  ./tests/docker-dns-srv
-	@mv ./tests/docker-dns-srv/Dockerfile.bak ./tests/docker-dns-srv/Dockerfile
-
-	docker run \
-	  --rm \
-	  --dns 127.0.0.1 \
-	  gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION) \
-	  /bin/bash -c "/etc/init.d/bind9 start && cat /dev/null >/etc/hosts && dig +noall +answer SRV _etcd-client-ssl._tcp.etcd.local && dig +noall +answer SRV _etcd-server-ssl._tcp.etcd.local && dig +noall +answer m1.etcd.local m2.etcd.local m3.etcd.local"
-
-push-docker-dns-srv-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	gcloud docker -- push gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION)
-
-pull-docker-dns-srv-test:
-	$(info GO_VERSION: $(GO_VERSION))
-	docker pull gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION)
-
-docker-dns-srv-test-certs-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  --dns 127.0.0.1 \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-dns-srv/certs,destination=/certs \
-	  gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /certs/run.sh && rm -rf m*.etcd"
-
-docker-dns-srv-test-certs-gateway-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  --dns 127.0.0.1 \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-dns-srv/certs-gateway,destination=/certs-gateway \
-	  gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /certs-gateway/run.sh && rm -rf m*.etcd"
-
-docker-dns-srv-test-certs-wildcard-run:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
-	$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
-	docker run \
-	  --rm \
-	  --tty \
-	  --dns 127.0.0.1 \
-	  $(TMP_DIR_MOUNT_FLAG) \
-	  --mount type=bind,source=`pwd`/bin,destination=/etcd \
-	  --mount type=bind,source=`pwd`/tests/docker-dns-srv/certs-wildcard,destination=/certs-wildcard \
-	  gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION) \
-	  /bin/bash -c "cd /etcd && /certs-wildcard/run.sh && rm -rf m*.etcd"
-
-
-
-# Example:
-#   make build-functional
-#   make build-docker-functional
-#   make push-docker-functional
-#   make pull-docker-functional
-
-build-functional:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info ETCD_VERSION: $(ETCD_VERSION))
-	./functional/build
-	./bin/etcd-agent -help || true && \
-	  ./bin/etcd-proxy -help || true && \
-	  ./bin/etcd-runner --help || true && \
-	  ./bin/etcd-tester -help || true
-
-build-docker-functional:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info ETCD_VERSION: $(ETCD_VERSION))
-	@sed -i.bak 's|REPLACE_ME_GO_VERSION|$(GO_VERSION)|g' ./functional/Dockerfile
-	docker build \
-	  --tag gcr.io/etcd-development/etcd-functional:go$(GO_VERSION) \
-	  --file ./functional/Dockerfile \
-	  .
-	@mv ./functional/Dockerfile.bak ./functional/Dockerfile
-
-	docker run \
-	  --rm \
-	  gcr.io/etcd-development/etcd-functional:go$(GO_VERSION) \
-	  /bin/bash -c "./bin/etcd --version && \
-	   ./bin/etcd-failpoints --version && \
-	   ETCDCTL_API=3 ./bin/etcdctl version && \
-	   ./bin/etcd-agent -help || true && \
-	   ./bin/etcd-proxy -help || true && \
-	   ./bin/etcd-runner --help || true && \
-	   ./bin/etcd-tester -help || true && \
-	   ./bin/benchmark --help || true"
-
-push-docker-functional:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info ETCD_VERSION: $(ETCD_VERSION))
-	gcloud docker -- push gcr.io/etcd-development/etcd-functional:go$(GO_VERSION)
-
-pull-docker-functional:
-	$(info GO_VERSION: $(GO_VERSION))
-	$(info ETCD_VERSION: $(ETCD_VERSION))
-	docker pull gcr.io/etcd-development/etcd-functional:go$(GO_VERSION)
diff --git a/vendor/github.com/coreos/etcd/Procfile b/vendor/github.com/coreos/etcd/Procfile
deleted file mode 100644
index 868967c..0000000
--- a/vendor/github.com/coreos/etcd/Procfile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Use goreman to run `go get github.com/mattn/goreman`
-etcd1: bin/etcd --name infra1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
-etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
-etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
-#proxy: bin/etcd grpc-proxy start --endpoints=127.0.0.1:2379,127.0.0.1:22379,127.0.0.1:32379 --listen-addr=127.0.0.1:23790 --advertise-client-url=127.0.0.1:23790 --enable-pprof
diff --git a/vendor/github.com/coreos/etcd/Procfile.v2 b/vendor/github.com/coreos/etcd/Procfile.v2
deleted file mode 100644
index 41dd49f..0000000
--- a/vendor/github.com/coreos/etcd/Procfile.v2
+++ /dev/null
@@ -1,6 +0,0 @@
-# Use goreman to run `go get github.com/mattn/goreman`
-etcd1: bin/etcd --name infra1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
-etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
-etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
-# in future, use proxy to listen on 2379
-#proxy: bin/etcd --name infra-proxy1 --proxy=on --listen-client-urls http://127.0.0.1:2378 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --enable-pprof
diff --git a/vendor/github.com/coreos/etcd/README.md b/vendor/github.com/coreos/etcd/README.md
deleted file mode 100644
index 2b55901..0000000
--- a/vendor/github.com/coreos/etcd/README.md
+++ /dev/null
@@ -1,161 +0,0 @@
-# etcd
-
-[![Go Report Card](https://goreportcard.com/badge/github.com/coreos/etcd?style=flat-square)](https://goreportcard.com/report/github.com/coreos/etcd)
-[![Coverage](https://codecov.io/gh/coreos/etcd/branch/master/graph/badge.svg)](https://codecov.io/gh/coreos/etcd)
-[![Build Status Travis](https://img.shields.io/travis/coreos/etcdlabs.svg?style=flat-square&&branch=master)](https://travis-ci.org/coreos/etcd)
-[![Build Status Semaphore](https://semaphoreci.com/api/v1/coreos/etcd/branches/master/shields_badge.svg)](https://semaphoreci.com/coreos/etcd)
-[![Godoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/github.com/coreos/etcd)
-[![Releases](https://img.shields.io/github/release/coreos/etcd/all.svg?style=flat-square)](https://github.com/coreos/etcd/releases)
-[![LICENSE](https://img.shields.io/github/license/coreos/etcd.svg?style=flat-square)](https://github.com/coreos/etcd/blob/master/LICENSE)
-
-**Note**: The `master` branch may be in an *unstable or even broken state* during development. Please use [releases][github-release] instead of the `master` branch in order to get stable binaries.
-
-*the etcd v2 [documentation](Documentation/v2/README.md) has moved*
-
-![etcd Logo](logos/etcd-horizontal-color.png)
-
-etcd is a distributed reliable key-value store for the most critical data of a distributed system, with a focus on being:
-
-* *Simple*: well-defined, user-facing API (gRPC)
-* *Secure*: automatic TLS with optional client cert authentication
-* *Fast*: benchmarked 10,000 writes/sec
-* *Reliable*: properly distributed using Raft
-
-etcd is written in Go and uses the [Raft][raft] consensus algorithm to manage a highly-available replicated log.
-
-etcd is used [in production by many companies](./Documentation/production-users.md), and the development team stands behind it in critical deployment scenarios, where etcd is frequently teamed with applications such as [Kubernetes][k8s], [fleet][fleet], [locksmith][locksmith], [vulcand][vulcand], [Doorman][doorman], and many others. Reliability is further ensured by rigorous [testing][etcd-tests].
-
-See [etcdctl][etcdctl] for a simple command line client.
-
-[raft]: https://raft.github.io/
-[k8s]: http://kubernetes.io/
-[doorman]: https://github.com/youtube/doorman
-[fleet]: https://github.com/coreos/fleet
-[locksmith]: https://github.com/coreos/locksmith
-[vulcand]: https://github.com/vulcand/vulcand
-[etcdctl]: https://github.com/coreos/etcd/tree/master/etcdctl
-[etcd-tests]: http://dash.etcd.io
-
-## Community meetings
-
-etcd contributors and maintainers have bi-weekly meetings at 11:00 AM (USA Pacific) on Tuesdays. There is an [iCalendar][rfc5545] format for the meetings [here](meeting.ics). Anyone is welcome to join via [Zoom][zoom] or audio-only: +1 669 900 6833. An initial agenda will be posted to the [shared Google docs][shared-meeting-notes] a day before each meeting, and everyone is welcome to suggest additional topics or other agendas.
-
-[rfc5545]: https://tools.ietf.org/html/rfc5545
-[zoom]: https://coreos.zoom.us/j/854793406
-[shared-meeting-notes]: https://docs.google.com/document/d/1DbVXOHvd9scFsSmL2oNg4YGOHJdXqtx583DmeVWrB_M/edit#
-
-## Getting started
-
-### Getting etcd
-
-The easiest way to get etcd is to use one of the pre-built release binaries which are available for OSX, Linux, Windows, [rkt][rkt], and Docker. Instructions for using these binaries are on the [GitHub releases page][github-release].
-
-For those wanting to try the very latest version, [build the latest version of etcd][dl-build] from the `master` branch. This first needs [*Go*](https://golang.org/) installed (version 1.9+ is required). All development occurs on `master`, including new features and bug fixes. Bug fixes are first targeted at `master` and subsequently ported to release branches, as described in the [branch management][branch-management] guide.
-
-[rkt]: https://github.com/rkt/rkt/releases/
-[github-release]: https://github.com/coreos/etcd/releases/
-[branch-management]: ./Documentation/branch_management.md
-[dl-build]: ./Documentation/dl_build.md#build-the-latest-version
-
-### Running etcd
-
-First start a single-member cluster of etcd.
-
-If etcd is installed using the [pre-built release binaries][github-release], run it from the installation location as below:
-
-```sh
-/tmp/etcd-download-test/etcd
-```
-The etcd command can be simply run as such if it is moved to the system path as below:
-
-```sh
-mv /tmp/etcd-download-test/etcd /usr/locale/bin/
-
-etcd
-```
-
-If etcd is [build from the master branch][dl-build], run it as below:
-
-```sh
-./bin/etcd
-```
-
-This will bring up etcd listening on port 2379 for client communication and on port 2380 for server-to-server communication.
-
-Next, let's set a single key, and then retrieve it:
-
-```
-ETCDCTL_API=3 etcdctl put mykey "this is awesome"
-ETCDCTL_API=3 etcdctl get mykey
-```
-
-That's it! etcd is now running and serving client requests. For more
-
-- [Animated quick demo][demo-gif]
-- [Interactive etcd playground][etcd-play]
-
-[demo-gif]: ./Documentation/demo.md
-[etcd-play]: http://play.etcd.io/
-
-### etcd TCP ports
-
-The [official etcd ports][iana-ports] are 2379 for client requests, and 2380 for peer communication.
-
-[iana-ports]: http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
-
-### Running a local etcd cluster
-
-First install [goreman](https://github.com/mattn/goreman), which manages Procfile-based applications.
-
-Our [Procfile script](./Procfile) will set up a local example cluster. Start it with:
-
-```sh
-goreman start
-```
-
-This will bring up 3 etcd members `infra1`, `infra2` and `infra3` and etcd `grpc-proxy`, which runs locally and composes a cluster.
-
-Every cluster member and proxy accepts key value reads and key value writes.
-
-### Running etcd on Kubernetes
-
-To run an etcd cluster on Kubernetes, try [etcd operator](https://github.com/coreos/etcd-operator).
-
-### Next steps
-
-Now it's time to dig into the full etcd API and other guides.
-
-- Read the full [documentation][fulldoc].
-- Explore the full gRPC [API][api].
-- Set up a [multi-machine cluster][clustering].
-- Learn the [config format, env variables and flags][configuration].
-- Find [language bindings and tools][integrations].
-- Use TLS to [secure an etcd cluster][security].
-- [Tune etcd][tuning].
-
-[fulldoc]: ./Documentation/docs.md
-[api]: ./Documentation/dev-guide/api_reference_v3.md
-[clustering]: ./Documentation/op-guide/clustering.md
-[configuration]: ./Documentation/op-guide/configuration.md
-[integrations]: ./Documentation/integrations.md
-[security]: ./Documentation/op-guide/security.md
-[tuning]: ./Documentation/tuning.md
-
-## Contact
-
-- Mailing list: [etcd-dev](https://groups.google.com/forum/?hl=en#!forum/etcd-dev)
-- IRC: #[etcd](irc://irc.freenode.org:6667/#etcd) on freenode.org
-- Planning/Roadmap: [milestones](https://github.com/coreos/etcd/milestones), [roadmap](./ROADMAP.md)
-- Bugs: [issues](https://github.com/coreos/etcd/issues)
-
-## Contributing
-
-See [CONTRIBUTING](CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
-
-## Reporting bugs
-
-See [reporting bugs](Documentation/reporting_bugs.md) for details about reporting any issues.
-
-### License
-
-etcd is under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
diff --git a/vendor/github.com/coreos/etcd/ROADMAP.md b/vendor/github.com/coreos/etcd/ROADMAP.md
deleted file mode 100644
index f7ae890..0000000
--- a/vendor/github.com/coreos/etcd/ROADMAP.md
+++ /dev/null
@@ -1,23 +0,0 @@
-#  etcd roadmap
-
-**work in progress**
-
-This document defines a high level roadmap for etcd development.
-
-The dates below should not be considered authoritative, but rather indicative of the projected timeline of the project. The [milestones defined in GitHub](https://github.com/coreos/etcd/milestones) represent the most up-to-date and issue-for-issue plans.
-
-etcd 3.2 is our current stable branch. The roadmap below outlines new features that will be added to etcd, and while subject to change, define what future stable will look like.
-
-### etcd 3.2 (2017-May)
-- Stable scalable proxy
-- Proxy-as-client interface passthrough
-- Lock service
-- Namespacing proxy
-- TLS Command Name and JWT token based authentication
-- Read-modify-write V3 Put
-- Improved watch performance
-- Support non-blocking concurrent read
-
-### etcd 3.3 (?)
-- TBD
-
diff --git a/vendor/github.com/coreos/etcd/V2Procfile b/vendor/github.com/coreos/etcd/V2Procfile
deleted file mode 100644
index 925910f..0000000
--- a/vendor/github.com/coreos/etcd/V2Procfile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Use goreman to run `go get github.com/mattn/goreman`
-etcd1: bin/etcd --name infra1 --listen-client-urls http://127.0.0.1:12379 --advertise-client-urls http://127.0.0.1:12379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
-etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
-etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
-proxy: bin/etcd --name infra-proxy1 --proxy=on --listen-client-urls http://127.0.0.1:2379 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --enable-pprof
diff --git a/vendor/github.com/coreos/etcd/alarm/alarms.go b/vendor/github.com/coreos/etcd/alarm/alarms.go
deleted file mode 100644
index 4f0ebe9..0000000
--- a/vendor/github.com/coreos/etcd/alarm/alarms.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package alarm manages health status alarms in etcd.
-package alarm
-
-import (
-	"sync"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	alarmBucketName = []byte("alarm")
-	plog            = capnslog.NewPackageLogger("github.com/coreos/etcd", "alarm")
-)
-
-type BackendGetter interface {
-	Backend() backend.Backend
-}
-
-type alarmSet map[types.ID]*pb.AlarmMember
-
-// AlarmStore persists alarms to the backend.
-type AlarmStore struct {
-	mu    sync.Mutex
-	types map[pb.AlarmType]alarmSet
-
-	bg BackendGetter
-}
-
-func NewAlarmStore(bg BackendGetter) (*AlarmStore, error) {
-	ret := &AlarmStore{types: make(map[pb.AlarmType]alarmSet), bg: bg}
-	err := ret.restore()
-	return ret, err
-}
-
-func (a *AlarmStore) Activate(id types.ID, at pb.AlarmType) *pb.AlarmMember {
-	a.mu.Lock()
-	defer a.mu.Unlock()
-
-	newAlarm := &pb.AlarmMember{MemberID: uint64(id), Alarm: at}
-	if m := a.addToMap(newAlarm); m != newAlarm {
-		return m
-	}
-
-	v, err := newAlarm.Marshal()
-	if err != nil {
-		plog.Panicf("failed to marshal alarm member")
-	}
-
-	b := a.bg.Backend()
-	b.BatchTx().Lock()
-	b.BatchTx().UnsafePut(alarmBucketName, v, nil)
-	b.BatchTx().Unlock()
-
-	return newAlarm
-}
-
-func (a *AlarmStore) Deactivate(id types.ID, at pb.AlarmType) *pb.AlarmMember {
-	a.mu.Lock()
-	defer a.mu.Unlock()
-
-	t := a.types[at]
-	if t == nil {
-		t = make(alarmSet)
-		a.types[at] = t
-	}
-	m := t[id]
-	if m == nil {
-		return nil
-	}
-
-	delete(t, id)
-
-	v, err := m.Marshal()
-	if err != nil {
-		plog.Panicf("failed to marshal alarm member")
-	}
-
-	b := a.bg.Backend()
-	b.BatchTx().Lock()
-	b.BatchTx().UnsafeDelete(alarmBucketName, v)
-	b.BatchTx().Unlock()
-
-	return m
-}
-
-func (a *AlarmStore) Get(at pb.AlarmType) (ret []*pb.AlarmMember) {
-	a.mu.Lock()
-	defer a.mu.Unlock()
-	if at == pb.AlarmType_NONE {
-		for _, t := range a.types {
-			for _, m := range t {
-				ret = append(ret, m)
-			}
-		}
-		return ret
-	}
-	for _, m := range a.types[at] {
-		ret = append(ret, m)
-	}
-	return ret
-}
-
-func (a *AlarmStore) restore() error {
-	b := a.bg.Backend()
-	tx := b.BatchTx()
-
-	tx.Lock()
-	tx.UnsafeCreateBucket(alarmBucketName)
-	err := tx.UnsafeForEach(alarmBucketName, func(k, v []byte) error {
-		var m pb.AlarmMember
-		if err := m.Unmarshal(k); err != nil {
-			return err
-		}
-		a.addToMap(&m)
-		return nil
-	})
-	tx.Unlock()
-
-	b.ForceCommit()
-	return err
-}
-
-func (a *AlarmStore) addToMap(newAlarm *pb.AlarmMember) *pb.AlarmMember {
-	t := a.types[newAlarm.Alarm]
-	if t == nil {
-		t = make(alarmSet)
-		a.types[newAlarm.Alarm] = t
-	}
-	m := t[types.ID(newAlarm.MemberID)]
-	if m != nil {
-		return m
-	}
-	t[types.ID(newAlarm.MemberID)] = newAlarm
-	return newAlarm
-}
diff --git a/vendor/github.com/coreos/etcd/auth/doc.go b/vendor/github.com/coreos/etcd/auth/doc.go
deleted file mode 100644
index 72741a1..0000000
--- a/vendor/github.com/coreos/etcd/auth/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package auth provides client role authentication for accessing keys in etcd.
-package auth
diff --git a/vendor/github.com/coreos/etcd/auth/jwt.go b/vendor/github.com/coreos/etcd/auth/jwt.go
deleted file mode 100644
index 99b2d6b..0000000
--- a/vendor/github.com/coreos/etcd/auth/jwt.go
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package auth
-
-import (
-	"context"
-	"crypto/rsa"
-	"io/ioutil"
-
-	jwt "github.com/dgrijalva/jwt-go"
-)
-
-type tokenJWT struct {
-	signMethod string
-	signKey    *rsa.PrivateKey
-	verifyKey  *rsa.PublicKey
-}
-
-func (t *tokenJWT) enable()                         {}
-func (t *tokenJWT) disable()                        {}
-func (t *tokenJWT) invalidateUser(string)           {}
-func (t *tokenJWT) genTokenPrefix() (string, error) { return "", nil }
-
-func (t *tokenJWT) info(ctx context.Context, token string, rev uint64) (*AuthInfo, bool) {
-	// rev isn't used in JWT, it is only used in simple token
-	var (
-		username string
-		revision uint64
-	)
-
-	parsed, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
-		return t.verifyKey, nil
-	})
-
-	switch err.(type) {
-	case nil:
-		if !parsed.Valid {
-			plog.Warningf("invalid jwt token: %s", token)
-			return nil, false
-		}
-
-		claims := parsed.Claims.(jwt.MapClaims)
-
-		username = claims["username"].(string)
-		revision = uint64(claims["revision"].(float64))
-	default:
-		plog.Warningf("failed to parse jwt token: %s", err)
-		return nil, false
-	}
-
-	return &AuthInfo{Username: username, Revision: revision}, true
-}
-
-func (t *tokenJWT) assign(ctx context.Context, username string, revision uint64) (string, error) {
-	// Future work: let a jwt token include permission information would be useful for
-	// permission checking in proxy side.
-	tk := jwt.NewWithClaims(jwt.GetSigningMethod(t.signMethod),
-		jwt.MapClaims{
-			"username": username,
-			"revision": revision,
-		})
-
-	token, err := tk.SignedString(t.signKey)
-	if err != nil {
-		plog.Debugf("failed to sign jwt token: %s", err)
-		return "", err
-	}
-
-	plog.Debugf("jwt token: %s", token)
-
-	return token, err
-}
-
-func prepareOpts(opts map[string]string) (jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath string, err error) {
-	for k, v := range opts {
-		switch k {
-		case "sign-method":
-			jwtSignMethod = v
-		case "pub-key":
-			jwtPubKeyPath = v
-		case "priv-key":
-			jwtPrivKeyPath = v
-		default:
-			plog.Errorf("unknown token specific option: %s", k)
-			return "", "", "", ErrInvalidAuthOpts
-		}
-	}
-	if len(jwtSignMethod) == 0 {
-		return "", "", "", ErrInvalidAuthOpts
-	}
-	return jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath, nil
-}
-
-func newTokenProviderJWT(opts map[string]string) (*tokenJWT, error) {
-	jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath, err := prepareOpts(opts)
-	if err != nil {
-		return nil, ErrInvalidAuthOpts
-	}
-
-	t := &tokenJWT{}
-
-	t.signMethod = jwtSignMethod
-
-	verifyBytes, err := ioutil.ReadFile(jwtPubKeyPath)
-	if err != nil {
-		plog.Errorf("failed to read public key (%s) for jwt: %s", jwtPubKeyPath, err)
-		return nil, err
-	}
-	t.verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)
-	if err != nil {
-		plog.Errorf("failed to parse public key (%s): %s", jwtPubKeyPath, err)
-		return nil, err
-	}
-
-	signBytes, err := ioutil.ReadFile(jwtPrivKeyPath)
-	if err != nil {
-		plog.Errorf("failed to read private key (%s) for jwt: %s", jwtPrivKeyPath, err)
-		return nil, err
-	}
-	t.signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes)
-	if err != nil {
-		plog.Errorf("failed to parse private key (%s): %s", jwtPrivKeyPath, err)
-		return nil, err
-	}
-
-	return t, nil
-}
diff --git a/vendor/github.com/coreos/etcd/auth/nop.go b/vendor/github.com/coreos/etcd/auth/nop.go
deleted file mode 100644
index d437874..0000000
--- a/vendor/github.com/coreos/etcd/auth/nop.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package auth
-
-import (
-	"context"
-)
-
-type tokenNop struct{}
-
-func (t *tokenNop) enable()                         {}
-func (t *tokenNop) disable()                        {}
-func (t *tokenNop) invalidateUser(string)           {}
-func (t *tokenNop) genTokenPrefix() (string, error) { return "", nil }
-func (t *tokenNop) info(ctx context.Context, token string, rev uint64) (*AuthInfo, bool) {
-	return nil, false
-}
-func (t *tokenNop) assign(ctx context.Context, username string, revision uint64) (string, error) {
-	return "", ErrAuthFailed
-}
-func newTokenProviderNop() (*tokenNop, error) {
-	return &tokenNop{}, nil
-}
diff --git a/vendor/github.com/coreos/etcd/auth/range_perm_cache.go b/vendor/github.com/coreos/etcd/auth/range_perm_cache.go
deleted file mode 100644
index 691b65b..0000000
--- a/vendor/github.com/coreos/etcd/auth/range_perm_cache.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package auth
-
-import (
-	"github.com/coreos/etcd/auth/authpb"
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/pkg/adt"
-)
-
-func getMergedPerms(tx backend.BatchTx, userName string) *unifiedRangePermissions {
-	user := getUser(tx, userName)
-	if user == nil {
-		plog.Errorf("invalid user name %s", userName)
-		return nil
-	}
-
-	readPerms := &adt.IntervalTree{}
-	writePerms := &adt.IntervalTree{}
-
-	for _, roleName := range user.Roles {
-		role := getRole(tx, roleName)
-		if role == nil {
-			continue
-		}
-
-		for _, perm := range role.KeyPermission {
-			var ivl adt.Interval
-			var rangeEnd []byte
-
-			if len(perm.RangeEnd) != 1 || perm.RangeEnd[0] != 0 {
-				rangeEnd = perm.RangeEnd
-			}
-
-			if len(perm.RangeEnd) != 0 {
-				ivl = adt.NewBytesAffineInterval(perm.Key, rangeEnd)
-			} else {
-				ivl = adt.NewBytesAffinePoint(perm.Key)
-			}
-
-			switch perm.PermType {
-			case authpb.READWRITE:
-				readPerms.Insert(ivl, struct{}{})
-				writePerms.Insert(ivl, struct{}{})
-
-			case authpb.READ:
-				readPerms.Insert(ivl, struct{}{})
-
-			case authpb.WRITE:
-				writePerms.Insert(ivl, struct{}{})
-			}
-		}
-	}
-
-	return &unifiedRangePermissions{
-		readPerms:  readPerms,
-		writePerms: writePerms,
-	}
-}
-
-func checkKeyInterval(cachedPerms *unifiedRangePermissions, key, rangeEnd []byte, permtyp authpb.Permission_Type) bool {
-	if len(rangeEnd) == 1 && rangeEnd[0] == 0 {
-		rangeEnd = nil
-	}
-
-	ivl := adt.NewBytesAffineInterval(key, rangeEnd)
-	switch permtyp {
-	case authpb.READ:
-		return cachedPerms.readPerms.Contains(ivl)
-	case authpb.WRITE:
-		return cachedPerms.writePerms.Contains(ivl)
-	default:
-		plog.Panicf("unknown auth type: %v", permtyp)
-	}
-	return false
-}
-
-func checkKeyPoint(cachedPerms *unifiedRangePermissions, key []byte, permtyp authpb.Permission_Type) bool {
-	pt := adt.NewBytesAffinePoint(key)
-	switch permtyp {
-	case authpb.READ:
-		return cachedPerms.readPerms.Intersects(pt)
-	case authpb.WRITE:
-		return cachedPerms.writePerms.Intersects(pt)
-	default:
-		plog.Panicf("unknown auth type: %v", permtyp)
-	}
-	return false
-}
-
-func (as *authStore) isRangeOpPermitted(tx backend.BatchTx, userName string, key, rangeEnd []byte, permtyp authpb.Permission_Type) bool {
-	// assumption: tx is Lock()ed
-	_, ok := as.rangePermCache[userName]
-	if !ok {
-		perms := getMergedPerms(tx, userName)
-		if perms == nil {
-			plog.Errorf("failed to create a unified permission of user %s", userName)
-			return false
-		}
-		as.rangePermCache[userName] = perms
-	}
-
-	if len(rangeEnd) == 0 {
-		return checkKeyPoint(as.rangePermCache[userName], key, permtyp)
-	}
-
-	return checkKeyInterval(as.rangePermCache[userName], key, rangeEnd, permtyp)
-}
-
-func (as *authStore) clearCachedPerm() {
-	as.rangePermCache = make(map[string]*unifiedRangePermissions)
-}
-
-func (as *authStore) invalidateCachedPerm(userName string) {
-	delete(as.rangePermCache, userName)
-}
-
-type unifiedRangePermissions struct {
-	readPerms  *adt.IntervalTree
-	writePerms *adt.IntervalTree
-}
diff --git a/vendor/github.com/coreos/etcd/auth/simple_token.go b/vendor/github.com/coreos/etcd/auth/simple_token.go
deleted file mode 100644
index ac55ad7..0000000
--- a/vendor/github.com/coreos/etcd/auth/simple_token.go
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package auth
-
-// CAUTION: This randum number based token mechanism is only for testing purpose.
-// JWT based mechanism will be added in the near future.
-
-import (
-	"context"
-	"crypto/rand"
-	"fmt"
-	"math/big"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-)
-
-const (
-	letters                  = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
-	defaultSimpleTokenLength = 16
-)
-
-// var for testing purposes
-var (
-	simpleTokenTTL           = 5 * time.Minute
-	simpleTokenTTLResolution = 1 * time.Second
-)
-
-type simpleTokenTTLKeeper struct {
-	tokens          map[string]time.Time
-	donec           chan struct{}
-	stopc           chan struct{}
-	deleteTokenFunc func(string)
-	mu              *sync.Mutex
-}
-
-func (tm *simpleTokenTTLKeeper) stop() {
-	select {
-	case tm.stopc <- struct{}{}:
-	case <-tm.donec:
-	}
-	<-tm.donec
-}
-
-func (tm *simpleTokenTTLKeeper) addSimpleToken(token string) {
-	tm.tokens[token] = time.Now().Add(simpleTokenTTL)
-}
-
-func (tm *simpleTokenTTLKeeper) resetSimpleToken(token string) {
-	if _, ok := tm.tokens[token]; ok {
-		tm.tokens[token] = time.Now().Add(simpleTokenTTL)
-	}
-}
-
-func (tm *simpleTokenTTLKeeper) deleteSimpleToken(token string) {
-	delete(tm.tokens, token)
-}
-
-func (tm *simpleTokenTTLKeeper) run() {
-	tokenTicker := time.NewTicker(simpleTokenTTLResolution)
-	defer func() {
-		tokenTicker.Stop()
-		close(tm.donec)
-	}()
-	for {
-		select {
-		case <-tokenTicker.C:
-			nowtime := time.Now()
-			tm.mu.Lock()
-			for t, tokenendtime := range tm.tokens {
-				if nowtime.After(tokenendtime) {
-					tm.deleteTokenFunc(t)
-					delete(tm.tokens, t)
-				}
-			}
-			tm.mu.Unlock()
-		case <-tm.stopc:
-			return
-		}
-	}
-}
-
-type tokenSimple struct {
-	indexWaiter       func(uint64) <-chan struct{}
-	simpleTokenKeeper *simpleTokenTTLKeeper
-	simpleTokensMu    sync.Mutex
-	simpleTokens      map[string]string // token -> username
-}
-
-func (t *tokenSimple) genTokenPrefix() (string, error) {
-	ret := make([]byte, defaultSimpleTokenLength)
-
-	for i := 0; i < defaultSimpleTokenLength; i++ {
-		bInt, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
-		if err != nil {
-			return "", err
-		}
-
-		ret[i] = letters[bInt.Int64()]
-	}
-
-	return string(ret), nil
-}
-
-func (t *tokenSimple) assignSimpleTokenToUser(username, token string) {
-	t.simpleTokensMu.Lock()
-	defer t.simpleTokensMu.Unlock()
-	if t.simpleTokenKeeper == nil {
-		return
-	}
-
-	_, ok := t.simpleTokens[token]
-	if ok {
-		plog.Panicf("token %s is alredy used", token)
-	}
-
-	t.simpleTokens[token] = username
-	t.simpleTokenKeeper.addSimpleToken(token)
-}
-
-func (t *tokenSimple) invalidateUser(username string) {
-	if t.simpleTokenKeeper == nil {
-		return
-	}
-	t.simpleTokensMu.Lock()
-	for token, name := range t.simpleTokens {
-		if strings.Compare(name, username) == 0 {
-			delete(t.simpleTokens, token)
-			t.simpleTokenKeeper.deleteSimpleToken(token)
-		}
-	}
-	t.simpleTokensMu.Unlock()
-}
-
-func (t *tokenSimple) enable() {
-	delf := func(tk string) {
-		if username, ok := t.simpleTokens[tk]; ok {
-			plog.Infof("deleting token %s for user %s", tk, username)
-			delete(t.simpleTokens, tk)
-		}
-	}
-	t.simpleTokenKeeper = &simpleTokenTTLKeeper{
-		tokens:          make(map[string]time.Time),
-		donec:           make(chan struct{}),
-		stopc:           make(chan struct{}),
-		deleteTokenFunc: delf,
-		mu:              &t.simpleTokensMu,
-	}
-	go t.simpleTokenKeeper.run()
-}
-
-func (t *tokenSimple) disable() {
-	t.simpleTokensMu.Lock()
-	tk := t.simpleTokenKeeper
-	t.simpleTokenKeeper = nil
-	t.simpleTokens = make(map[string]string) // invalidate all tokens
-	t.simpleTokensMu.Unlock()
-	if tk != nil {
-		tk.stop()
-	}
-}
-
-func (t *tokenSimple) info(ctx context.Context, token string, revision uint64) (*AuthInfo, bool) {
-	if !t.isValidSimpleToken(ctx, token) {
-		return nil, false
-	}
-	t.simpleTokensMu.Lock()
-	username, ok := t.simpleTokens[token]
-	if ok && t.simpleTokenKeeper != nil {
-		t.simpleTokenKeeper.resetSimpleToken(token)
-	}
-	t.simpleTokensMu.Unlock()
-	return &AuthInfo{Username: username, Revision: revision}, ok
-}
-
-func (t *tokenSimple) assign(ctx context.Context, username string, rev uint64) (string, error) {
-	// rev isn't used in simple token, it is only used in JWT
-	index := ctx.Value(AuthenticateParamIndex{}).(uint64)
-	simpleTokenPrefix := ctx.Value(AuthenticateParamSimpleTokenPrefix{}).(string)
-	token := fmt.Sprintf("%s.%d", simpleTokenPrefix, index)
-	t.assignSimpleTokenToUser(username, token)
-
-	return token, nil
-}
-
-func (t *tokenSimple) isValidSimpleToken(ctx context.Context, token string) bool {
-	splitted := strings.Split(token, ".")
-	if len(splitted) != 2 {
-		return false
-	}
-	index, err := strconv.Atoi(splitted[1])
-	if err != nil {
-		return false
-	}
-
-	select {
-	case <-t.indexWaiter(uint64(index)):
-		return true
-	case <-ctx.Done():
-	}
-
-	return false
-}
-
-func newTokenProviderSimple(indexWaiter func(uint64) <-chan struct{}) *tokenSimple {
-	return &tokenSimple{
-		simpleTokens: make(map[string]string),
-		indexWaiter:  indexWaiter,
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/auth/store.go b/vendor/github.com/coreos/etcd/auth/store.go
deleted file mode 100644
index d676cb5..0000000
--- a/vendor/github.com/coreos/etcd/auth/store.go
+++ /dev/null
@@ -1,1136 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package auth
-
-import (
-	"bytes"
-	"context"
-	"encoding/binary"
-	"errors"
-	"sort"
-	"strings"
-	"sync"
-	"sync/atomic"
-
-	"github.com/coreos/etcd/auth/authpb"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc/backend"
-
-	"github.com/coreos/pkg/capnslog"
-	"golang.org/x/crypto/bcrypt"
-	"google.golang.org/grpc/credentials"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/peer"
-)
-
-var (
-	enableFlagKey = []byte("authEnabled")
-	authEnabled   = []byte{1}
-	authDisabled  = []byte{0}
-
-	revisionKey = []byte("authRevision")
-
-	authBucketName      = []byte("auth")
-	authUsersBucketName = []byte("authUsers")
-	authRolesBucketName = []byte("authRoles")
-
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "auth")
-
-	ErrRootUserNotExist     = errors.New("auth: root user does not exist")
-	ErrRootRoleNotExist     = errors.New("auth: root user does not have root role")
-	ErrUserAlreadyExist     = errors.New("auth: user already exists")
-	ErrUserEmpty            = errors.New("auth: user name is empty")
-	ErrUserNotFound         = errors.New("auth: user not found")
-	ErrRoleAlreadyExist     = errors.New("auth: role already exists")
-	ErrRoleNotFound         = errors.New("auth: role not found")
-	ErrAuthFailed           = errors.New("auth: authentication failed, invalid user ID or password")
-	ErrPermissionDenied     = errors.New("auth: permission denied")
-	ErrRoleNotGranted       = errors.New("auth: role is not granted to the user")
-	ErrPermissionNotGranted = errors.New("auth: permission is not granted to the role")
-	ErrAuthNotEnabled       = errors.New("auth: authentication is not enabled")
-	ErrAuthOldRevision      = errors.New("auth: revision in header is old")
-	ErrInvalidAuthToken     = errors.New("auth: invalid auth token")
-	ErrInvalidAuthOpts      = errors.New("auth: invalid auth options")
-	ErrInvalidAuthMgmt      = errors.New("auth: invalid auth management")
-
-	// BcryptCost is the algorithm cost / strength for hashing auth passwords
-	BcryptCost = bcrypt.DefaultCost
-)
-
-const (
-	rootUser = "root"
-	rootRole = "root"
-
-	tokenTypeSimple = "simple"
-	tokenTypeJWT    = "jwt"
-
-	revBytesLen = 8
-)
-
-type AuthInfo struct {
-	Username string
-	Revision uint64
-}
-
-// AuthenticateParamIndex is used for a key of context in the parameters of Authenticate()
-type AuthenticateParamIndex struct{}
-
-// AuthenticateParamSimpleTokenPrefix is used for a key of context in the parameters of Authenticate()
-type AuthenticateParamSimpleTokenPrefix struct{}
-
-type AuthStore interface {
-	// AuthEnable turns on the authentication feature
-	AuthEnable() error
-
-	// AuthDisable turns off the authentication feature
-	AuthDisable()
-
-	// Authenticate does authentication based on given user name and password
-	Authenticate(ctx context.Context, username, password string) (*pb.AuthenticateResponse, error)
-
-	// Recover recovers the state of auth store from the given backend
-	Recover(b backend.Backend)
-
-	// UserAdd adds a new user
-	UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
-
-	// UserDelete deletes a user
-	UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
-
-	// UserChangePassword changes a password of a user
-	UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error)
-
-	// UserGrantRole grants a role to the user
-	UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error)
-
-	// UserGet gets the detailed information of a users
-	UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error)
-
-	// UserRevokeRole revokes a role of a user
-	UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error)
-
-	// RoleAdd adds a new role
-	RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error)
-
-	// RoleGrantPermission grants a permission to a role
-	RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error)
-
-	// RoleGet gets the detailed information of a role
-	RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error)
-
-	// RoleRevokePermission gets the detailed information of a role
-	RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error)
-
-	// RoleDelete gets the detailed information of a role
-	RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error)
-
-	// UserList gets a list of all users
-	UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error)
-
-	// RoleList gets a list of all roles
-	RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error)
-
-	// IsPutPermitted checks put permission of the user
-	IsPutPermitted(authInfo *AuthInfo, key []byte) error
-
-	// IsRangePermitted checks range permission of the user
-	IsRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error
-
-	// IsDeleteRangePermitted checks delete-range permission of the user
-	IsDeleteRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error
-
-	// IsAdminPermitted checks admin permission of the user
-	IsAdminPermitted(authInfo *AuthInfo) error
-
-	// GenTokenPrefix produces a random string in a case of simple token
-	// in a case of JWT, it produces an empty string
-	GenTokenPrefix() (string, error)
-
-	// Revision gets current revision of authStore
-	Revision() uint64
-
-	// CheckPassword checks a given pair of username and password is correct
-	CheckPassword(username, password string) (uint64, error)
-
-	// Close does cleanup of AuthStore
-	Close() error
-
-	// AuthInfoFromCtx gets AuthInfo from gRPC's context
-	AuthInfoFromCtx(ctx context.Context) (*AuthInfo, error)
-
-	// AuthInfoFromTLS gets AuthInfo from TLS info of gRPC's context
-	AuthInfoFromTLS(ctx context.Context) *AuthInfo
-
-	// WithRoot generates and installs a token that can be used as a root credential
-	WithRoot(ctx context.Context) context.Context
-
-	// HasRole checks that user has role
-	HasRole(user, role string) bool
-}
-
-type TokenProvider interface {
-	info(ctx context.Context, token string, revision uint64) (*AuthInfo, bool)
-	assign(ctx context.Context, username string, revision uint64) (string, error)
-	enable()
-	disable()
-
-	invalidateUser(string)
-	genTokenPrefix() (string, error)
-}
-
-type authStore struct {
-	// atomic operations; need 64-bit align, or 32-bit tests will crash
-	revision uint64
-
-	be        backend.Backend
-	enabled   bool
-	enabledMu sync.RWMutex
-
-	rangePermCache map[string]*unifiedRangePermissions // username -> unifiedRangePermissions
-
-	tokenProvider TokenProvider
-}
-
-func (as *authStore) AuthEnable() error {
-	as.enabledMu.Lock()
-	defer as.enabledMu.Unlock()
-	if as.enabled {
-		plog.Noticef("Authentication already enabled")
-		return nil
-	}
-	b := as.be
-	tx := b.BatchTx()
-	tx.Lock()
-	defer func() {
-		tx.Unlock()
-		b.ForceCommit()
-	}()
-
-	u := getUser(tx, rootUser)
-	if u == nil {
-		return ErrRootUserNotExist
-	}
-
-	if !hasRootRole(u) {
-		return ErrRootRoleNotExist
-	}
-
-	tx.UnsafePut(authBucketName, enableFlagKey, authEnabled)
-
-	as.enabled = true
-	as.tokenProvider.enable()
-
-	as.rangePermCache = make(map[string]*unifiedRangePermissions)
-
-	as.setRevision(getRevision(tx))
-
-	plog.Noticef("Authentication enabled")
-
-	return nil
-}
-
-func (as *authStore) AuthDisable() {
-	as.enabledMu.Lock()
-	defer as.enabledMu.Unlock()
-	if !as.enabled {
-		return
-	}
-	b := as.be
-	tx := b.BatchTx()
-	tx.Lock()
-	tx.UnsafePut(authBucketName, enableFlagKey, authDisabled)
-	as.commitRevision(tx)
-	tx.Unlock()
-	b.ForceCommit()
-
-	as.enabled = false
-	as.tokenProvider.disable()
-
-	plog.Noticef("Authentication disabled")
-}
-
-func (as *authStore) Close() error {
-	as.enabledMu.Lock()
-	defer as.enabledMu.Unlock()
-	if !as.enabled {
-		return nil
-	}
-	as.tokenProvider.disable()
-	return nil
-}
-
-func (as *authStore) Authenticate(ctx context.Context, username, password string) (*pb.AuthenticateResponse, error) {
-	if !as.isAuthEnabled() {
-		return nil, ErrAuthNotEnabled
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(tx, username)
-	if user == nil {
-		return nil, ErrAuthFailed
-	}
-
-	// Password checking is already performed in the API layer, so we don't need to check for now.
-	// Staleness of password can be detected with OCC in the API layer, too.
-
-	token, err := as.tokenProvider.assign(ctx, username, as.Revision())
-	if err != nil {
-		return nil, err
-	}
-
-	plog.Debugf("authorized %s, token is %s", username, token)
-	return &pb.AuthenticateResponse{Token: token}, nil
-}
-
-func (as *authStore) CheckPassword(username, password string) (uint64, error) {
-	if !as.isAuthEnabled() {
-		return 0, ErrAuthNotEnabled
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(tx, username)
-	if user == nil {
-		return 0, ErrAuthFailed
-	}
-
-	if bcrypt.CompareHashAndPassword(user.Password, []byte(password)) != nil {
-		plog.Noticef("authentication failed, invalid password for user %s", username)
-		return 0, ErrAuthFailed
-	}
-
-	return getRevision(tx), nil
-}
-
-func (as *authStore) Recover(be backend.Backend) {
-	enabled := false
-	as.be = be
-	tx := be.BatchTx()
-	tx.Lock()
-	_, vs := tx.UnsafeRange(authBucketName, enableFlagKey, nil, 0)
-	if len(vs) == 1 {
-		if bytes.Equal(vs[0], authEnabled) {
-			enabled = true
-		}
-	}
-
-	as.setRevision(getRevision(tx))
-
-	tx.Unlock()
-
-	as.enabledMu.Lock()
-	as.enabled = enabled
-	as.enabledMu.Unlock()
-}
-
-func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
-	if len(r.Name) == 0 {
-		return nil, ErrUserEmpty
-	}
-
-	hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), BcryptCost)
-	if err != nil {
-		plog.Errorf("failed to hash password: %s", err)
-		return nil, err
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(tx, r.Name)
-	if user != nil {
-		return nil, ErrUserAlreadyExist
-	}
-
-	newUser := &authpb.User{
-		Name:     []byte(r.Name),
-		Password: hashed,
-	}
-
-	putUser(tx, newUser)
-
-	as.commitRevision(tx)
-
-	plog.Noticef("added a new user: %s", r.Name)
-
-	return &pb.AuthUserAddResponse{}, nil
-}
-
-func (as *authStore) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
-	if as.enabled && strings.Compare(r.Name, rootUser) == 0 {
-		plog.Errorf("the user root must not be deleted")
-		return nil, ErrInvalidAuthMgmt
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(tx, r.Name)
-	if user == nil {
-		return nil, ErrUserNotFound
-	}
-
-	delUser(tx, r.Name)
-
-	as.commitRevision(tx)
-
-	as.invalidateCachedPerm(r.Name)
-	as.tokenProvider.invalidateUser(r.Name)
-
-	plog.Noticef("deleted a user: %s", r.Name)
-
-	return &pb.AuthUserDeleteResponse{}, nil
-}
-
-func (as *authStore) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
-	// TODO(mitake): measure the cost of bcrypt.GenerateFromPassword()
-	// If the cost is too high, we should move the encryption to outside of the raft
-	hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), BcryptCost)
-	if err != nil {
-		plog.Errorf("failed to hash password: %s", err)
-		return nil, err
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(tx, r.Name)
-	if user == nil {
-		return nil, ErrUserNotFound
-	}
-
-	updatedUser := &authpb.User{
-		Name:     []byte(r.Name),
-		Roles:    user.Roles,
-		Password: hashed,
-	}
-
-	putUser(tx, updatedUser)
-
-	as.commitRevision(tx)
-
-	as.invalidateCachedPerm(r.Name)
-	as.tokenProvider.invalidateUser(r.Name)
-
-	plog.Noticef("changed a password of a user: %s", r.Name)
-
-	return &pb.AuthUserChangePasswordResponse{}, nil
-}
-
-func (as *authStore) UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(tx, r.User)
-	if user == nil {
-		return nil, ErrUserNotFound
-	}
-
-	if r.Role != rootRole {
-		role := getRole(tx, r.Role)
-		if role == nil {
-			return nil, ErrRoleNotFound
-		}
-	}
-
-	idx := sort.SearchStrings(user.Roles, r.Role)
-	if idx < len(user.Roles) && strings.Compare(user.Roles[idx], r.Role) == 0 {
-		plog.Warningf("user %s is already granted role %s", r.User, r.Role)
-		return &pb.AuthUserGrantRoleResponse{}, nil
-	}
-
-	user.Roles = append(user.Roles, r.Role)
-	sort.Strings(user.Roles)
-
-	putUser(tx, user)
-
-	as.invalidateCachedPerm(r.User)
-
-	as.commitRevision(tx)
-
-	plog.Noticef("granted role %s to user %s", r.Role, r.User)
-	return &pb.AuthUserGrantRoleResponse{}, nil
-}
-
-func (as *authStore) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	user := getUser(tx, r.Name)
-	tx.Unlock()
-
-	if user == nil {
-		return nil, ErrUserNotFound
-	}
-
-	var resp pb.AuthUserGetResponse
-	resp.Roles = append(resp.Roles, user.Roles...)
-	return &resp, nil
-}
-
-func (as *authStore) UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	users := getAllUsers(tx)
-	tx.Unlock()
-
-	resp := &pb.AuthUserListResponse{Users: make([]string, len(users))}
-	for i := range users {
-		resp.Users[i] = string(users[i].Name)
-	}
-	return resp, nil
-}
-
-func (as *authStore) UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
-	if as.enabled && strings.Compare(r.Name, rootUser) == 0 && strings.Compare(r.Role, rootRole) == 0 {
-		plog.Errorf("the role root must not be revoked from the user root")
-		return nil, ErrInvalidAuthMgmt
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(tx, r.Name)
-	if user == nil {
-		return nil, ErrUserNotFound
-	}
-
-	updatedUser := &authpb.User{
-		Name:     user.Name,
-		Password: user.Password,
-	}
-
-	for _, role := range user.Roles {
-		if strings.Compare(role, r.Role) != 0 {
-			updatedUser.Roles = append(updatedUser.Roles, role)
-		}
-	}
-
-	if len(updatedUser.Roles) == len(user.Roles) {
-		return nil, ErrRoleNotGranted
-	}
-
-	putUser(tx, updatedUser)
-
-	as.invalidateCachedPerm(r.Name)
-
-	as.commitRevision(tx)
-
-	plog.Noticef("revoked role %s from user %s", r.Role, r.Name)
-	return &pb.AuthUserRevokeRoleResponse{}, nil
-}
-
-func (as *authStore) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	var resp pb.AuthRoleGetResponse
-
-	role := getRole(tx, r.Role)
-	if role == nil {
-		return nil, ErrRoleNotFound
-	}
-	resp.Perm = append(resp.Perm, role.KeyPermission...)
-	return &resp, nil
-}
-
-func (as *authStore) RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	roles := getAllRoles(tx)
-	tx.Unlock()
-
-	resp := &pb.AuthRoleListResponse{Roles: make([]string, len(roles))}
-	for i := range roles {
-		resp.Roles[i] = string(roles[i].Name)
-	}
-	return resp, nil
-}
-
-func (as *authStore) RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	role := getRole(tx, r.Role)
-	if role == nil {
-		return nil, ErrRoleNotFound
-	}
-
-	updatedRole := &authpb.Role{
-		Name: role.Name,
-	}
-
-	for _, perm := range role.KeyPermission {
-		if !bytes.Equal(perm.Key, []byte(r.Key)) || !bytes.Equal(perm.RangeEnd, []byte(r.RangeEnd)) {
-			updatedRole.KeyPermission = append(updatedRole.KeyPermission, perm)
-		}
-	}
-
-	if len(role.KeyPermission) == len(updatedRole.KeyPermission) {
-		return nil, ErrPermissionNotGranted
-	}
-
-	putRole(tx, updatedRole)
-
-	// TODO(mitake): currently single role update invalidates every cache
-	// It should be optimized.
-	as.clearCachedPerm()
-
-	as.commitRevision(tx)
-
-	plog.Noticef("revoked key %s from role %s", r.Key, r.Role)
-	return &pb.AuthRoleRevokePermissionResponse{}, nil
-}
-
-func (as *authStore) RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) {
-	if as.enabled && strings.Compare(r.Role, rootRole) == 0 {
-		plog.Errorf("the role root must not be deleted")
-		return nil, ErrInvalidAuthMgmt
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	role := getRole(tx, r.Role)
-	if role == nil {
-		return nil, ErrRoleNotFound
-	}
-
-	delRole(tx, r.Role)
-
-	users := getAllUsers(tx)
-	for _, user := range users {
-		updatedUser := &authpb.User{
-			Name:     user.Name,
-			Password: user.Password,
-		}
-
-		for _, role := range user.Roles {
-			if strings.Compare(role, r.Role) != 0 {
-				updatedUser.Roles = append(updatedUser.Roles, role)
-			}
-		}
-
-		if len(updatedUser.Roles) == len(user.Roles) {
-			continue
-		}
-
-		putUser(tx, updatedUser)
-
-		as.invalidateCachedPerm(string(user.Name))
-	}
-
-	as.commitRevision(tx)
-
-	plog.Noticef("deleted role %s", r.Role)
-	return &pb.AuthRoleDeleteResponse{}, nil
-}
-
-func (as *authStore) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	role := getRole(tx, r.Name)
-	if role != nil {
-		return nil, ErrRoleAlreadyExist
-	}
-
-	newRole := &authpb.Role{
-		Name: []byte(r.Name),
-	}
-
-	putRole(tx, newRole)
-
-	as.commitRevision(tx)
-
-	plog.Noticef("Role %s is created", r.Name)
-
-	return &pb.AuthRoleAddResponse{}, nil
-}
-
-func (as *authStore) authInfoFromToken(ctx context.Context, token string) (*AuthInfo, bool) {
-	return as.tokenProvider.info(ctx, token, as.Revision())
-}
-
-type permSlice []*authpb.Permission
-
-func (perms permSlice) Len() int {
-	return len(perms)
-}
-
-func (perms permSlice) Less(i, j int) bool {
-	return bytes.Compare(perms[i].Key, perms[j].Key) < 0
-}
-
-func (perms permSlice) Swap(i, j int) {
-	perms[i], perms[j] = perms[j], perms[i]
-}
-
-func (as *authStore) RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	role := getRole(tx, r.Name)
-	if role == nil {
-		return nil, ErrRoleNotFound
-	}
-
-	idx := sort.Search(len(role.KeyPermission), func(i int) bool {
-		return bytes.Compare(role.KeyPermission[i].Key, []byte(r.Perm.Key)) >= 0
-	})
-
-	if idx < len(role.KeyPermission) && bytes.Equal(role.KeyPermission[idx].Key, r.Perm.Key) && bytes.Equal(role.KeyPermission[idx].RangeEnd, r.Perm.RangeEnd) {
-		// update existing permission
-		role.KeyPermission[idx].PermType = r.Perm.PermType
-	} else {
-		// append new permission to the role
-		newPerm := &authpb.Permission{
-			Key:      []byte(r.Perm.Key),
-			RangeEnd: []byte(r.Perm.RangeEnd),
-			PermType: r.Perm.PermType,
-		}
-
-		role.KeyPermission = append(role.KeyPermission, newPerm)
-		sort.Sort(permSlice(role.KeyPermission))
-	}
-
-	putRole(tx, role)
-
-	// TODO(mitake): currently single role update invalidates every cache
-	// It should be optimized.
-	as.clearCachedPerm()
-
-	as.commitRevision(tx)
-
-	plog.Noticef("role %s's permission of key %s is updated as %s", r.Name, r.Perm.Key, authpb.Permission_Type_name[int32(r.Perm.PermType)])
-
-	return &pb.AuthRoleGrantPermissionResponse{}, nil
-}
-
-func (as *authStore) isOpPermitted(userName string, revision uint64, key, rangeEnd []byte, permTyp authpb.Permission_Type) error {
-	// TODO(mitake): this function would be costly so we need a caching mechanism
-	if !as.isAuthEnabled() {
-		return nil
-	}
-
-	// only gets rev == 0 when passed AuthInfo{}; no user given
-	if revision == 0 {
-		return ErrUserEmpty
-	}
-
-	if revision < as.Revision() {
-		return ErrAuthOldRevision
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(tx, userName)
-	if user == nil {
-		plog.Errorf("invalid user name %s for permission checking", userName)
-		return ErrPermissionDenied
-	}
-
-	// root role should have permission on all ranges
-	if hasRootRole(user) {
-		return nil
-	}
-
-	if as.isRangeOpPermitted(tx, userName, key, rangeEnd, permTyp) {
-		return nil
-	}
-
-	return ErrPermissionDenied
-}
-
-func (as *authStore) IsPutPermitted(authInfo *AuthInfo, key []byte) error {
-	return as.isOpPermitted(authInfo.Username, authInfo.Revision, key, nil, authpb.WRITE)
-}
-
-func (as *authStore) IsRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error {
-	return as.isOpPermitted(authInfo.Username, authInfo.Revision, key, rangeEnd, authpb.READ)
-}
-
-func (as *authStore) IsDeleteRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error {
-	return as.isOpPermitted(authInfo.Username, authInfo.Revision, key, rangeEnd, authpb.WRITE)
-}
-
-func (as *authStore) IsAdminPermitted(authInfo *AuthInfo) error {
-	if !as.isAuthEnabled() {
-		return nil
-	}
-	if authInfo == nil {
-		return ErrUserEmpty
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	u := getUser(tx, authInfo.Username)
-	tx.Unlock()
-
-	if u == nil {
-		return ErrUserNotFound
-	}
-
-	if !hasRootRole(u) {
-		return ErrPermissionDenied
-	}
-
-	return nil
-}
-
-func getUser(tx backend.BatchTx, username string) *authpb.User {
-	_, vs := tx.UnsafeRange(authUsersBucketName, []byte(username), nil, 0)
-	if len(vs) == 0 {
-		return nil
-	}
-
-	user := &authpb.User{}
-	err := user.Unmarshal(vs[0])
-	if err != nil {
-		plog.Panicf("failed to unmarshal user struct (name: %s): %s", username, err)
-	}
-	return user
-}
-
-func getAllUsers(tx backend.BatchTx) []*authpb.User {
-	_, vs := tx.UnsafeRange(authUsersBucketName, []byte{0}, []byte{0xff}, -1)
-	if len(vs) == 0 {
-		return nil
-	}
-
-	users := make([]*authpb.User, len(vs))
-	for i := range vs {
-		user := &authpb.User{}
-		err := user.Unmarshal(vs[i])
-		if err != nil {
-			plog.Panicf("failed to unmarshal user struct: %s", err)
-		}
-		users[i] = user
-	}
-	return users
-}
-
-func putUser(tx backend.BatchTx, user *authpb.User) {
-	b, err := user.Marshal()
-	if err != nil {
-		plog.Panicf("failed to marshal user struct (name: %s): %s", user.Name, err)
-	}
-	tx.UnsafePut(authUsersBucketName, user.Name, b)
-}
-
-func delUser(tx backend.BatchTx, username string) {
-	tx.UnsafeDelete(authUsersBucketName, []byte(username))
-}
-
-func getRole(tx backend.BatchTx, rolename string) *authpb.Role {
-	_, vs := tx.UnsafeRange(authRolesBucketName, []byte(rolename), nil, 0)
-	if len(vs) == 0 {
-		return nil
-	}
-
-	role := &authpb.Role{}
-	err := role.Unmarshal(vs[0])
-	if err != nil {
-		plog.Panicf("failed to unmarshal role struct (name: %s): %s", rolename, err)
-	}
-	return role
-}
-
-func getAllRoles(tx backend.BatchTx) []*authpb.Role {
-	_, vs := tx.UnsafeRange(authRolesBucketName, []byte{0}, []byte{0xff}, -1)
-	if len(vs) == 0 {
-		return nil
-	}
-
-	roles := make([]*authpb.Role, len(vs))
-	for i := range vs {
-		role := &authpb.Role{}
-		err := role.Unmarshal(vs[i])
-		if err != nil {
-			plog.Panicf("failed to unmarshal role struct: %s", err)
-		}
-		roles[i] = role
-	}
-	return roles
-}
-
-func putRole(tx backend.BatchTx, role *authpb.Role) {
-	b, err := role.Marshal()
-	if err != nil {
-		plog.Panicf("failed to marshal role struct (name: %s): %s", role.Name, err)
-	}
-
-	tx.UnsafePut(authRolesBucketName, []byte(role.Name), b)
-}
-
-func delRole(tx backend.BatchTx, rolename string) {
-	tx.UnsafeDelete(authRolesBucketName, []byte(rolename))
-}
-
-func (as *authStore) isAuthEnabled() bool {
-	as.enabledMu.RLock()
-	defer as.enabledMu.RUnlock()
-	return as.enabled
-}
-
-func NewAuthStore(be backend.Backend, tp TokenProvider) *authStore {
-	tx := be.BatchTx()
-	tx.Lock()
-
-	tx.UnsafeCreateBucket(authBucketName)
-	tx.UnsafeCreateBucket(authUsersBucketName)
-	tx.UnsafeCreateBucket(authRolesBucketName)
-
-	enabled := false
-	_, vs := tx.UnsafeRange(authBucketName, enableFlagKey, nil, 0)
-	if len(vs) == 1 {
-		if bytes.Equal(vs[0], authEnabled) {
-			enabled = true
-		}
-	}
-
-	as := &authStore{
-		be:             be,
-		revision:       getRevision(tx),
-		enabled:        enabled,
-		rangePermCache: make(map[string]*unifiedRangePermissions),
-		tokenProvider:  tp,
-	}
-
-	if enabled {
-		as.tokenProvider.enable()
-	}
-
-	if as.Revision() == 0 {
-		as.commitRevision(tx)
-	}
-
-	tx.Unlock()
-	be.ForceCommit()
-
-	return as
-}
-
-func hasRootRole(u *authpb.User) bool {
-	// u.Roles is sorted in UserGrantRole(), so we can use binary search.
-	idx := sort.SearchStrings(u.Roles, rootRole)
-	return idx != len(u.Roles) && u.Roles[idx] == rootRole
-}
-
-func (as *authStore) commitRevision(tx backend.BatchTx) {
-	atomic.AddUint64(&as.revision, 1)
-	revBytes := make([]byte, revBytesLen)
-	binary.BigEndian.PutUint64(revBytes, as.Revision())
-	tx.UnsafePut(authBucketName, revisionKey, revBytes)
-}
-
-func getRevision(tx backend.BatchTx) uint64 {
-	_, vs := tx.UnsafeRange(authBucketName, []byte(revisionKey), nil, 0)
-	if len(vs) != 1 {
-		// this can happen in the initialization phase
-		return 0
-	}
-
-	return binary.BigEndian.Uint64(vs[0])
-}
-
-func (as *authStore) setRevision(rev uint64) {
-	atomic.StoreUint64(&as.revision, rev)
-}
-
-func (as *authStore) Revision() uint64 {
-	return atomic.LoadUint64(&as.revision)
-}
-
-func (as *authStore) AuthInfoFromTLS(ctx context.Context) *AuthInfo {
-	peer, ok := peer.FromContext(ctx)
-	if !ok || peer == nil || peer.AuthInfo == nil {
-		return nil
-	}
-
-	tlsInfo := peer.AuthInfo.(credentials.TLSInfo)
-	for _, chains := range tlsInfo.State.VerifiedChains {
-		for _, chain := range chains {
-			cn := chain.Subject.CommonName
-			plog.Debugf("found common name %s", cn)
-
-			ai := &AuthInfo{
-				Username: cn,
-				Revision: as.Revision(),
-			}
-			md, ok := metadata.FromIncomingContext(ctx)
-			if !ok {
-				return nil
-			}
-
-			// gRPC-gateway proxy request to etcd server includes Grpcgateway-Accept
-			// header. The proxy uses etcd client server certificate. If the certificate
-			// has a CommonName we should never use this for authentication.
-			if gw := md["grpcgateway-accept"]; len(gw) > 0 {
-				plog.Warningf("ignoring common name in gRPC-gateway proxy request %s", ai.Username)
-				return nil
-			}
-			return ai
-		}
-	}
-
-	return nil
-}
-
-func (as *authStore) AuthInfoFromCtx(ctx context.Context) (*AuthInfo, error) {
-	md, ok := metadata.FromIncomingContext(ctx)
-	if !ok {
-		return nil, nil
-	}
-
-	//TODO(mitake|hexfusion) review unifying key names
-	ts, ok := md["token"]
-	if !ok {
-		ts, ok = md["authorization"]
-	}
-	if !ok {
-		return nil, nil
-	}
-
-	token := ts[0]
-	authInfo, uok := as.authInfoFromToken(ctx, token)
-	if !uok {
-		plog.Warningf("invalid auth token: %s", token)
-		return nil, ErrInvalidAuthToken
-	}
-
-	return authInfo, nil
-}
-
-func (as *authStore) GenTokenPrefix() (string, error) {
-	return as.tokenProvider.genTokenPrefix()
-}
-
-func decomposeOpts(optstr string) (string, map[string]string, error) {
-	opts := strings.Split(optstr, ",")
-	tokenType := opts[0]
-
-	typeSpecificOpts := make(map[string]string)
-	for i := 1; i < len(opts); i++ {
-		pair := strings.Split(opts[i], "=")
-
-		if len(pair) != 2 {
-			plog.Errorf("invalid token specific option: %s", optstr)
-			return "", nil, ErrInvalidAuthOpts
-		}
-
-		if _, ok := typeSpecificOpts[pair[0]]; ok {
-			plog.Errorf("invalid token specific option, duplicated parameters (%s): %s", pair[0], optstr)
-			return "", nil, ErrInvalidAuthOpts
-		}
-
-		typeSpecificOpts[pair[0]] = pair[1]
-	}
-
-	return tokenType, typeSpecificOpts, nil
-
-}
-
-func NewTokenProvider(tokenOpts string, indexWaiter func(uint64) <-chan struct{}) (TokenProvider, error) {
-	tokenType, typeSpecificOpts, err := decomposeOpts(tokenOpts)
-	if err != nil {
-		return nil, ErrInvalidAuthOpts
-	}
-
-	switch tokenType {
-	case tokenTypeSimple:
-		plog.Warningf("simple token is not cryptographically signed")
-		return newTokenProviderSimple(indexWaiter), nil
-
-	case tokenTypeJWT:
-		return newTokenProviderJWT(typeSpecificOpts)
-
-	case "":
-		return newTokenProviderNop()
-	default:
-		plog.Errorf("unknown token type: %s", tokenType)
-		return nil, ErrInvalidAuthOpts
-	}
-}
-
-func (as *authStore) WithRoot(ctx context.Context) context.Context {
-	if !as.isAuthEnabled() {
-		return ctx
-	}
-
-	var ctxForAssign context.Context
-	if ts, ok := as.tokenProvider.(*tokenSimple); ok && ts != nil {
-		ctx1 := context.WithValue(ctx, AuthenticateParamIndex{}, uint64(0))
-		prefix, err := ts.genTokenPrefix()
-		if err != nil {
-			plog.Errorf("failed to generate prefix of internally used token")
-			return ctx
-		}
-		ctxForAssign = context.WithValue(ctx1, AuthenticateParamSimpleTokenPrefix{}, prefix)
-	} else {
-		ctxForAssign = ctx
-	}
-
-	token, err := as.tokenProvider.assign(ctxForAssign, "root", as.Revision())
-	if err != nil {
-		// this must not happen
-		plog.Errorf("failed to assign token for lease revoking: %s", err)
-		return ctx
-	}
-
-	mdMap := map[string]string{
-		"token": token,
-	}
-	tokenMD := metadata.New(mdMap)
-
-	// use "mdIncomingKey{}" since it's called from local etcdserver
-	return metadata.NewIncomingContext(ctx, tokenMD)
-}
-
-func (as *authStore) HasRole(user, role string) bool {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	u := getUser(tx, user)
-	tx.Unlock()
-
-	if u == nil {
-		plog.Warningf("tried to check user %s has role %s, but user %s doesn't exist", user, role, user)
-		return false
-	}
-
-	for _, r := range u.Roles {
-		if role == r {
-			return true
-		}
-	}
-
-	return false
-}
diff --git a/vendor/github.com/coreos/etcd/bill-of-materials.json b/vendor/github.com/coreos/etcd/bill-of-materials.json
deleted file mode 100644
index 98e2822..0000000
--- a/vendor/github.com/coreos/etcd/bill-of-materials.json
+++ /dev/null
@@ -1,451 +0,0 @@
-[
-	{
-		"project": "bitbucket.org/ww/goautoneg",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/beorn7/perks/quantile",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.9891304347826086
-			}
-		]
-	},
-	{
-		"project": "github.com/bgentry/speakeasy",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.9441624365482234
-			}
-		]
-	},
-	{
-		"project": "github.com/coreos/bbolt",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/coreos/etcd",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/coreos/go-semver/semver",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/coreos/go-systemd",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 0.9966703662597114
-			}
-		]
-	},
-	{
-		"project": "github.com/coreos/pkg",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/cpuguy83/go-md2man/md2man",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/dgrijalva/jwt-go",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.9891304347826086
-			}
-		]
-	},
-	{
-		"project": "github.com/dustin/go-humanize",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.96875
-			}
-		]
-	},
-	{
-		"project": "github.com/ghodss/yaml",
-		"licenses": [
-			{
-				"type": "MIT License and BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/gogo/protobuf",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 0.9090909090909091
-			}
-		]
-	},
-	{
-		"project": "github.com/golang/groupcache/lru",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 0.9966703662597114
-			}
-		]
-	},
-	{
-		"project": "github.com/golang/protobuf",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 0.92
-			}
-		]
-	},
-	{
-		"project": "github.com/google/btree",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/gorilla/websocket",
-		"licenses": [
-			{
-				"type": "BSD 2-clause \"Simplified\" License",
-				"confidence": 0.9852216748768473
-			}
-		]
-	},
-	{
-		"project": "github.com/grpc-ecosystem/go-grpc-prometheus",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/grpc-ecosystem/grpc-gateway",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 0.979253112033195
-			}
-		]
-	},
-	{
-		"project": "github.com/inconshreveable/mousetrap",
-		"licenses": [
-			{
-				"type": "MIT License and BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 1
-			},
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/jonboulle/clockwork",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/mattn/go-runewidth",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/matttproud/golang_protobuf_extensions/pbutil",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/olekukonko/tablewriter",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.9891304347826086
-			}
-		]
-	},
-	{
-		"project": "github.com/prometheus/client_golang/prometheus",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/prometheus/client_model/go",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/prometheus/common",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/prometheus/procfs",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/russross/blackfriday",
-		"licenses": [
-			{
-				"type": "BSD 2-clause \"Simplified\" License",
-				"confidence": 0.9626168224299065
-			}
-		]
-	},
-	{
-		"project": "github.com/sirupsen/logrus",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/soheilhy/cmux",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/spf13/cobra",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 0.9573241061130334
-			}
-		]
-	},
-	{
-		"project": "github.com/spf13/pflag",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 0.9663865546218487
-			}
-		]
-	},
-	{
-		"project": "github.com/tmc/grpc-websocket-proxy/wsproxy",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.9891304347826086
-			}
-		]
-	},
-	{
-		"project": "github.com/ugorji/go/codec",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.9946524064171123
-			}
-		]
-	},
-	{
-		"project": "github.com/urfave/cli",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "github.com/xiang90/probing",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "go.uber.org/atomic",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.9891304347826086
-			}
-		]
-	},
-	{
-		"project": "go.uber.org/multierr",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.9891304347826086
-			}
-		]
-	},
-	{
-		"project": "go.uber.org/zap",
-		"licenses": [
-			{
-				"type": "MIT License",
-				"confidence": 0.9891304347826086
-			}
-		]
-	},
-	{
-		"project": "golang.org/x/crypto",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 0.9663865546218487
-			}
-		]
-	},
-	{
-		"project": "golang.org/x/net",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 0.9663865546218487
-			}
-		]
-	},
-	{
-		"project": "golang.org/x/sys/unix",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 0.9663865546218487
-			}
-		]
-	},
-	{
-		"project": "golang.org/x/text",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 0.9663865546218487
-			}
-		]
-	},
-	{
-		"project": "golang.org/x/time/rate",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 0.9663865546218487
-			}
-		]
-	},
-	{
-		"project": "google.golang.org/genproto/googleapis/rpc/status",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "google.golang.org/grpc",
-		"licenses": [
-			{
-				"type": "Apache License 2.0",
-				"confidence": 1
-			}
-		]
-	},
-	{
-		"project": "gopkg.in/cheggaaa/pb.v1",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 0.9916666666666667
-			}
-		]
-	},
-	{
-		"project": "gopkg.in/yaml.v2",
-		"licenses": [
-			{
-				"type": "The Unlicense",
-				"confidence": 0.35294117647058826
-			},
-			{
-				"type": "MIT License",
-				"confidence": 0.8975609756097561
-			}
-		]
-	}
-]
diff --git a/vendor/github.com/coreos/etcd/bill-of-materials.override.json b/vendor/github.com/coreos/etcd/bill-of-materials.override.json
deleted file mode 100644
index 34de90e..0000000
--- a/vendor/github.com/coreos/etcd/bill-of-materials.override.json
+++ /dev/null
@@ -1,26 +0,0 @@
-[
-	{
-		"project": "bitbucket.org/ww/goautoneg",
-		"licenses": [
-			{
-				"type": "BSD 3-clause \"New\" or \"Revised\" License"
-			}
-		]
-	},
-	{
-		"project": "github.com/ghodss/yaml",
-		"licenses": [
-			{
-				"type": "MIT License and BSD 3-clause \"New\" or \"Revised\" License"
-			}
-		]
-	},
-	{
-		"project": "github.com/inconshreveable/mousetrap",
-		"licenses": [
-			{
-				"type": "Apache License 2.0"
-			}
-		]
-	}
-]
diff --git a/vendor/github.com/coreos/etcd/build b/vendor/github.com/coreos/etcd/build
deleted file mode 100755
index b233d32..0000000
--- a/vendor/github.com/coreos/etcd/build
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/sh -e
-
-# set some environment variables
-ORG_PATH="github.com/coreos"
-REPO_PATH="${ORG_PATH}/etcd"
-
-GIT_SHA=$(git rev-parse --short HEAD || echo "GitNotFound")
-if [ ! -z "$FAILPOINTS" ]; then
-	GIT_SHA="$GIT_SHA"-FAILPOINTS
-fi
-
-# Set GO_LDFLAGS="-s" for building without symbols for debugging.
-GO_LDFLAGS="$GO_LDFLAGS -X ${REPO_PATH}/cmd/vendor/${REPO_PATH}/version.GitSHA=${GIT_SHA}"
-
-# enable/disable failpoints
-toggle_failpoints() {
-	mode="$1"
-	if which gofail >/dev/null 2>&1; then
-		gofail "$mode" etcdserver/ mvcc/backend/
-	elif [ "$mode" != "disable" ]; then
-		echo "FAILPOINTS set but gofail not found"
-		exit 1
-	fi
-}
-
-toggle_failpoints_default() {
-	mode="disable"
-	if [ ! -z "$FAILPOINTS" ]; then mode="enable"; fi
-	toggle_failpoints "$mode"
-}
-
-etcd_build() {
-	out="bin"
-	if [ -n "${BINDIR}" ]; then out="${BINDIR}"; fi
-	toggle_failpoints_default
-	# Static compilation is useful when etcd is run in a container. $GO_BUILD_FLAGS is OK
-
-	# shellcheck disable=SC2086
-	CGO_ENABLED=0 go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "$GO_LDFLAGS" -o "${out}/etcd" ${REPO_PATH}/cmd/etcd || return
-	# shellcheck disable=SC2086
-	CGO_ENABLED=0 go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "$GO_LDFLAGS" -o "${out}/etcdctl" ${REPO_PATH}/cmd/etcdctl || return
-}
-
-etcd_setup_gopath() {
-	d=$(dirname "$0")
-	CDIR=$(cd "$d" && pwd)
-	cd "$CDIR"
-	etcdGOPATH="${CDIR}/gopath"
-	# preserve old gopath to support building with unvendored tooling deps (e.g., gofail)
-	if [ -n "$GOPATH" ]; then
-		GOPATH=":$GOPATH"
-	fi
-	export GOPATH=${etcdGOPATH}$GOPATH
-	rm -rf "${etcdGOPATH}/src"
-	mkdir -p "${etcdGOPATH}"
-	ln -s "${CDIR}/cmd/vendor" "${etcdGOPATH}/src"
-}
-
-toggle_failpoints_default
-
-# only build when called directly, not sourced
-if echo "$0" | grep "build$" >/dev/null; then
-	# force new gopath so builds outside of gopath work
-	etcd_setup_gopath
-	etcd_build
-fi
diff --git a/vendor/github.com/coreos/etcd/build.bat b/vendor/github.com/coreos/etcd/build.bat
deleted file mode 100755
index ff9b209..0000000
--- a/vendor/github.com/coreos/etcd/build.bat
+++ /dev/null
@@ -1 +0,0 @@
-powershell -ExecutionPolicy Bypass -File build.ps1
diff --git a/vendor/github.com/coreos/etcd/build.ps1 b/vendor/github.com/coreos/etcd/build.ps1
deleted file mode 100644
index 455d37d..0000000
--- a/vendor/github.com/coreos/etcd/build.ps1
+++ /dev/null
@@ -1,81 +0,0 @@
-$ORG_PATH="github.com/coreos"
-$REPO_PATH="$ORG_PATH/etcd"
-$PWD = $((Get-Item -Path ".\" -Verbose).FullName)
-$FSROOT = $((Get-Location).Drive.Name+":")
-$FSYS = $((Get-WMIObject win32_logicaldisk -filter "DeviceID = '$FSROOT'").filesystem)
-
-if ($FSYS.StartsWith("FAT","CurrentCultureIgnoreCase")) {
-	echo "Error: Cannot build etcd using the $FSYS filesystem (use NTFS instead)"
-	exit 1
-}
-
-# Set $Env:GO_LDFLAGS="-s" for building without symbols.
-$GO_LDFLAGS="$Env:GO_LDFLAGS -X $REPO_PATH/cmd/vendor/$REPO_PATH/version.GitSHA=$GIT_SHA"
-
-# rebuild symlinks
-git ls-files -s cmd | select-string -pattern 120000 | ForEach {
-	$l = $_.ToString()
-	$lnkname = $l.Split('	')[1]
-	$target = "$(git log -p HEAD -- $lnkname | select -last 2 | select -first 1)"
-	$target = $target.SubString(1,$target.Length-1).Replace("/","\")
-	$lnkname = $lnkname.Replace("/","\")
-
-	$terms = $lnkname.Split("\")
-	$dirname = $terms[0..($terms.length-2)] -join "\"
-	$lnkname = "$PWD\$lnkname"
-	$targetAbs = "$((Get-Item -Path "$dirname\$target").FullName)"
-	$targetAbs = $targetAbs.Replace("/", "\")
-
-	if (test-path -pathtype container "$targetAbs") {
-		if (Test-Path "$lnkname") {
-			if ((Get-Item "$lnkname") -is [System.IO.DirectoryInfo]) {
-				# rd so deleting junction doesn't take files with it
-				cmd /c rd  "$lnkname"
-			}
-		}
-		if (Test-Path "$lnkname") {
-			if (!((Get-Item "$lnkname") -is [System.IO.DirectoryInfo])) {
-				cmd /c del /A /F  "$lnkname"
-			}
-		}
-		cmd /c mklink /J  "$lnkname"   "$targetAbs"  ">NUL"
-	} else {
-		# Remove file with symlink data (first run)
-		if (Test-Path "$lnkname") {
-			cmd /c del /A /F  "$lnkname"
-		}
-		cmd /c mklink /H  "$lnkname"   "$targetAbs"  ">NUL"
-	}
-}
-
-if (-not $env:GOPATH) {
-	$orgpath="$PWD\gopath\src\" + $ORG_PATH.Replace("/", "\")
-	if (Test-Path "$orgpath\etcd") {
-		if ((Get-Item "$orgpath\etcd") -is [System.IO.DirectoryInfo]) {
-			# rd so deleting junction doesn't take files with it
-			cmd /c rd  "$orgpath\etcd"
-		}
-	}
-	if (Test-Path "$orgpath") {
-		if ((Get-Item "$orgpath") -is [System.IO.DirectoryInfo]) {
-			# rd so deleting junction doesn't take files with it
-			cmd /c rd  "$orgpath"
-		}
-	}
-	if (Test-Path "$orgpath") {
-		if (!((Get-Item "$orgpath") -is [System.IO.DirectoryInfo])) {
-			# Remove file with symlink data (first run)
-			cmd /c del /A /F  "$orgpath"
-		}
-	}
-	cmd /c mkdir  "$orgpath"
-	cmd /c mklink /J  "$orgpath\etcd"   "$PWD"  ">NUL"
-	$env:GOPATH = "$PWD\gopath"
-}
-
-# Static compilation is useful when etcd is run in a container
-$env:CGO_ENABLED = 0
-$env:GO15VENDOREXPERIMENT = 1
-$GIT_SHA="$(git rev-parse --short HEAD)"
-go build -a -installsuffix cgo -ldflags $GO_LDFLAGS -o bin\etcd.exe "$REPO_PATH\cmd\etcd"
-go build -a -installsuffix cgo -ldflags $GO_LDFLAGS -o bin\etcdctl.exe "$REPO_PATH\cmd\etcdctl"
diff --git a/vendor/github.com/coreos/etcd/client/README.md b/vendor/github.com/coreos/etcd/client/README.md
deleted file mode 100644
index 2be731e..0000000
--- a/vendor/github.com/coreos/etcd/client/README.md
+++ /dev/null
@@ -1,117 +0,0 @@
-# etcd/client
-
-etcd/client is the Go client library for etcd.
-
-[![GoDoc](https://godoc.org/github.com/coreos/etcd/client?status.png)](https://godoc.org/github.com/coreos/etcd/client)
-
-etcd uses `cmd/vendor` directory to store external dependencies, which are
-to be compiled into etcd release binaries. `client` can be imported without
-vendoring. For full compatibility, it is recommended to vendor builds using
-etcd's vendored packages, using tools like godep, as in
-[vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories).
-For more detail, please read [Go vendor design](https://golang.org/s/go15vendor).
-
-## Install
-
-```bash
-go get github.com/coreos/etcd/client
-```
-
-## Usage
-
-```go
-package main
-
-import (
-	"log"
-	"time"
-	"context"
-
-	"github.com/coreos/etcd/client"
-)
-
-func main() {
-	cfg := client.Config{
-		Endpoints:               []string{"http://127.0.0.1:2379"},
-		Transport:               client.DefaultTransport,
-		// set timeout per request to fail fast when the target endpoint is unavailable
-		HeaderTimeoutPerRequest: time.Second,
-	}
-	c, err := client.New(cfg)
-	if err != nil {
-		log.Fatal(err)
-	}
-	kapi := client.NewKeysAPI(c)
-	// set "/foo" key with "bar" value
-	log.Print("Setting '/foo' key with 'bar' value")
-	resp, err := kapi.Set(context.Background(), "/foo", "bar", nil)
-	if err != nil {
-		log.Fatal(err)
-	} else {
-		// print common key info
-		log.Printf("Set is done. Metadata is %q\n", resp)
-	}
-	// get "/foo" key's value
-	log.Print("Getting '/foo' key value")
-	resp, err = kapi.Get(context.Background(), "/foo", nil)
-	if err != nil {
-		log.Fatal(err)
-	} else {
-		// print common key info
-		log.Printf("Get is done. Metadata is %q\n", resp)
-		// print value
-		log.Printf("%q key has %q value\n", resp.Node.Key, resp.Node.Value)
-	}
-}
-```
-
-## Error Handling
-
-etcd client might return three types of errors.
-
-- context error
-
-Each API call has its first parameter as `context`. A context can be canceled or have an attached deadline. If the context is canceled or reaches its deadline, the responding context error will be returned no matter what internal errors the API call has already encountered.
-
-- cluster error
-
-Each API call tries to send request to the cluster endpoints one by one until it successfully gets a response. If a requests to an endpoint fails, due to exceeding per request timeout or connection issues, the error will be added into a list of errors. If all possible endpoints fail, a cluster error that includes all encountered errors will be returned.
-
-- response error
-
-If the response gets from the cluster is invalid, a plain string error will be returned. For example, it might be a invalid JSON error.
-
-Here is the example code to handle client errors:
-
-```go
-cfg := client.Config{Endpoints: []string{"http://etcd1:2379","http://etcd2:2379","http://etcd3:2379"}}
-c, err := client.New(cfg)
-if err != nil {
-	log.Fatal(err)
-}
-
-kapi := client.NewKeysAPI(c)
-resp, err := kapi.Set(ctx, "test", "bar", nil)
-if err != nil {
-	if err == context.Canceled {
-		// ctx is canceled by another routine
-	} else if err == context.DeadlineExceeded {
-		// ctx is attached with a deadline and it exceeded
-	} else if cerr, ok := err.(*client.ClusterError); ok {
-		// process (cerr.Errors)
-	} else {
-		// bad cluster endpoints, which are not etcd servers
-	}
-}
-```
-
-
-## Caveat
-
-1. etcd/client prefers to use the same endpoint as long as the endpoint continues to work well. This saves socket resources, and improves efficiency for both client and server side. This preference doesn't remove consistency from the data consumed by the client because data replicated to each etcd member has already passed through the consensus process.
-
-2. etcd/client does round-robin rotation on other available endpoints if the preferred endpoint isn't functioning properly. For example, if the member that etcd/client connects to is hard killed, etcd/client will fail on the first attempt with the killed member, and succeed on the second attempt with another member. If it fails to talk to all available endpoints, it will return all errors happened.
-
-3. Default etcd/client cannot handle the case that the remote server is SIGSTOPed now. TCP keepalive mechanism doesn't help in this scenario because operating system may still send TCP keep-alive packets. Over time we'd like to improve this functionality, but solving this issue isn't high priority because a real-life case in which a server is stopped, but the connection is kept alive, hasn't been brought to our attention.
-
-4. etcd/client cannot detect whether a member is healthy with watches and non-quorum read requests. If the member is isolated from the cluster, etcd/client may retrieve outdated data. Instead, users can either issue quorum read requests or monitor the /health endpoint for member health information.
diff --git a/vendor/github.com/coreos/etcd/client/auth_role.go b/vendor/github.com/coreos/etcd/client/auth_role.go
deleted file mode 100644
index b6ba7e1..0000000
--- a/vendor/github.com/coreos/etcd/client/auth_role.go
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"net/http"
-	"net/url"
-)
-
-type Role struct {
-	Role        string       `json:"role"`
-	Permissions Permissions  `json:"permissions"`
-	Grant       *Permissions `json:"grant,omitempty"`
-	Revoke      *Permissions `json:"revoke,omitempty"`
-}
-
-type Permissions struct {
-	KV rwPermission `json:"kv"`
-}
-
-type rwPermission struct {
-	Read  []string `json:"read"`
-	Write []string `json:"write"`
-}
-
-type PermissionType int
-
-const (
-	ReadPermission PermissionType = iota
-	WritePermission
-	ReadWritePermission
-)
-
-// NewAuthRoleAPI constructs a new AuthRoleAPI that uses HTTP to
-// interact with etcd's role creation and modification features.
-func NewAuthRoleAPI(c Client) AuthRoleAPI {
-	return &httpAuthRoleAPI{
-		client: c,
-	}
-}
-
-type AuthRoleAPI interface {
-	// AddRole adds a role.
-	AddRole(ctx context.Context, role string) error
-
-	// RemoveRole removes a role.
-	RemoveRole(ctx context.Context, role string) error
-
-	// GetRole retrieves role details.
-	GetRole(ctx context.Context, role string) (*Role, error)
-
-	// GrantRoleKV grants a role some permission prefixes for the KV store.
-	GrantRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error)
-
-	// RevokeRoleKV revokes some permission prefixes for a role on the KV store.
-	RevokeRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error)
-
-	// ListRoles lists roles.
-	ListRoles(ctx context.Context) ([]string, error)
-}
-
-type httpAuthRoleAPI struct {
-	client httpClient
-}
-
-type authRoleAPIAction struct {
-	verb string
-	name string
-	role *Role
-}
-
-type authRoleAPIList struct{}
-
-func (list *authRoleAPIList) HTTPRequest(ep url.URL) *http.Request {
-	u := v2AuthURL(ep, "roles", "")
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-func (l *authRoleAPIAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2AuthURL(ep, "roles", l.name)
-	if l.role == nil {
-		req, _ := http.NewRequest(l.verb, u.String(), nil)
-		return req
-	}
-	b, err := json.Marshal(l.role)
-	if err != nil {
-		panic(err)
-	}
-	body := bytes.NewReader(b)
-	req, _ := http.NewRequest(l.verb, u.String(), body)
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-func (r *httpAuthRoleAPI) ListRoles(ctx context.Context) ([]string, error) {
-	resp, body, err := r.client.Do(ctx, &authRoleAPIList{})
-	if err != nil {
-		return nil, err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		return nil, err
-	}
-	var roleList struct {
-		Roles []Role `json:"roles"`
-	}
-	if err = json.Unmarshal(body, &roleList); err != nil {
-		return nil, err
-	}
-	ret := make([]string, 0, len(roleList.Roles))
-	for _, r := range roleList.Roles {
-		ret = append(ret, r.Role)
-	}
-	return ret, nil
-}
-
-func (r *httpAuthRoleAPI) AddRole(ctx context.Context, rolename string) error {
-	role := &Role{
-		Role: rolename,
-	}
-	return r.addRemoveRole(ctx, &authRoleAPIAction{
-		verb: "PUT",
-		name: rolename,
-		role: role,
-	})
-}
-
-func (r *httpAuthRoleAPI) RemoveRole(ctx context.Context, rolename string) error {
-	return r.addRemoveRole(ctx, &authRoleAPIAction{
-		verb: "DELETE",
-		name: rolename,
-	})
-}
-
-func (r *httpAuthRoleAPI) addRemoveRole(ctx context.Context, req *authRoleAPIAction) error {
-	resp, body, err := r.client.Do(ctx, req)
-	if err != nil {
-		return err
-	}
-	if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
-		var sec authError
-		err := json.Unmarshal(body, &sec)
-		if err != nil {
-			return err
-		}
-		return sec
-	}
-	return nil
-}
-
-func (r *httpAuthRoleAPI) GetRole(ctx context.Context, rolename string) (*Role, error) {
-	return r.modRole(ctx, &authRoleAPIAction{
-		verb: "GET",
-		name: rolename,
-	})
-}
-
-func buildRWPermission(prefixes []string, permType PermissionType) rwPermission {
-	var out rwPermission
-	switch permType {
-	case ReadPermission:
-		out.Read = prefixes
-	case WritePermission:
-		out.Write = prefixes
-	case ReadWritePermission:
-		out.Read = prefixes
-		out.Write = prefixes
-	}
-	return out
-}
-
-func (r *httpAuthRoleAPI) GrantRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
-	rwp := buildRWPermission(prefixes, permType)
-	role := &Role{
-		Role: rolename,
-		Grant: &Permissions{
-			KV: rwp,
-		},
-	}
-	return r.modRole(ctx, &authRoleAPIAction{
-		verb: "PUT",
-		name: rolename,
-		role: role,
-	})
-}
-
-func (r *httpAuthRoleAPI) RevokeRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
-	rwp := buildRWPermission(prefixes, permType)
-	role := &Role{
-		Role: rolename,
-		Revoke: &Permissions{
-			KV: rwp,
-		},
-	}
-	return r.modRole(ctx, &authRoleAPIAction{
-		verb: "PUT",
-		name: rolename,
-		role: role,
-	})
-}
-
-func (r *httpAuthRoleAPI) modRole(ctx context.Context, req *authRoleAPIAction) (*Role, error) {
-	resp, body, err := r.client.Do(ctx, req)
-	if err != nil {
-		return nil, err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		var sec authError
-		err = json.Unmarshal(body, &sec)
-		if err != nil {
-			return nil, err
-		}
-		return nil, sec
-	}
-	var role Role
-	if err = json.Unmarshal(body, &role); err != nil {
-		return nil, err
-	}
-	return &role, nil
-}
diff --git a/vendor/github.com/coreos/etcd/client/auth_user.go b/vendor/github.com/coreos/etcd/client/auth_user.go
deleted file mode 100644
index 8e7e2ef..0000000
--- a/vendor/github.com/coreos/etcd/client/auth_user.go
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"net/http"
-	"net/url"
-	"path"
-)
-
-var (
-	defaultV2AuthPrefix = "/v2/auth"
-)
-
-type User struct {
-	User     string   `json:"user"`
-	Password string   `json:"password,omitempty"`
-	Roles    []string `json:"roles"`
-	Grant    []string `json:"grant,omitempty"`
-	Revoke   []string `json:"revoke,omitempty"`
-}
-
-// userListEntry is the user representation given by the server for ListUsers
-type userListEntry struct {
-	User  string `json:"user"`
-	Roles []Role `json:"roles"`
-}
-
-type UserRoles struct {
-	User  string `json:"user"`
-	Roles []Role `json:"roles"`
-}
-
-func v2AuthURL(ep url.URL, action string, name string) *url.URL {
-	if name != "" {
-		ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action, name)
-		return &ep
-	}
-	ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action)
-	return &ep
-}
-
-// NewAuthAPI constructs a new AuthAPI that uses HTTP to
-// interact with etcd's general auth features.
-func NewAuthAPI(c Client) AuthAPI {
-	return &httpAuthAPI{
-		client: c,
-	}
-}
-
-type AuthAPI interface {
-	// Enable auth.
-	Enable(ctx context.Context) error
-
-	// Disable auth.
-	Disable(ctx context.Context) error
-}
-
-type httpAuthAPI struct {
-	client httpClient
-}
-
-func (s *httpAuthAPI) Enable(ctx context.Context) error {
-	return s.enableDisable(ctx, &authAPIAction{"PUT"})
-}
-
-func (s *httpAuthAPI) Disable(ctx context.Context) error {
-	return s.enableDisable(ctx, &authAPIAction{"DELETE"})
-}
-
-func (s *httpAuthAPI) enableDisable(ctx context.Context, req httpAction) error {
-	resp, body, err := s.client.Do(ctx, req)
-	if err != nil {
-		return err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
-		var sec authError
-		err = json.Unmarshal(body, &sec)
-		if err != nil {
-			return err
-		}
-		return sec
-	}
-	return nil
-}
-
-type authAPIAction struct {
-	verb string
-}
-
-func (l *authAPIAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2AuthURL(ep, "enable", "")
-	req, _ := http.NewRequest(l.verb, u.String(), nil)
-	return req
-}
-
-type authError struct {
-	Message string `json:"message"`
-	Code    int    `json:"-"`
-}
-
-func (e authError) Error() string {
-	return e.Message
-}
-
-// NewAuthUserAPI constructs a new AuthUserAPI that uses HTTP to
-// interact with etcd's user creation and modification features.
-func NewAuthUserAPI(c Client) AuthUserAPI {
-	return &httpAuthUserAPI{
-		client: c,
-	}
-}
-
-type AuthUserAPI interface {
-	// AddUser adds a user.
-	AddUser(ctx context.Context, username string, password string) error
-
-	// RemoveUser removes a user.
-	RemoveUser(ctx context.Context, username string) error
-
-	// GetUser retrieves user details.
-	GetUser(ctx context.Context, username string) (*User, error)
-
-	// GrantUser grants a user some permission roles.
-	GrantUser(ctx context.Context, username string, roles []string) (*User, error)
-
-	// RevokeUser revokes some permission roles from a user.
-	RevokeUser(ctx context.Context, username string, roles []string) (*User, error)
-
-	// ChangePassword changes the user's password.
-	ChangePassword(ctx context.Context, username string, password string) (*User, error)
-
-	// ListUsers lists the users.
-	ListUsers(ctx context.Context) ([]string, error)
-}
-
-type httpAuthUserAPI struct {
-	client httpClient
-}
-
-type authUserAPIAction struct {
-	verb     string
-	username string
-	user     *User
-}
-
-type authUserAPIList struct{}
-
-func (list *authUserAPIList) HTTPRequest(ep url.URL) *http.Request {
-	u := v2AuthURL(ep, "users", "")
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-func (l *authUserAPIAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2AuthURL(ep, "users", l.username)
-	if l.user == nil {
-		req, _ := http.NewRequest(l.verb, u.String(), nil)
-		return req
-	}
-	b, err := json.Marshal(l.user)
-	if err != nil {
-		panic(err)
-	}
-	body := bytes.NewReader(b)
-	req, _ := http.NewRequest(l.verb, u.String(), body)
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-func (u *httpAuthUserAPI) ListUsers(ctx context.Context) ([]string, error) {
-	resp, body, err := u.client.Do(ctx, &authUserAPIList{})
-	if err != nil {
-		return nil, err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		var sec authError
-		err = json.Unmarshal(body, &sec)
-		if err != nil {
-			return nil, err
-		}
-		return nil, sec
-	}
-
-	var userList struct {
-		Users []userListEntry `json:"users"`
-	}
-
-	if err = json.Unmarshal(body, &userList); err != nil {
-		return nil, err
-	}
-
-	ret := make([]string, 0, len(userList.Users))
-	for _, u := range userList.Users {
-		ret = append(ret, u.User)
-	}
-	return ret, nil
-}
-
-func (u *httpAuthUserAPI) AddUser(ctx context.Context, username string, password string) error {
-	user := &User{
-		User:     username,
-		Password: password,
-	}
-	return u.addRemoveUser(ctx, &authUserAPIAction{
-		verb:     "PUT",
-		username: username,
-		user:     user,
-	})
-}
-
-func (u *httpAuthUserAPI) RemoveUser(ctx context.Context, username string) error {
-	return u.addRemoveUser(ctx, &authUserAPIAction{
-		verb:     "DELETE",
-		username: username,
-	})
-}
-
-func (u *httpAuthUserAPI) addRemoveUser(ctx context.Context, req *authUserAPIAction) error {
-	resp, body, err := u.client.Do(ctx, req)
-	if err != nil {
-		return err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
-		var sec authError
-		err = json.Unmarshal(body, &sec)
-		if err != nil {
-			return err
-		}
-		return sec
-	}
-	return nil
-}
-
-func (u *httpAuthUserAPI) GetUser(ctx context.Context, username string) (*User, error) {
-	return u.modUser(ctx, &authUserAPIAction{
-		verb:     "GET",
-		username: username,
-	})
-}
-
-func (u *httpAuthUserAPI) GrantUser(ctx context.Context, username string, roles []string) (*User, error) {
-	user := &User{
-		User:  username,
-		Grant: roles,
-	}
-	return u.modUser(ctx, &authUserAPIAction{
-		verb:     "PUT",
-		username: username,
-		user:     user,
-	})
-}
-
-func (u *httpAuthUserAPI) RevokeUser(ctx context.Context, username string, roles []string) (*User, error) {
-	user := &User{
-		User:   username,
-		Revoke: roles,
-	}
-	return u.modUser(ctx, &authUserAPIAction{
-		verb:     "PUT",
-		username: username,
-		user:     user,
-	})
-}
-
-func (u *httpAuthUserAPI) ChangePassword(ctx context.Context, username string, password string) (*User, error) {
-	user := &User{
-		User:     username,
-		Password: password,
-	}
-	return u.modUser(ctx, &authUserAPIAction{
-		verb:     "PUT",
-		username: username,
-		user:     user,
-	})
-}
-
-func (u *httpAuthUserAPI) modUser(ctx context.Context, req *authUserAPIAction) (*User, error) {
-	resp, body, err := u.client.Do(ctx, req)
-	if err != nil {
-		return nil, err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		var sec authError
-		err = json.Unmarshal(body, &sec)
-		if err != nil {
-			return nil, err
-		}
-		return nil, sec
-	}
-	var user User
-	if err = json.Unmarshal(body, &user); err != nil {
-		var userR UserRoles
-		if urerr := json.Unmarshal(body, &userR); urerr != nil {
-			return nil, err
-		}
-		user.User = userR.User
-		for _, r := range userR.Roles {
-			user.Roles = append(user.Roles, r.Role)
-		}
-	}
-	return &user, nil
-}
diff --git a/vendor/github.com/coreos/etcd/client/cancelreq.go b/vendor/github.com/coreos/etcd/client/cancelreq.go
deleted file mode 100644
index 76d1f04..0000000
--- a/vendor/github.com/coreos/etcd/client/cancelreq.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// borrowed from golang/net/context/ctxhttp/cancelreq.go
-
-package client
-
-import "net/http"
-
-func requestCanceler(tr CancelableTransport, req *http.Request) func() {
-	ch := make(chan struct{})
-	req.Cancel = ch
-
-	return func() {
-		close(ch)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/client/client.go b/vendor/github.com/coreos/etcd/client/client.go
deleted file mode 100644
index e687450..0000000
--- a/vendor/github.com/coreos/etcd/client/client.go
+++ /dev/null
@@ -1,710 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import (
-	"context"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"math/rand"
-	"net"
-	"net/http"
-	"net/url"
-	"sort"
-	"strconv"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/version"
-)
-
-var (
-	ErrNoEndpoints           = errors.New("client: no endpoints available")
-	ErrTooManyRedirects      = errors.New("client: too many redirects")
-	ErrClusterUnavailable    = errors.New("client: etcd cluster is unavailable or misconfigured")
-	ErrNoLeaderEndpoint      = errors.New("client: no leader endpoint available")
-	errTooManyRedirectChecks = errors.New("client: too many redirect checks")
-
-	// oneShotCtxValue is set on a context using WithValue(&oneShotValue) so
-	// that Do() will not retry a request
-	oneShotCtxValue interface{}
-)
-
-var DefaultRequestTimeout = 5 * time.Second
-
-var DefaultTransport CancelableTransport = &http.Transport{
-	Proxy: http.ProxyFromEnvironment,
-	Dial: (&net.Dialer{
-		Timeout:   30 * time.Second,
-		KeepAlive: 30 * time.Second,
-	}).Dial,
-	TLSHandshakeTimeout: 10 * time.Second,
-}
-
-type EndpointSelectionMode int
-
-const (
-	// EndpointSelectionRandom is the default value of the 'SelectionMode'.
-	// As the name implies, the client object will pick a node from the members
-	// of the cluster in a random fashion. If the cluster has three members, A, B,
-	// and C, the client picks any node from its three members as its request
-	// destination.
-	EndpointSelectionRandom EndpointSelectionMode = iota
-
-	// If 'SelectionMode' is set to 'EndpointSelectionPrioritizeLeader',
-	// requests are sent directly to the cluster leader. This reduces
-	// forwarding roundtrips compared to making requests to etcd followers
-	// who then forward them to the cluster leader. In the event of a leader
-	// failure, however, clients configured this way cannot prioritize among
-	// the remaining etcd followers. Therefore, when a client sets 'SelectionMode'
-	// to 'EndpointSelectionPrioritizeLeader', it must use 'client.AutoSync()' to
-	// maintain its knowledge of current cluster state.
-	//
-	// This mode should be used with Client.AutoSync().
-	EndpointSelectionPrioritizeLeader
-)
-
-type Config struct {
-	// Endpoints defines a set of URLs (schemes, hosts and ports only)
-	// that can be used to communicate with a logical etcd cluster. For
-	// example, a three-node cluster could be provided like so:
-	//
-	// 	Endpoints: []string{
-	//		"http://node1.example.com:2379",
-	//		"http://node2.example.com:2379",
-	//		"http://node3.example.com:2379",
-	//	}
-	//
-	// If multiple endpoints are provided, the Client will attempt to
-	// use them all in the event that one or more of them are unusable.
-	//
-	// If Client.Sync is ever called, the Client may cache an alternate
-	// set of endpoints to continue operation.
-	Endpoints []string
-
-	// Transport is used by the Client to drive HTTP requests. If not
-	// provided, DefaultTransport will be used.
-	Transport CancelableTransport
-
-	// CheckRedirect specifies the policy for handling HTTP redirects.
-	// If CheckRedirect is not nil, the Client calls it before
-	// following an HTTP redirect. The sole argument is the number of
-	// requests that have already been made. If CheckRedirect returns
-	// an error, Client.Do will not make any further requests and return
-	// the error back it to the caller.
-	//
-	// If CheckRedirect is nil, the Client uses its default policy,
-	// which is to stop after 10 consecutive requests.
-	CheckRedirect CheckRedirectFunc
-
-	// Username specifies the user credential to add as an authorization header
-	Username string
-
-	// Password is the password for the specified user to add as an authorization header
-	// to the request.
-	Password string
-
-	// HeaderTimeoutPerRequest specifies the time limit to wait for response
-	// header in a single request made by the Client. The timeout includes
-	// connection time, any redirects, and header wait time.
-	//
-	// For non-watch GET request, server returns the response body immediately.
-	// For PUT/POST/DELETE request, server will attempt to commit request
-	// before responding, which is expected to take `100ms + 2 * RTT`.
-	// For watch request, server returns the header immediately to notify Client
-	// watch start. But if server is behind some kind of proxy, the response
-	// header may be cached at proxy, and Client cannot rely on this behavior.
-	//
-	// Especially, wait request will ignore this timeout.
-	//
-	// One API call may send multiple requests to different etcd servers until it
-	// succeeds. Use context of the API to specify the overall timeout.
-	//
-	// A HeaderTimeoutPerRequest of zero means no timeout.
-	HeaderTimeoutPerRequest time.Duration
-
-	// SelectionMode is an EndpointSelectionMode enum that specifies the
-	// policy for choosing the etcd cluster node to which requests are sent.
-	SelectionMode EndpointSelectionMode
-}
-
-func (cfg *Config) transport() CancelableTransport {
-	if cfg.Transport == nil {
-		return DefaultTransport
-	}
-	return cfg.Transport
-}
-
-func (cfg *Config) checkRedirect() CheckRedirectFunc {
-	if cfg.CheckRedirect == nil {
-		return DefaultCheckRedirect
-	}
-	return cfg.CheckRedirect
-}
-
-// CancelableTransport mimics net/http.Transport, but requires that
-// the object also support request cancellation.
-type CancelableTransport interface {
-	http.RoundTripper
-	CancelRequest(req *http.Request)
-}
-
-type CheckRedirectFunc func(via int) error
-
-// DefaultCheckRedirect follows up to 10 redirects, but no more.
-var DefaultCheckRedirect CheckRedirectFunc = func(via int) error {
-	if via > 10 {
-		return ErrTooManyRedirects
-	}
-	return nil
-}
-
-type Client interface {
-	// Sync updates the internal cache of the etcd cluster's membership.
-	Sync(context.Context) error
-
-	// AutoSync periodically calls Sync() every given interval.
-	// The recommended sync interval is 10 seconds to 1 minute, which does
-	// not bring too much overhead to server and makes client catch up the
-	// cluster change in time.
-	//
-	// The example to use it:
-	//
-	//  for {
-	//      err := client.AutoSync(ctx, 10*time.Second)
-	//      if err == context.DeadlineExceeded || err == context.Canceled {
-	//          break
-	//      }
-	//      log.Print(err)
-	//  }
-	AutoSync(context.Context, time.Duration) error
-
-	// Endpoints returns a copy of the current set of API endpoints used
-	// by Client to resolve HTTP requests. If Sync has ever been called,
-	// this may differ from the initial Endpoints provided in the Config.
-	Endpoints() []string
-
-	// SetEndpoints sets the set of API endpoints used by Client to resolve
-	// HTTP requests. If the given endpoints are not valid, an error will be
-	// returned
-	SetEndpoints(eps []string) error
-
-	// GetVersion retrieves the current etcd server and cluster version
-	GetVersion(ctx context.Context) (*version.Versions, error)
-
-	httpClient
-}
-
-func New(cfg Config) (Client, error) {
-	c := &httpClusterClient{
-		clientFactory: newHTTPClientFactory(cfg.transport(), cfg.checkRedirect(), cfg.HeaderTimeoutPerRequest),
-		rand:          rand.New(rand.NewSource(int64(time.Now().Nanosecond()))),
-		selectionMode: cfg.SelectionMode,
-	}
-	if cfg.Username != "" {
-		c.credentials = &credentials{
-			username: cfg.Username,
-			password: cfg.Password,
-		}
-	}
-	if err := c.SetEndpoints(cfg.Endpoints); err != nil {
-		return nil, err
-	}
-	return c, nil
-}
-
-type httpClient interface {
-	Do(context.Context, httpAction) (*http.Response, []byte, error)
-}
-
-func newHTTPClientFactory(tr CancelableTransport, cr CheckRedirectFunc, headerTimeout time.Duration) httpClientFactory {
-	return func(ep url.URL) httpClient {
-		return &redirectFollowingHTTPClient{
-			checkRedirect: cr,
-			client: &simpleHTTPClient{
-				transport:     tr,
-				endpoint:      ep,
-				headerTimeout: headerTimeout,
-			},
-		}
-	}
-}
-
-type credentials struct {
-	username string
-	password string
-}
-
-type httpClientFactory func(url.URL) httpClient
-
-type httpAction interface {
-	HTTPRequest(url.URL) *http.Request
-}
-
-type httpClusterClient struct {
-	clientFactory httpClientFactory
-	endpoints     []url.URL
-	pinned        int
-	credentials   *credentials
-	sync.RWMutex
-	rand          *rand.Rand
-	selectionMode EndpointSelectionMode
-}
-
-func (c *httpClusterClient) getLeaderEndpoint(ctx context.Context, eps []url.URL) (string, error) {
-	ceps := make([]url.URL, len(eps))
-	copy(ceps, eps)
-
-	// To perform a lookup on the new endpoint list without using the current
-	// client, we'll copy it
-	clientCopy := &httpClusterClient{
-		clientFactory: c.clientFactory,
-		credentials:   c.credentials,
-		rand:          c.rand,
-
-		pinned:    0,
-		endpoints: ceps,
-	}
-
-	mAPI := NewMembersAPI(clientCopy)
-	leader, err := mAPI.Leader(ctx)
-	if err != nil {
-		return "", err
-	}
-	if len(leader.ClientURLs) == 0 {
-		return "", ErrNoLeaderEndpoint
-	}
-
-	return leader.ClientURLs[0], nil // TODO: how to handle multiple client URLs?
-}
-
-func (c *httpClusterClient) parseEndpoints(eps []string) ([]url.URL, error) {
-	if len(eps) == 0 {
-		return []url.URL{}, ErrNoEndpoints
-	}
-
-	neps := make([]url.URL, len(eps))
-	for i, ep := range eps {
-		u, err := url.Parse(ep)
-		if err != nil {
-			return []url.URL{}, err
-		}
-		neps[i] = *u
-	}
-	return neps, nil
-}
-
-func (c *httpClusterClient) SetEndpoints(eps []string) error {
-	neps, err := c.parseEndpoints(eps)
-	if err != nil {
-		return err
-	}
-
-	c.Lock()
-	defer c.Unlock()
-
-	c.endpoints = shuffleEndpoints(c.rand, neps)
-	// We're not doing anything for PrioritizeLeader here. This is
-	// due to not having a context meaning we can't call getLeaderEndpoint
-	// However, if you're using PrioritizeLeader, you've already been told
-	// to regularly call sync, where we do have a ctx, and can figure the
-	// leader. PrioritizeLeader is also quite a loose guarantee, so deal
-	// with it
-	c.pinned = 0
-
-	return nil
-}
-
-func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) {
-	action := act
-	c.RLock()
-	leps := len(c.endpoints)
-	eps := make([]url.URL, leps)
-	n := copy(eps, c.endpoints)
-	pinned := c.pinned
-
-	if c.credentials != nil {
-		action = &authedAction{
-			act:         act,
-			credentials: *c.credentials,
-		}
-	}
-	c.RUnlock()
-
-	if leps == 0 {
-		return nil, nil, ErrNoEndpoints
-	}
-
-	if leps != n {
-		return nil, nil, errors.New("unable to pick endpoint: copy failed")
-	}
-
-	var resp *http.Response
-	var body []byte
-	var err error
-	cerr := &ClusterError{}
-	isOneShot := ctx.Value(&oneShotCtxValue) != nil
-
-	for i := pinned; i < leps+pinned; i++ {
-		k := i % leps
-		hc := c.clientFactory(eps[k])
-		resp, body, err = hc.Do(ctx, action)
-		if err != nil {
-			cerr.Errors = append(cerr.Errors, err)
-			if err == ctx.Err() {
-				return nil, nil, ctx.Err()
-			}
-			if err == context.Canceled || err == context.DeadlineExceeded {
-				return nil, nil, err
-			}
-		} else if resp.StatusCode/100 == 5 {
-			switch resp.StatusCode {
-			case http.StatusInternalServerError, http.StatusServiceUnavailable:
-				// TODO: make sure this is a no leader response
-				cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s has no leader", eps[k].String()))
-			default:
-				cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s returns server error [%s]", eps[k].String(), http.StatusText(resp.StatusCode)))
-			}
-			err = cerr.Errors[0]
-		}
-		if err != nil {
-			if !isOneShot {
-				continue
-			}
-			c.Lock()
-			c.pinned = (k + 1) % leps
-			c.Unlock()
-			return nil, nil, err
-		}
-		if k != pinned {
-			c.Lock()
-			c.pinned = k
-			c.Unlock()
-		}
-		return resp, body, nil
-	}
-
-	return nil, nil, cerr
-}
-
-func (c *httpClusterClient) Endpoints() []string {
-	c.RLock()
-	defer c.RUnlock()
-
-	eps := make([]string, len(c.endpoints))
-	for i, ep := range c.endpoints {
-		eps[i] = ep.String()
-	}
-
-	return eps
-}
-
-func (c *httpClusterClient) Sync(ctx context.Context) error {
-	mAPI := NewMembersAPI(c)
-	ms, err := mAPI.List(ctx)
-	if err != nil {
-		return err
-	}
-
-	var eps []string
-	for _, m := range ms {
-		eps = append(eps, m.ClientURLs...)
-	}
-
-	neps, err := c.parseEndpoints(eps)
-	if err != nil {
-		return err
-	}
-
-	npin := 0
-
-	switch c.selectionMode {
-	case EndpointSelectionRandom:
-		c.RLock()
-		eq := endpointsEqual(c.endpoints, neps)
-		c.RUnlock()
-
-		if eq {
-			return nil
-		}
-		// When items in the endpoint list changes, we choose a new pin
-		neps = shuffleEndpoints(c.rand, neps)
-	case EndpointSelectionPrioritizeLeader:
-		nle, err := c.getLeaderEndpoint(ctx, neps)
-		if err != nil {
-			return ErrNoLeaderEndpoint
-		}
-
-		for i, n := range neps {
-			if n.String() == nle {
-				npin = i
-				break
-			}
-		}
-	default:
-		return fmt.Errorf("invalid endpoint selection mode: %d", c.selectionMode)
-	}
-
-	c.Lock()
-	defer c.Unlock()
-	c.endpoints = neps
-	c.pinned = npin
-
-	return nil
-}
-
-func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration) error {
-	ticker := time.NewTicker(interval)
-	defer ticker.Stop()
-	for {
-		err := c.Sync(ctx)
-		if err != nil {
-			return err
-		}
-		select {
-		case <-ctx.Done():
-			return ctx.Err()
-		case <-ticker.C:
-		}
-	}
-}
-
-func (c *httpClusterClient) GetVersion(ctx context.Context) (*version.Versions, error) {
-	act := &getAction{Prefix: "/version"}
-
-	resp, body, err := c.Do(ctx, act)
-	if err != nil {
-		return nil, err
-	}
-
-	switch resp.StatusCode {
-	case http.StatusOK:
-		if len(body) == 0 {
-			return nil, ErrEmptyBody
-		}
-		var vresp version.Versions
-		if err := json.Unmarshal(body, &vresp); err != nil {
-			return nil, ErrInvalidJSON
-		}
-		return &vresp, nil
-	default:
-		var etcdErr Error
-		if err := json.Unmarshal(body, &etcdErr); err != nil {
-			return nil, ErrInvalidJSON
-		}
-		return nil, etcdErr
-	}
-}
-
-type roundTripResponse struct {
-	resp *http.Response
-	err  error
-}
-
-type simpleHTTPClient struct {
-	transport     CancelableTransport
-	endpoint      url.URL
-	headerTimeout time.Duration
-}
-
-func (c *simpleHTTPClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) {
-	req := act.HTTPRequest(c.endpoint)
-
-	if err := printcURL(req); err != nil {
-		return nil, nil, err
-	}
-
-	isWait := false
-	if req != nil && req.URL != nil {
-		ws := req.URL.Query().Get("wait")
-		if len(ws) != 0 {
-			var err error
-			isWait, err = strconv.ParseBool(ws)
-			if err != nil {
-				return nil, nil, fmt.Errorf("wrong wait value %s (%v for %+v)", ws, err, req)
-			}
-		}
-	}
-
-	var hctx context.Context
-	var hcancel context.CancelFunc
-	if !isWait && c.headerTimeout > 0 {
-		hctx, hcancel = context.WithTimeout(ctx, c.headerTimeout)
-	} else {
-		hctx, hcancel = context.WithCancel(ctx)
-	}
-	defer hcancel()
-
-	reqcancel := requestCanceler(c.transport, req)
-
-	rtchan := make(chan roundTripResponse, 1)
-	go func() {
-		resp, err := c.transport.RoundTrip(req)
-		rtchan <- roundTripResponse{resp: resp, err: err}
-		close(rtchan)
-	}()
-
-	var resp *http.Response
-	var err error
-
-	select {
-	case rtresp := <-rtchan:
-		resp, err = rtresp.resp, rtresp.err
-	case <-hctx.Done():
-		// cancel and wait for request to actually exit before continuing
-		reqcancel()
-		rtresp := <-rtchan
-		resp = rtresp.resp
-		switch {
-		case ctx.Err() != nil:
-			err = ctx.Err()
-		case hctx.Err() != nil:
-			err = fmt.Errorf("client: endpoint %s exceeded header timeout", c.endpoint.String())
-		default:
-			panic("failed to get error from context")
-		}
-	}
-
-	// always check for resp nil-ness to deal with possible
-	// race conditions between channels above
-	defer func() {
-		if resp != nil {
-			resp.Body.Close()
-		}
-	}()
-
-	if err != nil {
-		return nil, nil, err
-	}
-
-	var body []byte
-	done := make(chan struct{})
-	go func() {
-		body, err = ioutil.ReadAll(resp.Body)
-		done <- struct{}{}
-	}()
-
-	select {
-	case <-ctx.Done():
-		resp.Body.Close()
-		<-done
-		return nil, nil, ctx.Err()
-	case <-done:
-	}
-
-	return resp, body, err
-}
-
-type authedAction struct {
-	act         httpAction
-	credentials credentials
-}
-
-func (a *authedAction) HTTPRequest(url url.URL) *http.Request {
-	r := a.act.HTTPRequest(url)
-	r.SetBasicAuth(a.credentials.username, a.credentials.password)
-	return r
-}
-
-type redirectFollowingHTTPClient struct {
-	client        httpClient
-	checkRedirect CheckRedirectFunc
-}
-
-func (r *redirectFollowingHTTPClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) {
-	next := act
-	for i := 0; i < 100; i++ {
-		if i > 0 {
-			if err := r.checkRedirect(i); err != nil {
-				return nil, nil, err
-			}
-		}
-		resp, body, err := r.client.Do(ctx, next)
-		if err != nil {
-			return nil, nil, err
-		}
-		if resp.StatusCode/100 == 3 {
-			hdr := resp.Header.Get("Location")
-			if hdr == "" {
-				return nil, nil, fmt.Errorf("Location header not set")
-			}
-			loc, err := url.Parse(hdr)
-			if err != nil {
-				return nil, nil, fmt.Errorf("Location header not valid URL: %s", hdr)
-			}
-			next = &redirectedHTTPAction{
-				action:   act,
-				location: *loc,
-			}
-			continue
-		}
-		return resp, body, nil
-	}
-
-	return nil, nil, errTooManyRedirectChecks
-}
-
-type redirectedHTTPAction struct {
-	action   httpAction
-	location url.URL
-}
-
-func (r *redirectedHTTPAction) HTTPRequest(ep url.URL) *http.Request {
-	orig := r.action.HTTPRequest(ep)
-	orig.URL = &r.location
-	return orig
-}
-
-func shuffleEndpoints(r *rand.Rand, eps []url.URL) []url.URL {
-	// copied from Go 1.9<= rand.Rand.Perm
-	n := len(eps)
-	p := make([]int, n)
-	for i := 0; i < n; i++ {
-		j := r.Intn(i + 1)
-		p[i] = p[j]
-		p[j] = i
-	}
-	neps := make([]url.URL, n)
-	for i, k := range p {
-		neps[i] = eps[k]
-	}
-	return neps
-}
-
-func endpointsEqual(left, right []url.URL) bool {
-	if len(left) != len(right) {
-		return false
-	}
-
-	sLeft := make([]string, len(left))
-	sRight := make([]string, len(right))
-	for i, l := range left {
-		sLeft[i] = l.String()
-	}
-	for i, r := range right {
-		sRight[i] = r.String()
-	}
-
-	sort.Strings(sLeft)
-	sort.Strings(sRight)
-	for i := range sLeft {
-		if sLeft[i] != sRight[i] {
-			return false
-		}
-	}
-	return true
-}
diff --git a/vendor/github.com/coreos/etcd/client/cluster_error.go b/vendor/github.com/coreos/etcd/client/cluster_error.go
deleted file mode 100644
index 34618cd..0000000
--- a/vendor/github.com/coreos/etcd/client/cluster_error.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import "fmt"
-
-type ClusterError struct {
-	Errors []error
-}
-
-func (ce *ClusterError) Error() string {
-	s := ErrClusterUnavailable.Error()
-	for i, e := range ce.Errors {
-		s += fmt.Sprintf("; error #%d: %s\n", i, e)
-	}
-	return s
-}
-
-func (ce *ClusterError) Detail() string {
-	s := ""
-	for i, e := range ce.Errors {
-		s += fmt.Sprintf("error #%d: %s\n", i, e)
-	}
-	return s
-}
diff --git a/vendor/github.com/coreos/etcd/client/curl.go b/vendor/github.com/coreos/etcd/client/curl.go
deleted file mode 100644
index c8bc9fb..0000000
--- a/vendor/github.com/coreos/etcd/client/curl.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import (
-	"bytes"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"os"
-)
-
-var (
-	cURLDebug = false
-)
-
-func EnablecURLDebug() {
-	cURLDebug = true
-}
-
-func DisablecURLDebug() {
-	cURLDebug = false
-}
-
-// printcURL prints the cURL equivalent request to stderr.
-// It returns an error if the body of the request cannot
-// be read.
-// The caller MUST cancel the request if there is an error.
-func printcURL(req *http.Request) error {
-	if !cURLDebug {
-		return nil
-	}
-	var (
-		command string
-		b       []byte
-		err     error
-	)
-
-	if req.URL != nil {
-		command = fmt.Sprintf("curl -X %s %s", req.Method, req.URL.String())
-	}
-
-	if req.Body != nil {
-		b, err = ioutil.ReadAll(req.Body)
-		if err != nil {
-			return err
-		}
-		command += fmt.Sprintf(" -d %q", string(b))
-	}
-
-	fmt.Fprintf(os.Stderr, "cURL Command: %s\n", command)
-
-	// reset body
-	body := bytes.NewBuffer(b)
-	req.Body = ioutil.NopCloser(body)
-
-	return nil
-}
diff --git a/vendor/github.com/coreos/etcd/client/discover.go b/vendor/github.com/coreos/etcd/client/discover.go
deleted file mode 100644
index 442e35f..0000000
--- a/vendor/github.com/coreos/etcd/client/discover.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import (
-	"github.com/coreos/etcd/pkg/srv"
-)
-
-// Discoverer is an interface that wraps the Discover method.
-type Discoverer interface {
-	// Discover looks up the etcd servers for the domain.
-	Discover(domain string) ([]string, error)
-}
-
-type srvDiscover struct{}
-
-// NewSRVDiscover constructs a new Discoverer that uses the stdlib to lookup SRV records.
-func NewSRVDiscover() Discoverer {
-	return &srvDiscover{}
-}
-
-func (d *srvDiscover) Discover(domain string) ([]string, error) {
-	srvs, err := srv.GetClient("etcd-client", domain)
-	if err != nil {
-		return nil, err
-	}
-	return srvs.Endpoints, nil
-}
diff --git a/vendor/github.com/coreos/etcd/client/doc.go b/vendor/github.com/coreos/etcd/client/doc.go
deleted file mode 100644
index ad4eca4..0000000
--- a/vendor/github.com/coreos/etcd/client/doc.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/*
-Package client provides bindings for the etcd APIs.
-
-Create a Config and exchange it for a Client:
-
-	import (
-		"net/http"
-		"context"
-
-		"github.com/coreos/etcd/client"
-	)
-
-	cfg := client.Config{
-		Endpoints: []string{"http://127.0.0.1:2379"},
-		Transport: DefaultTransport,
-	}
-
-	c, err := client.New(cfg)
-	if err != nil {
-		// handle error
-	}
-
-Clients are safe for concurrent use by multiple goroutines.
-
-Create a KeysAPI using the Client, then use it to interact with etcd:
-
-	kAPI := client.NewKeysAPI(c)
-
-	// create a new key /foo with the value "bar"
-	_, err = kAPI.Create(context.Background(), "/foo", "bar")
-	if err != nil {
-		// handle error
-	}
-
-	// delete the newly created key only if the value is still "bar"
-	_, err = kAPI.Delete(context.Background(), "/foo", &DeleteOptions{PrevValue: "bar"})
-	if err != nil {
-		// handle error
-	}
-
-Use a custom context to set timeouts on your operations:
-
-	import "time"
-
-	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
-	defer cancel()
-
-	// set a new key, ignoring its previous state
-	_, err := kAPI.Set(ctx, "/ping", "pong", nil)
-	if err != nil {
-		if err == context.DeadlineExceeded {
-			// request took longer than 5s
-		} else {
-			// handle error
-		}
-	}
-
-*/
-package client
diff --git a/vendor/github.com/coreos/etcd/client/keys.generated.go b/vendor/github.com/coreos/etcd/client/keys.generated.go
deleted file mode 100644
index 237fdbe..0000000
--- a/vendor/github.com/coreos/etcd/client/keys.generated.go
+++ /dev/null
@@ -1,5218 +0,0 @@
-// ************************************************************
-// DO NOT EDIT.
-// THIS FILE IS AUTO-GENERATED BY codecgen.
-// ************************************************************
-
-package client
-
-import (
-	"errors"
-	"fmt"
-	"reflect"
-	"runtime"
-	time "time"
-
-	codec1978 "github.com/ugorji/go/codec"
-)
-
-const (
-	// ----- content types ----
-	codecSelferC_UTF87612 = 1
-	codecSelferC_RAW7612  = 0
-	// ----- value types used ----
-	codecSelferValueTypeArray7612 = 10
-	codecSelferValueTypeMap7612   = 9
-	// ----- containerStateValues ----
-	codecSelfer_containerMapKey7612    = 2
-	codecSelfer_containerMapValue7612  = 3
-	codecSelfer_containerMapEnd7612    = 4
-	codecSelfer_containerArrayElem7612 = 6
-	codecSelfer_containerArrayEnd7612  = 7
-)
-
-var (
-	codecSelferBitsize7612                         = uint8(reflect.TypeOf(uint(0)).Bits())
-	codecSelferOnlyMapOrArrayEncodeToStructErr7612 = errors.New(`only encoded map or array can be decoded into a struct`)
-)
-
-type codecSelfer7612 struct{}
-
-func init() {
-	if codec1978.GenVersion != 8 {
-		_, file, _, _ := runtime.Caller(0)
-		err := fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v",
-			8, codec1978.GenVersion, file)
-		panic(err)
-	}
-	if false { // reference the types, but skip this branch at build/run time
-		var v0 time.Duration
-		_ = v0
-	}
-}
-
-func (x *Error) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(4)
-			} else {
-				r.WriteMapStart(4)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeInt(int64(x.Code))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("errorCode"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeInt(int64(x.Code))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym7 := z.EncBinary()
-				_ = yym7
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Message))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("message"))
-				r.WriteMapElemValue()
-				yym8 := z.EncBinary()
-				_ = yym8
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Message))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym10 := z.EncBinary()
-				_ = yym10
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Cause))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("cause"))
-				r.WriteMapElemValue()
-				yym11 := z.EncBinary()
-				_ = yym11
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Cause))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym13 := z.EncBinary()
-				_ = yym13
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.Index))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("index"))
-				r.WriteMapElemValue()
-				yym14 := z.EncBinary()
-				_ = yym14
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.Index))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *Error) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *Error) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "errorCode":
-			if r.TryDecodeAsNil() {
-				x.Code = 0
-			} else {
-				yyv4 := &x.Code
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*int)(yyv4)) = int(r.DecodeInt(codecSelferBitsize7612))
-				}
-			}
-		case "message":
-			if r.TryDecodeAsNil() {
-				x.Message = ""
-			} else {
-				yyv6 := &x.Message
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*string)(yyv6)) = r.DecodeString()
-				}
-			}
-		case "cause":
-			if r.TryDecodeAsNil() {
-				x.Cause = ""
-			} else {
-				yyv8 := &x.Cause
-				yym9 := z.DecBinary()
-				_ = yym9
-				if false {
-				} else {
-					*((*string)(yyv8)) = r.DecodeString()
-				}
-			}
-		case "index":
-			if r.TryDecodeAsNil() {
-				x.Index = 0
-			} else {
-				yyv10 := &x.Index
-				yym11 := z.DecBinary()
-				_ = yym11
-				if false {
-				} else {
-					*((*uint64)(yyv10)) = uint64(r.DecodeUint(64))
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *Error) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj12 int
-	var yyb12 bool
-	var yyhl12 bool = l >= 0
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Code = 0
-	} else {
-		yyv13 := &x.Code
-		yym14 := z.DecBinary()
-		_ = yym14
-		if false {
-		} else {
-			*((*int)(yyv13)) = int(r.DecodeInt(codecSelferBitsize7612))
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Message = ""
-	} else {
-		yyv15 := &x.Message
-		yym16 := z.DecBinary()
-		_ = yym16
-		if false {
-		} else {
-			*((*string)(yyv15)) = r.DecodeString()
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Cause = ""
-	} else {
-		yyv17 := &x.Cause
-		yym18 := z.DecBinary()
-		_ = yym18
-		if false {
-		} else {
-			*((*string)(yyv17)) = r.DecodeString()
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Index = 0
-	} else {
-		yyv19 := &x.Index
-		yym20 := z.DecBinary()
-		_ = yym20
-		if false {
-		} else {
-			*((*uint64)(yyv19)) = uint64(r.DecodeUint(64))
-		}
-	}
-	for {
-		yyj12++
-		if yyhl12 {
-			yyb12 = yyj12 > l
-		} else {
-			yyb12 = r.CheckBreak()
-		}
-		if yyb12 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj12-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x PrevExistType) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	yym1 := z.EncBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.EncExt(x) {
-	} else {
-		r.EncodeString(codecSelferC_UTF87612, string(x))
-	}
-}
-
-func (x *PrevExistType) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		*((*string)(x)) = r.DecodeString()
-	}
-}
-
-func (x *WatcherOptions) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(2)
-			} else {
-				r.WriteMapStart(2)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.AfterIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("AfterIndex"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.AfterIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym7 := z.EncBinary()
-				_ = yym7
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Recursive"))
-				r.WriteMapElemValue()
-				yym8 := z.EncBinary()
-				_ = yym8
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *WatcherOptions) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *WatcherOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "AfterIndex":
-			if r.TryDecodeAsNil() {
-				x.AfterIndex = 0
-			} else {
-				yyv4 := &x.AfterIndex
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*uint64)(yyv4)) = uint64(r.DecodeUint(64))
-				}
-			}
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				yyv6 := &x.Recursive
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*bool)(yyv6)) = r.DecodeBool()
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *WatcherOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj8 int
-	var yyb8 bool
-	var yyhl8 bool = l >= 0
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.AfterIndex = 0
-	} else {
-		yyv9 := &x.AfterIndex
-		yym10 := z.DecBinary()
-		_ = yym10
-		if false {
-		} else {
-			*((*uint64)(yyv9)) = uint64(r.DecodeUint(64))
-		}
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		yyv11 := &x.Recursive
-		yym12 := z.DecBinary()
-		_ = yym12
-		if false {
-		} else {
-			*((*bool)(yyv11)) = r.DecodeBool()
-		}
-	}
-	for {
-		yyj8++
-		if yyhl8 {
-			yyb8 = yyj8 > l
-		} else {
-			yyb8 = r.CheckBreak()
-		}
-		if yyb8 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj8-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *CreateInOrderOptions) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(1)
-			} else {
-				r.WriteMapStart(1)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else if z.HasExtensions() && z.EncExt(x.TTL) {
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("TTL"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else if z.HasExtensions() && z.EncExt(x.TTL) {
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *CreateInOrderOptions) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *CreateInOrderOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "TTL":
-			if r.TryDecodeAsNil() {
-				x.TTL = 0
-			} else {
-				yyv4 := &x.TTL
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else if z.HasExtensions() && z.DecExt(yyv4) {
-				} else {
-					*((*int64)(yyv4)) = int64(r.DecodeInt(64))
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *CreateInOrderOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj6 int
-	var yyb6 bool
-	var yyhl6 bool = l >= 0
-	yyj6++
-	if yyhl6 {
-		yyb6 = yyj6 > l
-	} else {
-		yyb6 = r.CheckBreak()
-	}
-	if yyb6 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.TTL = 0
-	} else {
-		yyv7 := &x.TTL
-		yym8 := z.DecBinary()
-		_ = yym8
-		if false {
-		} else if z.HasExtensions() && z.DecExt(yyv7) {
-		} else {
-			*((*int64)(yyv7)) = int64(r.DecodeInt(64))
-		}
-	}
-	for {
-		yyj6++
-		if yyhl6 {
-			yyb6 = yyj6 > l
-		} else {
-			yyb6 = r.CheckBreak()
-		}
-		if yyb6 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj6-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *SetOptions) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(7)
-			} else {
-				r.WriteMapStart(7)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.PrevValue))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("PrevValue"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.PrevValue))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym7 := z.EncBinary()
-				_ = yym7
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("PrevIndex"))
-				r.WriteMapElemValue()
-				yym8 := z.EncBinary()
-				_ = yym8
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				x.PrevExist.CodecEncodeSelf(e)
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("PrevExist"))
-				r.WriteMapElemValue()
-				x.PrevExist.CodecEncodeSelf(e)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym13 := z.EncBinary()
-				_ = yym13
-				if false {
-				} else if z.HasExtensions() && z.EncExt(x.TTL) {
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("TTL"))
-				r.WriteMapElemValue()
-				yym14 := z.EncBinary()
-				_ = yym14
-				if false {
-				} else if z.HasExtensions() && z.EncExt(x.TTL) {
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym16 := z.EncBinary()
-				_ = yym16
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Refresh))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Refresh"))
-				r.WriteMapElemValue()
-				yym17 := z.EncBinary()
-				_ = yym17
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Refresh))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym19 := z.EncBinary()
-				_ = yym19
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Dir"))
-				r.WriteMapElemValue()
-				yym20 := z.EncBinary()
-				_ = yym20
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym22 := z.EncBinary()
-				_ = yym22
-				if false {
-				} else {
-					r.EncodeBool(bool(x.NoValueOnSuccess))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("NoValueOnSuccess"))
-				r.WriteMapElemValue()
-				yym23 := z.EncBinary()
-				_ = yym23
-				if false {
-				} else {
-					r.EncodeBool(bool(x.NoValueOnSuccess))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *SetOptions) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *SetOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "PrevValue":
-			if r.TryDecodeAsNil() {
-				x.PrevValue = ""
-			} else {
-				yyv4 := &x.PrevValue
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*string)(yyv4)) = r.DecodeString()
-				}
-			}
-		case "PrevIndex":
-			if r.TryDecodeAsNil() {
-				x.PrevIndex = 0
-			} else {
-				yyv6 := &x.PrevIndex
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*uint64)(yyv6)) = uint64(r.DecodeUint(64))
-				}
-			}
-		case "PrevExist":
-			if r.TryDecodeAsNil() {
-				x.PrevExist = ""
-			} else {
-				yyv8 := &x.PrevExist
-				yyv8.CodecDecodeSelf(d)
-			}
-		case "TTL":
-			if r.TryDecodeAsNil() {
-				x.TTL = 0
-			} else {
-				yyv9 := &x.TTL
-				yym10 := z.DecBinary()
-				_ = yym10
-				if false {
-				} else if z.HasExtensions() && z.DecExt(yyv9) {
-				} else {
-					*((*int64)(yyv9)) = int64(r.DecodeInt(64))
-				}
-			}
-		case "Refresh":
-			if r.TryDecodeAsNil() {
-				x.Refresh = false
-			} else {
-				yyv11 := &x.Refresh
-				yym12 := z.DecBinary()
-				_ = yym12
-				if false {
-				} else {
-					*((*bool)(yyv11)) = r.DecodeBool()
-				}
-			}
-		case "Dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = false
-			} else {
-				yyv13 := &x.Dir
-				yym14 := z.DecBinary()
-				_ = yym14
-				if false {
-				} else {
-					*((*bool)(yyv13)) = r.DecodeBool()
-				}
-			}
-		case "NoValueOnSuccess":
-			if r.TryDecodeAsNil() {
-				x.NoValueOnSuccess = false
-			} else {
-				yyv15 := &x.NoValueOnSuccess
-				yym16 := z.DecBinary()
-				_ = yym16
-				if false {
-				} else {
-					*((*bool)(yyv15)) = r.DecodeBool()
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *SetOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj17 int
-	var yyb17 bool
-	var yyhl17 bool = l >= 0
-	yyj17++
-	if yyhl17 {
-		yyb17 = yyj17 > l
-	} else {
-		yyb17 = r.CheckBreak()
-	}
-	if yyb17 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevValue = ""
-	} else {
-		yyv18 := &x.PrevValue
-		yym19 := z.DecBinary()
-		_ = yym19
-		if false {
-		} else {
-			*((*string)(yyv18)) = r.DecodeString()
-		}
-	}
-	yyj17++
-	if yyhl17 {
-		yyb17 = yyj17 > l
-	} else {
-		yyb17 = r.CheckBreak()
-	}
-	if yyb17 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevIndex = 0
-	} else {
-		yyv20 := &x.PrevIndex
-		yym21 := z.DecBinary()
-		_ = yym21
-		if false {
-		} else {
-			*((*uint64)(yyv20)) = uint64(r.DecodeUint(64))
-		}
-	}
-	yyj17++
-	if yyhl17 {
-		yyb17 = yyj17 > l
-	} else {
-		yyb17 = r.CheckBreak()
-	}
-	if yyb17 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevExist = ""
-	} else {
-		yyv22 := &x.PrevExist
-		yyv22.CodecDecodeSelf(d)
-	}
-	yyj17++
-	if yyhl17 {
-		yyb17 = yyj17 > l
-	} else {
-		yyb17 = r.CheckBreak()
-	}
-	if yyb17 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.TTL = 0
-	} else {
-		yyv23 := &x.TTL
-		yym24 := z.DecBinary()
-		_ = yym24
-		if false {
-		} else if z.HasExtensions() && z.DecExt(yyv23) {
-		} else {
-			*((*int64)(yyv23)) = int64(r.DecodeInt(64))
-		}
-	}
-	yyj17++
-	if yyhl17 {
-		yyb17 = yyj17 > l
-	} else {
-		yyb17 = r.CheckBreak()
-	}
-	if yyb17 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Refresh = false
-	} else {
-		yyv25 := &x.Refresh
-		yym26 := z.DecBinary()
-		_ = yym26
-		if false {
-		} else {
-			*((*bool)(yyv25)) = r.DecodeBool()
-		}
-	}
-	yyj17++
-	if yyhl17 {
-		yyb17 = yyj17 > l
-	} else {
-		yyb17 = r.CheckBreak()
-	}
-	if yyb17 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = false
-	} else {
-		yyv27 := &x.Dir
-		yym28 := z.DecBinary()
-		_ = yym28
-		if false {
-		} else {
-			*((*bool)(yyv27)) = r.DecodeBool()
-		}
-	}
-	yyj17++
-	if yyhl17 {
-		yyb17 = yyj17 > l
-	} else {
-		yyb17 = r.CheckBreak()
-	}
-	if yyb17 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.NoValueOnSuccess = false
-	} else {
-		yyv29 := &x.NoValueOnSuccess
-		yym30 := z.DecBinary()
-		_ = yym30
-		if false {
-		} else {
-			*((*bool)(yyv29)) = r.DecodeBool()
-		}
-	}
-	for {
-		yyj17++
-		if yyhl17 {
-			yyb17 = yyj17 > l
-		} else {
-			yyb17 = r.CheckBreak()
-		}
-		if yyb17 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj17-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *GetOptions) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(3)
-			} else {
-				r.WriteMapStart(3)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Recursive"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym7 := z.EncBinary()
-				_ = yym7
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Sort))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Sort"))
-				r.WriteMapElemValue()
-				yym8 := z.EncBinary()
-				_ = yym8
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Sort))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym10 := z.EncBinary()
-				_ = yym10
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Quorum))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Quorum"))
-				r.WriteMapElemValue()
-				yym11 := z.EncBinary()
-				_ = yym11
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Quorum))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *GetOptions) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *GetOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				yyv4 := &x.Recursive
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*bool)(yyv4)) = r.DecodeBool()
-				}
-			}
-		case "Sort":
-			if r.TryDecodeAsNil() {
-				x.Sort = false
-			} else {
-				yyv6 := &x.Sort
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*bool)(yyv6)) = r.DecodeBool()
-				}
-			}
-		case "Quorum":
-			if r.TryDecodeAsNil() {
-				x.Quorum = false
-			} else {
-				yyv8 := &x.Quorum
-				yym9 := z.DecBinary()
-				_ = yym9
-				if false {
-				} else {
-					*((*bool)(yyv8)) = r.DecodeBool()
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *GetOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj10 int
-	var yyb10 bool
-	var yyhl10 bool = l >= 0
-	yyj10++
-	if yyhl10 {
-		yyb10 = yyj10 > l
-	} else {
-		yyb10 = r.CheckBreak()
-	}
-	if yyb10 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		yyv11 := &x.Recursive
-		yym12 := z.DecBinary()
-		_ = yym12
-		if false {
-		} else {
-			*((*bool)(yyv11)) = r.DecodeBool()
-		}
-	}
-	yyj10++
-	if yyhl10 {
-		yyb10 = yyj10 > l
-	} else {
-		yyb10 = r.CheckBreak()
-	}
-	if yyb10 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Sort = false
-	} else {
-		yyv13 := &x.Sort
-		yym14 := z.DecBinary()
-		_ = yym14
-		if false {
-		} else {
-			*((*bool)(yyv13)) = r.DecodeBool()
-		}
-	}
-	yyj10++
-	if yyhl10 {
-		yyb10 = yyj10 > l
-	} else {
-		yyb10 = r.CheckBreak()
-	}
-	if yyb10 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Quorum = false
-	} else {
-		yyv15 := &x.Quorum
-		yym16 := z.DecBinary()
-		_ = yym16
-		if false {
-		} else {
-			*((*bool)(yyv15)) = r.DecodeBool()
-		}
-	}
-	for {
-		yyj10++
-		if yyhl10 {
-			yyb10 = yyj10 > l
-		} else {
-			yyb10 = r.CheckBreak()
-		}
-		if yyb10 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj10-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *DeleteOptions) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(4)
-			} else {
-				r.WriteMapStart(4)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.PrevValue))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("PrevValue"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.PrevValue))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym7 := z.EncBinary()
-				_ = yym7
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("PrevIndex"))
-				r.WriteMapElemValue()
-				yym8 := z.EncBinary()
-				_ = yym8
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym10 := z.EncBinary()
-				_ = yym10
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Recursive"))
-				r.WriteMapElemValue()
-				yym11 := z.EncBinary()
-				_ = yym11
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym13 := z.EncBinary()
-				_ = yym13
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Dir"))
-				r.WriteMapElemValue()
-				yym14 := z.EncBinary()
-				_ = yym14
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *DeleteOptions) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *DeleteOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "PrevValue":
-			if r.TryDecodeAsNil() {
-				x.PrevValue = ""
-			} else {
-				yyv4 := &x.PrevValue
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*string)(yyv4)) = r.DecodeString()
-				}
-			}
-		case "PrevIndex":
-			if r.TryDecodeAsNil() {
-				x.PrevIndex = 0
-			} else {
-				yyv6 := &x.PrevIndex
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*uint64)(yyv6)) = uint64(r.DecodeUint(64))
-				}
-			}
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				yyv8 := &x.Recursive
-				yym9 := z.DecBinary()
-				_ = yym9
-				if false {
-				} else {
-					*((*bool)(yyv8)) = r.DecodeBool()
-				}
-			}
-		case "Dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = false
-			} else {
-				yyv10 := &x.Dir
-				yym11 := z.DecBinary()
-				_ = yym11
-				if false {
-				} else {
-					*((*bool)(yyv10)) = r.DecodeBool()
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *DeleteOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj12 int
-	var yyb12 bool
-	var yyhl12 bool = l >= 0
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevValue = ""
-	} else {
-		yyv13 := &x.PrevValue
-		yym14 := z.DecBinary()
-		_ = yym14
-		if false {
-		} else {
-			*((*string)(yyv13)) = r.DecodeString()
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevIndex = 0
-	} else {
-		yyv15 := &x.PrevIndex
-		yym16 := z.DecBinary()
-		_ = yym16
-		if false {
-		} else {
-			*((*uint64)(yyv15)) = uint64(r.DecodeUint(64))
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		yyv17 := &x.Recursive
-		yym18 := z.DecBinary()
-		_ = yym18
-		if false {
-		} else {
-			*((*bool)(yyv17)) = r.DecodeBool()
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = false
-	} else {
-		yyv19 := &x.Dir
-		yym20 := z.DecBinary()
-		_ = yym20
-		if false {
-		} else {
-			*((*bool)(yyv19)) = r.DecodeBool()
-		}
-	}
-	for {
-		yyj12++
-		if yyhl12 {
-			yyb12 = yyj12 > l
-		} else {
-			yyb12 = r.CheckBreak()
-		}
-		if yyb12 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj12-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *Response) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(3)
-			} else {
-				r.WriteMapStart(3)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Action))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("action"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Action))
-				}
-			}
-			var yyn6 bool
-			if x.Node == nil {
-				yyn6 = true
-				goto LABEL6
-			}
-		LABEL6:
-			if yyr2 || yy2arr2 {
-				if yyn6 {
-					r.WriteArrayElem()
-					r.EncodeNil()
-				} else {
-					r.WriteArrayElem()
-					if x.Node == nil {
-						r.EncodeNil()
-					} else {
-						x.Node.CodecEncodeSelf(e)
-					}
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("node"))
-				r.WriteMapElemValue()
-				if yyn6 {
-					r.EncodeNil()
-				} else {
-					if x.Node == nil {
-						r.EncodeNil()
-					} else {
-						x.Node.CodecEncodeSelf(e)
-					}
-				}
-			}
-			var yyn9 bool
-			if x.PrevNode == nil {
-				yyn9 = true
-				goto LABEL9
-			}
-		LABEL9:
-			if yyr2 || yy2arr2 {
-				if yyn9 {
-					r.WriteArrayElem()
-					r.EncodeNil()
-				} else {
-					r.WriteArrayElem()
-					if x.PrevNode == nil {
-						r.EncodeNil()
-					} else {
-						x.PrevNode.CodecEncodeSelf(e)
-					}
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("prevNode"))
-				r.WriteMapElemValue()
-				if yyn9 {
-					r.EncodeNil()
-				} else {
-					if x.PrevNode == nil {
-						r.EncodeNil()
-					} else {
-						x.PrevNode.CodecEncodeSelf(e)
-					}
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *Response) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "action":
-			if r.TryDecodeAsNil() {
-				x.Action = ""
-			} else {
-				yyv4 := &x.Action
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*string)(yyv4)) = r.DecodeString()
-				}
-			}
-		case "node":
-			if x.Node == nil {
-				x.Node = new(Node)
-			}
-			if r.TryDecodeAsNil() {
-				if x.Node != nil {
-					x.Node = nil
-				}
-			} else {
-				if x.Node == nil {
-					x.Node = new(Node)
-				}
-				x.Node.CodecDecodeSelf(d)
-			}
-		case "prevNode":
-			if x.PrevNode == nil {
-				x.PrevNode = new(Node)
-			}
-			if r.TryDecodeAsNil() {
-				if x.PrevNode != nil {
-					x.PrevNode = nil
-				}
-			} else {
-				if x.PrevNode == nil {
-					x.PrevNode = new(Node)
-				}
-				x.PrevNode.CodecDecodeSelf(d)
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj8 int
-	var yyb8 bool
-	var yyhl8 bool = l >= 0
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Action = ""
-	} else {
-		yyv9 := &x.Action
-		yym10 := z.DecBinary()
-		_ = yym10
-		if false {
-		} else {
-			*((*string)(yyv9)) = r.DecodeString()
-		}
-	}
-	if x.Node == nil {
-		x.Node = new(Node)
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		if x.Node != nil {
-			x.Node = nil
-		}
-	} else {
-		if x.Node == nil {
-			x.Node = new(Node)
-		}
-		x.Node.CodecDecodeSelf(d)
-	}
-	if x.PrevNode == nil {
-		x.PrevNode = new(Node)
-	}
-	yyj8++
-	if yyhl8 {
-		yyb8 = yyj8 > l
-	} else {
-		yyb8 = r.CheckBreak()
-	}
-	if yyb8 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		if x.PrevNode != nil {
-			x.PrevNode = nil
-		}
-	} else {
-		if x.PrevNode == nil {
-			x.PrevNode = new(Node)
-		}
-		x.PrevNode.CodecDecodeSelf(d)
-	}
-	for {
-		yyj8++
-		if yyhl8 {
-			yyb8 = yyj8 > l
-		} else {
-			yyb8 = r.CheckBreak()
-		}
-		if yyb8 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj8-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			var yyq2 [8]bool
-			_ = yyq2
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			yyq2[1] = x.Dir != false
-			yyq2[6] = x.Expiration != nil
-			yyq2[7] = x.TTL != 0
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(8)
-			} else {
-				var yynn2 = 5
-				for _, b := range yyq2 {
-					if b {
-						yynn2++
-					}
-				}
-				r.WriteMapStart(yynn2)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Key))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("key"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Key))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if yyq2[1] {
-					yym7 := z.EncBinary()
-					_ = yym7
-					if false {
-					} else {
-						r.EncodeBool(bool(x.Dir))
-					}
-				} else {
-					r.EncodeBool(false)
-				}
-			} else {
-				if yyq2[1] {
-					r.WriteMapElemKey()
-					r.EncodeString(codecSelferC_UTF87612, string("dir"))
-					r.WriteMapElemValue()
-					yym8 := z.EncBinary()
-					_ = yym8
-					if false {
-					} else {
-						r.EncodeBool(bool(x.Dir))
-					}
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym10 := z.EncBinary()
-				_ = yym10
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Value))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("value"))
-				r.WriteMapElemValue()
-				yym11 := z.EncBinary()
-				_ = yym11
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Value))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if x.Nodes == nil {
-					r.EncodeNil()
-				} else {
-					x.Nodes.CodecEncodeSelf(e)
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("nodes"))
-				r.WriteMapElemValue()
-				if x.Nodes == nil {
-					r.EncodeNil()
-				} else {
-					x.Nodes.CodecEncodeSelf(e)
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym16 := z.EncBinary()
-				_ = yym16
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.CreatedIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("createdIndex"))
-				r.WriteMapElemValue()
-				yym17 := z.EncBinary()
-				_ = yym17
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.CreatedIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym19 := z.EncBinary()
-				_ = yym19
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.ModifiedIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("modifiedIndex"))
-				r.WriteMapElemValue()
-				yym20 := z.EncBinary()
-				_ = yym20
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.ModifiedIndex))
-				}
-			}
-			var yyn21 bool
-			if x.Expiration == nil {
-				yyn21 = true
-				goto LABEL21
-			}
-		LABEL21:
-			if yyr2 || yy2arr2 {
-				if yyn21 {
-					r.WriteArrayElem()
-					r.EncodeNil()
-				} else {
-					r.WriteArrayElem()
-					if yyq2[6] {
-						if x.Expiration == nil {
-							r.EncodeNil()
-						} else {
-							yym22 := z.EncBinary()
-							_ = yym22
-							if false {
-							} else if yym23 := z.TimeRtidIfBinc(); yym23 != 0 {
-								r.EncodeBuiltin(yym23, x.Expiration)
-							} else if z.HasExtensions() && z.EncExt(x.Expiration) {
-							} else if yym22 {
-								z.EncBinaryMarshal(x.Expiration)
-							} else if !yym22 && z.IsJSONHandle() {
-								z.EncJSONMarshal(x.Expiration)
-							} else {
-								z.EncFallback(x.Expiration)
-							}
-						}
-					} else {
-						r.EncodeNil()
-					}
-				}
-			} else {
-				if yyq2[6] {
-					r.WriteMapElemKey()
-					r.EncodeString(codecSelferC_UTF87612, string("expiration"))
-					r.WriteMapElemValue()
-					if yyn21 {
-						r.EncodeNil()
-					} else {
-						if x.Expiration == nil {
-							r.EncodeNil()
-						} else {
-							yym24 := z.EncBinary()
-							_ = yym24
-							if false {
-							} else if yym25 := z.TimeRtidIfBinc(); yym25 != 0 {
-								r.EncodeBuiltin(yym25, x.Expiration)
-							} else if z.HasExtensions() && z.EncExt(x.Expiration) {
-							} else if yym24 {
-								z.EncBinaryMarshal(x.Expiration)
-							} else if !yym24 && z.IsJSONHandle() {
-								z.EncJSONMarshal(x.Expiration)
-							} else {
-								z.EncFallback(x.Expiration)
-							}
-						}
-					}
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				if yyq2[7] {
-					yym27 := z.EncBinary()
-					_ = yym27
-					if false {
-					} else {
-						r.EncodeInt(int64(x.TTL))
-					}
-				} else {
-					r.EncodeInt(0)
-				}
-			} else {
-				if yyq2[7] {
-					r.WriteMapElemKey()
-					r.EncodeString(codecSelferC_UTF87612, string("ttl"))
-					r.WriteMapElemValue()
-					yym28 := z.EncBinary()
-					_ = yym28
-					if false {
-					} else {
-						r.EncodeInt(int64(x.TTL))
-					}
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *Node) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "key":
-			if r.TryDecodeAsNil() {
-				x.Key = ""
-			} else {
-				yyv4 := &x.Key
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*string)(yyv4)) = r.DecodeString()
-				}
-			}
-		case "dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = false
-			} else {
-				yyv6 := &x.Dir
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*bool)(yyv6)) = r.DecodeBool()
-				}
-			}
-		case "value":
-			if r.TryDecodeAsNil() {
-				x.Value = ""
-			} else {
-				yyv8 := &x.Value
-				yym9 := z.DecBinary()
-				_ = yym9
-				if false {
-				} else {
-					*((*string)(yyv8)) = r.DecodeString()
-				}
-			}
-		case "nodes":
-			if r.TryDecodeAsNil() {
-				x.Nodes = nil
-			} else {
-				yyv10 := &x.Nodes
-				yyv10.CodecDecodeSelf(d)
-			}
-		case "createdIndex":
-			if r.TryDecodeAsNil() {
-				x.CreatedIndex = 0
-			} else {
-				yyv11 := &x.CreatedIndex
-				yym12 := z.DecBinary()
-				_ = yym12
-				if false {
-				} else {
-					*((*uint64)(yyv11)) = uint64(r.DecodeUint(64))
-				}
-			}
-		case "modifiedIndex":
-			if r.TryDecodeAsNil() {
-				x.ModifiedIndex = 0
-			} else {
-				yyv13 := &x.ModifiedIndex
-				yym14 := z.DecBinary()
-				_ = yym14
-				if false {
-				} else {
-					*((*uint64)(yyv13)) = uint64(r.DecodeUint(64))
-				}
-			}
-		case "expiration":
-			if x.Expiration == nil {
-				x.Expiration = new(time.Time)
-			}
-			if r.TryDecodeAsNil() {
-				if x.Expiration != nil {
-					x.Expiration = nil
-				}
-			} else {
-				if x.Expiration == nil {
-					x.Expiration = new(time.Time)
-				}
-				yym16 := z.DecBinary()
-				_ = yym16
-				if false {
-				} else if yym17 := z.TimeRtidIfBinc(); yym17 != 0 {
-					r.DecodeBuiltin(yym17, x.Expiration)
-				} else if z.HasExtensions() && z.DecExt(x.Expiration) {
-				} else if yym16 {
-					z.DecBinaryUnmarshal(x.Expiration)
-				} else if !yym16 && z.IsJSONHandle() {
-					z.DecJSONUnmarshal(x.Expiration)
-				} else {
-					z.DecFallback(x.Expiration, false)
-				}
-			}
-		case "ttl":
-			if r.TryDecodeAsNil() {
-				x.TTL = 0
-			} else {
-				yyv18 := &x.TTL
-				yym19 := z.DecBinary()
-				_ = yym19
-				if false {
-				} else {
-					*((*int64)(yyv18)) = int64(r.DecodeInt(64))
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj20 int
-	var yyb20 bool
-	var yyhl20 bool = l >= 0
-	yyj20++
-	if yyhl20 {
-		yyb20 = yyj20 > l
-	} else {
-		yyb20 = r.CheckBreak()
-	}
-	if yyb20 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Key = ""
-	} else {
-		yyv21 := &x.Key
-		yym22 := z.DecBinary()
-		_ = yym22
-		if false {
-		} else {
-			*((*string)(yyv21)) = r.DecodeString()
-		}
-	}
-	yyj20++
-	if yyhl20 {
-		yyb20 = yyj20 > l
-	} else {
-		yyb20 = r.CheckBreak()
-	}
-	if yyb20 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = false
-	} else {
-		yyv23 := &x.Dir
-		yym24 := z.DecBinary()
-		_ = yym24
-		if false {
-		} else {
-			*((*bool)(yyv23)) = r.DecodeBool()
-		}
-	}
-	yyj20++
-	if yyhl20 {
-		yyb20 = yyj20 > l
-	} else {
-		yyb20 = r.CheckBreak()
-	}
-	if yyb20 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Value = ""
-	} else {
-		yyv25 := &x.Value
-		yym26 := z.DecBinary()
-		_ = yym26
-		if false {
-		} else {
-			*((*string)(yyv25)) = r.DecodeString()
-		}
-	}
-	yyj20++
-	if yyhl20 {
-		yyb20 = yyj20 > l
-	} else {
-		yyb20 = r.CheckBreak()
-	}
-	if yyb20 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Nodes = nil
-	} else {
-		yyv27 := &x.Nodes
-		yyv27.CodecDecodeSelf(d)
-	}
-	yyj20++
-	if yyhl20 {
-		yyb20 = yyj20 > l
-	} else {
-		yyb20 = r.CheckBreak()
-	}
-	if yyb20 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.CreatedIndex = 0
-	} else {
-		yyv28 := &x.CreatedIndex
-		yym29 := z.DecBinary()
-		_ = yym29
-		if false {
-		} else {
-			*((*uint64)(yyv28)) = uint64(r.DecodeUint(64))
-		}
-	}
-	yyj20++
-	if yyhl20 {
-		yyb20 = yyj20 > l
-	} else {
-		yyb20 = r.CheckBreak()
-	}
-	if yyb20 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.ModifiedIndex = 0
-	} else {
-		yyv30 := &x.ModifiedIndex
-		yym31 := z.DecBinary()
-		_ = yym31
-		if false {
-		} else {
-			*((*uint64)(yyv30)) = uint64(r.DecodeUint(64))
-		}
-	}
-	if x.Expiration == nil {
-		x.Expiration = new(time.Time)
-	}
-	yyj20++
-	if yyhl20 {
-		yyb20 = yyj20 > l
-	} else {
-		yyb20 = r.CheckBreak()
-	}
-	if yyb20 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		if x.Expiration != nil {
-			x.Expiration = nil
-		}
-	} else {
-		if x.Expiration == nil {
-			x.Expiration = new(time.Time)
-		}
-		yym33 := z.DecBinary()
-		_ = yym33
-		if false {
-		} else if yym34 := z.TimeRtidIfBinc(); yym34 != 0 {
-			r.DecodeBuiltin(yym34, x.Expiration)
-		} else if z.HasExtensions() && z.DecExt(x.Expiration) {
-		} else if yym33 {
-			z.DecBinaryUnmarshal(x.Expiration)
-		} else if !yym33 && z.IsJSONHandle() {
-			z.DecJSONUnmarshal(x.Expiration)
-		} else {
-			z.DecFallback(x.Expiration, false)
-		}
-	}
-	yyj20++
-	if yyhl20 {
-		yyb20 = yyj20 > l
-	} else {
-		yyb20 = r.CheckBreak()
-	}
-	if yyb20 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.TTL = 0
-	} else {
-		yyv35 := &x.TTL
-		yym36 := z.DecBinary()
-		_ = yym36
-		if false {
-		} else {
-			*((*int64)(yyv35)) = int64(r.DecodeInt(64))
-		}
-	}
-	for {
-		yyj20++
-		if yyhl20 {
-			yyb20 = yyj20 > l
-		} else {
-			yyb20 = r.CheckBreak()
-		}
-		if yyb20 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj20-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x Nodes) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			h.encNodes((Nodes)(x), e)
-		}
-	}
-}
-
-func (x *Nodes) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		h.decNodes((*Nodes)(x), d)
-	}
-}
-
-func (x *httpKeysAPI) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(0)
-			} else {
-				r.WriteMapStart(0)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *httpKeysAPI) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *httpKeysAPI) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *httpKeysAPI) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj4 int
-	var yyb4 bool
-	var yyhl4 bool = l >= 0
-	for {
-		yyj4++
-		if yyhl4 {
-			yyb4 = yyj4 > l
-		} else {
-			yyb4 = r.CheckBreak()
-		}
-		if yyb4 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj4-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *httpWatcher) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(0)
-			} else {
-				r.WriteMapStart(0)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *httpWatcher) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *httpWatcher) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *httpWatcher) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj4 int
-	var yyb4 bool
-	var yyhl4 bool = l >= 0
-	for {
-		yyj4++
-		if yyhl4 {
-			yyb4 = yyj4 > l
-		} else {
-			yyb4 = r.CheckBreak()
-		}
-		if yyb4 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj4-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *getAction) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(5)
-			} else {
-				r.WriteMapStart(5)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Prefix))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Prefix"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Prefix))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym7 := z.EncBinary()
-				_ = yym7
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Key))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Key"))
-				r.WriteMapElemValue()
-				yym8 := z.EncBinary()
-				_ = yym8
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Key))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym10 := z.EncBinary()
-				_ = yym10
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Recursive"))
-				r.WriteMapElemValue()
-				yym11 := z.EncBinary()
-				_ = yym11
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym13 := z.EncBinary()
-				_ = yym13
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Sorted))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Sorted"))
-				r.WriteMapElemValue()
-				yym14 := z.EncBinary()
-				_ = yym14
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Sorted))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym16 := z.EncBinary()
-				_ = yym16
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Quorum))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Quorum"))
-				r.WriteMapElemValue()
-				yym17 := z.EncBinary()
-				_ = yym17
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Quorum))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *getAction) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *getAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Prefix":
-			if r.TryDecodeAsNil() {
-				x.Prefix = ""
-			} else {
-				yyv4 := &x.Prefix
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*string)(yyv4)) = r.DecodeString()
-				}
-			}
-		case "Key":
-			if r.TryDecodeAsNil() {
-				x.Key = ""
-			} else {
-				yyv6 := &x.Key
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*string)(yyv6)) = r.DecodeString()
-				}
-			}
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				yyv8 := &x.Recursive
-				yym9 := z.DecBinary()
-				_ = yym9
-				if false {
-				} else {
-					*((*bool)(yyv8)) = r.DecodeBool()
-				}
-			}
-		case "Sorted":
-			if r.TryDecodeAsNil() {
-				x.Sorted = false
-			} else {
-				yyv10 := &x.Sorted
-				yym11 := z.DecBinary()
-				_ = yym11
-				if false {
-				} else {
-					*((*bool)(yyv10)) = r.DecodeBool()
-				}
-			}
-		case "Quorum":
-			if r.TryDecodeAsNil() {
-				x.Quorum = false
-			} else {
-				yyv12 := &x.Quorum
-				yym13 := z.DecBinary()
-				_ = yym13
-				if false {
-				} else {
-					*((*bool)(yyv12)) = r.DecodeBool()
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *getAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj14 int
-	var yyb14 bool
-	var yyhl14 bool = l >= 0
-	yyj14++
-	if yyhl14 {
-		yyb14 = yyj14 > l
-	} else {
-		yyb14 = r.CheckBreak()
-	}
-	if yyb14 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Prefix = ""
-	} else {
-		yyv15 := &x.Prefix
-		yym16 := z.DecBinary()
-		_ = yym16
-		if false {
-		} else {
-			*((*string)(yyv15)) = r.DecodeString()
-		}
-	}
-	yyj14++
-	if yyhl14 {
-		yyb14 = yyj14 > l
-	} else {
-		yyb14 = r.CheckBreak()
-	}
-	if yyb14 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Key = ""
-	} else {
-		yyv17 := &x.Key
-		yym18 := z.DecBinary()
-		_ = yym18
-		if false {
-		} else {
-			*((*string)(yyv17)) = r.DecodeString()
-		}
-	}
-	yyj14++
-	if yyhl14 {
-		yyb14 = yyj14 > l
-	} else {
-		yyb14 = r.CheckBreak()
-	}
-	if yyb14 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		yyv19 := &x.Recursive
-		yym20 := z.DecBinary()
-		_ = yym20
-		if false {
-		} else {
-			*((*bool)(yyv19)) = r.DecodeBool()
-		}
-	}
-	yyj14++
-	if yyhl14 {
-		yyb14 = yyj14 > l
-	} else {
-		yyb14 = r.CheckBreak()
-	}
-	if yyb14 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Sorted = false
-	} else {
-		yyv21 := &x.Sorted
-		yym22 := z.DecBinary()
-		_ = yym22
-		if false {
-		} else {
-			*((*bool)(yyv21)) = r.DecodeBool()
-		}
-	}
-	yyj14++
-	if yyhl14 {
-		yyb14 = yyj14 > l
-	} else {
-		yyb14 = r.CheckBreak()
-	}
-	if yyb14 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Quorum = false
-	} else {
-		yyv23 := &x.Quorum
-		yym24 := z.DecBinary()
-		_ = yym24
-		if false {
-		} else {
-			*((*bool)(yyv23)) = r.DecodeBool()
-		}
-	}
-	for {
-		yyj14++
-		if yyhl14 {
-			yyb14 = yyj14 > l
-		} else {
-			yyb14 = r.CheckBreak()
-		}
-		if yyb14 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj14-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *waitAction) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(4)
-			} else {
-				r.WriteMapStart(4)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Prefix))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Prefix"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Prefix))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym7 := z.EncBinary()
-				_ = yym7
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Key))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Key"))
-				r.WriteMapElemValue()
-				yym8 := z.EncBinary()
-				_ = yym8
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Key))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym10 := z.EncBinary()
-				_ = yym10
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.WaitIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("WaitIndex"))
-				r.WriteMapElemValue()
-				yym11 := z.EncBinary()
-				_ = yym11
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.WaitIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym13 := z.EncBinary()
-				_ = yym13
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Recursive"))
-				r.WriteMapElemValue()
-				yym14 := z.EncBinary()
-				_ = yym14
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *waitAction) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *waitAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Prefix":
-			if r.TryDecodeAsNil() {
-				x.Prefix = ""
-			} else {
-				yyv4 := &x.Prefix
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*string)(yyv4)) = r.DecodeString()
-				}
-			}
-		case "Key":
-			if r.TryDecodeAsNil() {
-				x.Key = ""
-			} else {
-				yyv6 := &x.Key
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*string)(yyv6)) = r.DecodeString()
-				}
-			}
-		case "WaitIndex":
-			if r.TryDecodeAsNil() {
-				x.WaitIndex = 0
-			} else {
-				yyv8 := &x.WaitIndex
-				yym9 := z.DecBinary()
-				_ = yym9
-				if false {
-				} else {
-					*((*uint64)(yyv8)) = uint64(r.DecodeUint(64))
-				}
-			}
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				yyv10 := &x.Recursive
-				yym11 := z.DecBinary()
-				_ = yym11
-				if false {
-				} else {
-					*((*bool)(yyv10)) = r.DecodeBool()
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *waitAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj12 int
-	var yyb12 bool
-	var yyhl12 bool = l >= 0
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Prefix = ""
-	} else {
-		yyv13 := &x.Prefix
-		yym14 := z.DecBinary()
-		_ = yym14
-		if false {
-		} else {
-			*((*string)(yyv13)) = r.DecodeString()
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Key = ""
-	} else {
-		yyv15 := &x.Key
-		yym16 := z.DecBinary()
-		_ = yym16
-		if false {
-		} else {
-			*((*string)(yyv15)) = r.DecodeString()
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.WaitIndex = 0
-	} else {
-		yyv17 := &x.WaitIndex
-		yym18 := z.DecBinary()
-		_ = yym18
-		if false {
-		} else {
-			*((*uint64)(yyv17)) = uint64(r.DecodeUint(64))
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		yyv19 := &x.Recursive
-		yym20 := z.DecBinary()
-		_ = yym20
-		if false {
-		} else {
-			*((*bool)(yyv19)) = r.DecodeBool()
-		}
-	}
-	for {
-		yyj12++
-		if yyhl12 {
-			yyb12 = yyj12 > l
-		} else {
-			yyb12 = r.CheckBreak()
-		}
-		if yyb12 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj12-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *setAction) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(10)
-			} else {
-				r.WriteMapStart(10)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Prefix))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Prefix"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Prefix))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym7 := z.EncBinary()
-				_ = yym7
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Key))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Key"))
-				r.WriteMapElemValue()
-				yym8 := z.EncBinary()
-				_ = yym8
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Key))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym10 := z.EncBinary()
-				_ = yym10
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Value))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Value"))
-				r.WriteMapElemValue()
-				yym11 := z.EncBinary()
-				_ = yym11
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Value))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym13 := z.EncBinary()
-				_ = yym13
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.PrevValue))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("PrevValue"))
-				r.WriteMapElemValue()
-				yym14 := z.EncBinary()
-				_ = yym14
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.PrevValue))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym16 := z.EncBinary()
-				_ = yym16
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("PrevIndex"))
-				r.WriteMapElemValue()
-				yym17 := z.EncBinary()
-				_ = yym17
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				x.PrevExist.CodecEncodeSelf(e)
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("PrevExist"))
-				r.WriteMapElemValue()
-				x.PrevExist.CodecEncodeSelf(e)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym22 := z.EncBinary()
-				_ = yym22
-				if false {
-				} else if z.HasExtensions() && z.EncExt(x.TTL) {
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("TTL"))
-				r.WriteMapElemValue()
-				yym23 := z.EncBinary()
-				_ = yym23
-				if false {
-				} else if z.HasExtensions() && z.EncExt(x.TTL) {
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym25 := z.EncBinary()
-				_ = yym25
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Refresh))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Refresh"))
-				r.WriteMapElemValue()
-				yym26 := z.EncBinary()
-				_ = yym26
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Refresh))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym28 := z.EncBinary()
-				_ = yym28
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Dir"))
-				r.WriteMapElemValue()
-				yym29 := z.EncBinary()
-				_ = yym29
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym31 := z.EncBinary()
-				_ = yym31
-				if false {
-				} else {
-					r.EncodeBool(bool(x.NoValueOnSuccess))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("NoValueOnSuccess"))
-				r.WriteMapElemValue()
-				yym32 := z.EncBinary()
-				_ = yym32
-				if false {
-				} else {
-					r.EncodeBool(bool(x.NoValueOnSuccess))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *setAction) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *setAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Prefix":
-			if r.TryDecodeAsNil() {
-				x.Prefix = ""
-			} else {
-				yyv4 := &x.Prefix
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*string)(yyv4)) = r.DecodeString()
-				}
-			}
-		case "Key":
-			if r.TryDecodeAsNil() {
-				x.Key = ""
-			} else {
-				yyv6 := &x.Key
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*string)(yyv6)) = r.DecodeString()
-				}
-			}
-		case "Value":
-			if r.TryDecodeAsNil() {
-				x.Value = ""
-			} else {
-				yyv8 := &x.Value
-				yym9 := z.DecBinary()
-				_ = yym9
-				if false {
-				} else {
-					*((*string)(yyv8)) = r.DecodeString()
-				}
-			}
-		case "PrevValue":
-			if r.TryDecodeAsNil() {
-				x.PrevValue = ""
-			} else {
-				yyv10 := &x.PrevValue
-				yym11 := z.DecBinary()
-				_ = yym11
-				if false {
-				} else {
-					*((*string)(yyv10)) = r.DecodeString()
-				}
-			}
-		case "PrevIndex":
-			if r.TryDecodeAsNil() {
-				x.PrevIndex = 0
-			} else {
-				yyv12 := &x.PrevIndex
-				yym13 := z.DecBinary()
-				_ = yym13
-				if false {
-				} else {
-					*((*uint64)(yyv12)) = uint64(r.DecodeUint(64))
-				}
-			}
-		case "PrevExist":
-			if r.TryDecodeAsNil() {
-				x.PrevExist = ""
-			} else {
-				yyv14 := &x.PrevExist
-				yyv14.CodecDecodeSelf(d)
-			}
-		case "TTL":
-			if r.TryDecodeAsNil() {
-				x.TTL = 0
-			} else {
-				yyv15 := &x.TTL
-				yym16 := z.DecBinary()
-				_ = yym16
-				if false {
-				} else if z.HasExtensions() && z.DecExt(yyv15) {
-				} else {
-					*((*int64)(yyv15)) = int64(r.DecodeInt(64))
-				}
-			}
-		case "Refresh":
-			if r.TryDecodeAsNil() {
-				x.Refresh = false
-			} else {
-				yyv17 := &x.Refresh
-				yym18 := z.DecBinary()
-				_ = yym18
-				if false {
-				} else {
-					*((*bool)(yyv17)) = r.DecodeBool()
-				}
-			}
-		case "Dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = false
-			} else {
-				yyv19 := &x.Dir
-				yym20 := z.DecBinary()
-				_ = yym20
-				if false {
-				} else {
-					*((*bool)(yyv19)) = r.DecodeBool()
-				}
-			}
-		case "NoValueOnSuccess":
-			if r.TryDecodeAsNil() {
-				x.NoValueOnSuccess = false
-			} else {
-				yyv21 := &x.NoValueOnSuccess
-				yym22 := z.DecBinary()
-				_ = yym22
-				if false {
-				} else {
-					*((*bool)(yyv21)) = r.DecodeBool()
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *setAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj23 int
-	var yyb23 bool
-	var yyhl23 bool = l >= 0
-	yyj23++
-	if yyhl23 {
-		yyb23 = yyj23 > l
-	} else {
-		yyb23 = r.CheckBreak()
-	}
-	if yyb23 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Prefix = ""
-	} else {
-		yyv24 := &x.Prefix
-		yym25 := z.DecBinary()
-		_ = yym25
-		if false {
-		} else {
-			*((*string)(yyv24)) = r.DecodeString()
-		}
-	}
-	yyj23++
-	if yyhl23 {
-		yyb23 = yyj23 > l
-	} else {
-		yyb23 = r.CheckBreak()
-	}
-	if yyb23 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Key = ""
-	} else {
-		yyv26 := &x.Key
-		yym27 := z.DecBinary()
-		_ = yym27
-		if false {
-		} else {
-			*((*string)(yyv26)) = r.DecodeString()
-		}
-	}
-	yyj23++
-	if yyhl23 {
-		yyb23 = yyj23 > l
-	} else {
-		yyb23 = r.CheckBreak()
-	}
-	if yyb23 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Value = ""
-	} else {
-		yyv28 := &x.Value
-		yym29 := z.DecBinary()
-		_ = yym29
-		if false {
-		} else {
-			*((*string)(yyv28)) = r.DecodeString()
-		}
-	}
-	yyj23++
-	if yyhl23 {
-		yyb23 = yyj23 > l
-	} else {
-		yyb23 = r.CheckBreak()
-	}
-	if yyb23 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevValue = ""
-	} else {
-		yyv30 := &x.PrevValue
-		yym31 := z.DecBinary()
-		_ = yym31
-		if false {
-		} else {
-			*((*string)(yyv30)) = r.DecodeString()
-		}
-	}
-	yyj23++
-	if yyhl23 {
-		yyb23 = yyj23 > l
-	} else {
-		yyb23 = r.CheckBreak()
-	}
-	if yyb23 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevIndex = 0
-	} else {
-		yyv32 := &x.PrevIndex
-		yym33 := z.DecBinary()
-		_ = yym33
-		if false {
-		} else {
-			*((*uint64)(yyv32)) = uint64(r.DecodeUint(64))
-		}
-	}
-	yyj23++
-	if yyhl23 {
-		yyb23 = yyj23 > l
-	} else {
-		yyb23 = r.CheckBreak()
-	}
-	if yyb23 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevExist = ""
-	} else {
-		yyv34 := &x.PrevExist
-		yyv34.CodecDecodeSelf(d)
-	}
-	yyj23++
-	if yyhl23 {
-		yyb23 = yyj23 > l
-	} else {
-		yyb23 = r.CheckBreak()
-	}
-	if yyb23 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.TTL = 0
-	} else {
-		yyv35 := &x.TTL
-		yym36 := z.DecBinary()
-		_ = yym36
-		if false {
-		} else if z.HasExtensions() && z.DecExt(yyv35) {
-		} else {
-			*((*int64)(yyv35)) = int64(r.DecodeInt(64))
-		}
-	}
-	yyj23++
-	if yyhl23 {
-		yyb23 = yyj23 > l
-	} else {
-		yyb23 = r.CheckBreak()
-	}
-	if yyb23 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Refresh = false
-	} else {
-		yyv37 := &x.Refresh
-		yym38 := z.DecBinary()
-		_ = yym38
-		if false {
-		} else {
-			*((*bool)(yyv37)) = r.DecodeBool()
-		}
-	}
-	yyj23++
-	if yyhl23 {
-		yyb23 = yyj23 > l
-	} else {
-		yyb23 = r.CheckBreak()
-	}
-	if yyb23 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = false
-	} else {
-		yyv39 := &x.Dir
-		yym40 := z.DecBinary()
-		_ = yym40
-		if false {
-		} else {
-			*((*bool)(yyv39)) = r.DecodeBool()
-		}
-	}
-	yyj23++
-	if yyhl23 {
-		yyb23 = yyj23 > l
-	} else {
-		yyb23 = r.CheckBreak()
-	}
-	if yyb23 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.NoValueOnSuccess = false
-	} else {
-		yyv41 := &x.NoValueOnSuccess
-		yym42 := z.DecBinary()
-		_ = yym42
-		if false {
-		} else {
-			*((*bool)(yyv41)) = r.DecodeBool()
-		}
-	}
-	for {
-		yyj23++
-		if yyhl23 {
-			yyb23 = yyj23 > l
-		} else {
-			yyb23 = r.CheckBreak()
-		}
-		if yyb23 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj23-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *deleteAction) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(6)
-			} else {
-				r.WriteMapStart(6)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Prefix))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Prefix"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Prefix))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym7 := z.EncBinary()
-				_ = yym7
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Key))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Key"))
-				r.WriteMapElemValue()
-				yym8 := z.EncBinary()
-				_ = yym8
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Key))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym10 := z.EncBinary()
-				_ = yym10
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.PrevValue))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("PrevValue"))
-				r.WriteMapElemValue()
-				yym11 := z.EncBinary()
-				_ = yym11
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.PrevValue))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym13 := z.EncBinary()
-				_ = yym13
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("PrevIndex"))
-				r.WriteMapElemValue()
-				yym14 := z.EncBinary()
-				_ = yym14
-				if false {
-				} else {
-					r.EncodeUint(uint64(x.PrevIndex))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym16 := z.EncBinary()
-				_ = yym16
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Dir"))
-				r.WriteMapElemValue()
-				yym17 := z.EncBinary()
-				_ = yym17
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Dir))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym19 := z.EncBinary()
-				_ = yym19
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Recursive"))
-				r.WriteMapElemValue()
-				yym20 := z.EncBinary()
-				_ = yym20
-				if false {
-				} else {
-					r.EncodeBool(bool(x.Recursive))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *deleteAction) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *deleteAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Prefix":
-			if r.TryDecodeAsNil() {
-				x.Prefix = ""
-			} else {
-				yyv4 := &x.Prefix
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*string)(yyv4)) = r.DecodeString()
-				}
-			}
-		case "Key":
-			if r.TryDecodeAsNil() {
-				x.Key = ""
-			} else {
-				yyv6 := &x.Key
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*string)(yyv6)) = r.DecodeString()
-				}
-			}
-		case "PrevValue":
-			if r.TryDecodeAsNil() {
-				x.PrevValue = ""
-			} else {
-				yyv8 := &x.PrevValue
-				yym9 := z.DecBinary()
-				_ = yym9
-				if false {
-				} else {
-					*((*string)(yyv8)) = r.DecodeString()
-				}
-			}
-		case "PrevIndex":
-			if r.TryDecodeAsNil() {
-				x.PrevIndex = 0
-			} else {
-				yyv10 := &x.PrevIndex
-				yym11 := z.DecBinary()
-				_ = yym11
-				if false {
-				} else {
-					*((*uint64)(yyv10)) = uint64(r.DecodeUint(64))
-				}
-			}
-		case "Dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = false
-			} else {
-				yyv12 := &x.Dir
-				yym13 := z.DecBinary()
-				_ = yym13
-				if false {
-				} else {
-					*((*bool)(yyv12)) = r.DecodeBool()
-				}
-			}
-		case "Recursive":
-			if r.TryDecodeAsNil() {
-				x.Recursive = false
-			} else {
-				yyv14 := &x.Recursive
-				yym15 := z.DecBinary()
-				_ = yym15
-				if false {
-				} else {
-					*((*bool)(yyv14)) = r.DecodeBool()
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *deleteAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj16 int
-	var yyb16 bool
-	var yyhl16 bool = l >= 0
-	yyj16++
-	if yyhl16 {
-		yyb16 = yyj16 > l
-	} else {
-		yyb16 = r.CheckBreak()
-	}
-	if yyb16 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Prefix = ""
-	} else {
-		yyv17 := &x.Prefix
-		yym18 := z.DecBinary()
-		_ = yym18
-		if false {
-		} else {
-			*((*string)(yyv17)) = r.DecodeString()
-		}
-	}
-	yyj16++
-	if yyhl16 {
-		yyb16 = yyj16 > l
-	} else {
-		yyb16 = r.CheckBreak()
-	}
-	if yyb16 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Key = ""
-	} else {
-		yyv19 := &x.Key
-		yym20 := z.DecBinary()
-		_ = yym20
-		if false {
-		} else {
-			*((*string)(yyv19)) = r.DecodeString()
-		}
-	}
-	yyj16++
-	if yyhl16 {
-		yyb16 = yyj16 > l
-	} else {
-		yyb16 = r.CheckBreak()
-	}
-	if yyb16 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevValue = ""
-	} else {
-		yyv21 := &x.PrevValue
-		yym22 := z.DecBinary()
-		_ = yym22
-		if false {
-		} else {
-			*((*string)(yyv21)) = r.DecodeString()
-		}
-	}
-	yyj16++
-	if yyhl16 {
-		yyb16 = yyj16 > l
-	} else {
-		yyb16 = r.CheckBreak()
-	}
-	if yyb16 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.PrevIndex = 0
-	} else {
-		yyv23 := &x.PrevIndex
-		yym24 := z.DecBinary()
-		_ = yym24
-		if false {
-		} else {
-			*((*uint64)(yyv23)) = uint64(r.DecodeUint(64))
-		}
-	}
-	yyj16++
-	if yyhl16 {
-		yyb16 = yyj16 > l
-	} else {
-		yyb16 = r.CheckBreak()
-	}
-	if yyb16 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = false
-	} else {
-		yyv25 := &x.Dir
-		yym26 := z.DecBinary()
-		_ = yym26
-		if false {
-		} else {
-			*((*bool)(yyv25)) = r.DecodeBool()
-		}
-	}
-	yyj16++
-	if yyhl16 {
-		yyb16 = yyj16 > l
-	} else {
-		yyb16 = r.CheckBreak()
-	}
-	if yyb16 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Recursive = false
-	} else {
-		yyv27 := &x.Recursive
-		yym28 := z.DecBinary()
-		_ = yym28
-		if false {
-		} else {
-			*((*bool)(yyv27)) = r.DecodeBool()
-		}
-	}
-	for {
-		yyj16++
-		if yyhl16 {
-			yyb16 = yyj16 > l
-		} else {
-			yyb16 = r.CheckBreak()
-		}
-		if yyb16 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj16-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x *createInOrderAction) CodecEncodeSelf(e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	if x == nil {
-		r.EncodeNil()
-	} else {
-		yym1 := z.EncBinary()
-		_ = yym1
-		if false {
-		} else if z.HasExtensions() && z.EncExt(x) {
-		} else {
-			yysep2 := !z.EncBinary()
-			yy2arr2 := z.EncBasicHandle().StructToArray
-			_, _ = yysep2, yy2arr2
-			const yyr2 bool = false
-			if yyr2 || yy2arr2 {
-				r.WriteArrayStart(4)
-			} else {
-				r.WriteMapStart(4)
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym4 := z.EncBinary()
-				_ = yym4
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Prefix))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Prefix"))
-				r.WriteMapElemValue()
-				yym5 := z.EncBinary()
-				_ = yym5
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Prefix))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym7 := z.EncBinary()
-				_ = yym7
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Dir))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Dir"))
-				r.WriteMapElemValue()
-				yym8 := z.EncBinary()
-				_ = yym8
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Dir))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym10 := z.EncBinary()
-				_ = yym10
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Value))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("Value"))
-				r.WriteMapElemValue()
-				yym11 := z.EncBinary()
-				_ = yym11
-				if false {
-				} else {
-					r.EncodeString(codecSelferC_UTF87612, string(x.Value))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayElem()
-				yym13 := z.EncBinary()
-				_ = yym13
-				if false {
-				} else if z.HasExtensions() && z.EncExt(x.TTL) {
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			} else {
-				r.WriteMapElemKey()
-				r.EncodeString(codecSelferC_UTF87612, string("TTL"))
-				r.WriteMapElemValue()
-				yym14 := z.EncBinary()
-				_ = yym14
-				if false {
-				} else if z.HasExtensions() && z.EncExt(x.TTL) {
-				} else {
-					r.EncodeInt(int64(x.TTL))
-				}
-			}
-			if yyr2 || yy2arr2 {
-				r.WriteArrayEnd()
-			} else {
-				r.WriteMapEnd()
-			}
-		}
-	}
-}
-
-func (x *createInOrderAction) CodecDecodeSelf(d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	yym1 := z.DecBinary()
-	_ = yym1
-	if false {
-	} else if z.HasExtensions() && z.DecExt(x) {
-	} else {
-		yyct2 := r.ContainerType()
-		if yyct2 == codecSelferValueTypeMap7612 {
-			yyl2 := r.ReadMapStart()
-			if yyl2 == 0 {
-				r.ReadMapEnd()
-			} else {
-				x.codecDecodeSelfFromMap(yyl2, d)
-			}
-		} else if yyct2 == codecSelferValueTypeArray7612 {
-			yyl2 := r.ReadArrayStart()
-			if yyl2 == 0 {
-				r.ReadArrayEnd()
-			} else {
-				x.codecDecodeSelfFromArray(yyl2, d)
-			}
-		} else {
-			panic(codecSelferOnlyMapOrArrayEncodeToStructErr7612)
-		}
-	}
-}
-
-func (x *createInOrderAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
-	_ = yys3Slc
-	var yyhl3 bool = l >= 0
-	for yyj3 := 0; ; yyj3++ {
-		if yyhl3 {
-			if yyj3 >= l {
-				break
-			}
-		} else {
-			if r.CheckBreak() {
-				break
-			}
-		}
-		r.ReadMapElemKey()
-		yys3Slc = r.DecodeStringAsBytes()
-		yys3 := string(yys3Slc)
-		r.ReadMapElemValue()
-		switch yys3 {
-		case "Prefix":
-			if r.TryDecodeAsNil() {
-				x.Prefix = ""
-			} else {
-				yyv4 := &x.Prefix
-				yym5 := z.DecBinary()
-				_ = yym5
-				if false {
-				} else {
-					*((*string)(yyv4)) = r.DecodeString()
-				}
-			}
-		case "Dir":
-			if r.TryDecodeAsNil() {
-				x.Dir = ""
-			} else {
-				yyv6 := &x.Dir
-				yym7 := z.DecBinary()
-				_ = yym7
-				if false {
-				} else {
-					*((*string)(yyv6)) = r.DecodeString()
-				}
-			}
-		case "Value":
-			if r.TryDecodeAsNil() {
-				x.Value = ""
-			} else {
-				yyv8 := &x.Value
-				yym9 := z.DecBinary()
-				_ = yym9
-				if false {
-				} else {
-					*((*string)(yyv8)) = r.DecodeString()
-				}
-			}
-		case "TTL":
-			if r.TryDecodeAsNil() {
-				x.TTL = 0
-			} else {
-				yyv10 := &x.TTL
-				yym11 := z.DecBinary()
-				_ = yym11
-				if false {
-				} else if z.HasExtensions() && z.DecExt(yyv10) {
-				} else {
-					*((*int64)(yyv10)) = int64(r.DecodeInt(64))
-				}
-			}
-		default:
-			z.DecStructFieldNotFound(-1, yys3)
-		} // end switch yys3
-	} // end for yyj3
-	r.ReadMapEnd()
-}
-
-func (x *createInOrderAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-	var yyj12 int
-	var yyb12 bool
-	var yyhl12 bool = l >= 0
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Prefix = ""
-	} else {
-		yyv13 := &x.Prefix
-		yym14 := z.DecBinary()
-		_ = yym14
-		if false {
-		} else {
-			*((*string)(yyv13)) = r.DecodeString()
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Dir = ""
-	} else {
-		yyv15 := &x.Dir
-		yym16 := z.DecBinary()
-		_ = yym16
-		if false {
-		} else {
-			*((*string)(yyv15)) = r.DecodeString()
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.Value = ""
-	} else {
-		yyv17 := &x.Value
-		yym18 := z.DecBinary()
-		_ = yym18
-		if false {
-		} else {
-			*((*string)(yyv17)) = r.DecodeString()
-		}
-	}
-	yyj12++
-	if yyhl12 {
-		yyb12 = yyj12 > l
-	} else {
-		yyb12 = r.CheckBreak()
-	}
-	if yyb12 {
-		r.ReadArrayEnd()
-		return
-	}
-	r.ReadArrayElem()
-	if r.TryDecodeAsNil() {
-		x.TTL = 0
-	} else {
-		yyv19 := &x.TTL
-		yym20 := z.DecBinary()
-		_ = yym20
-		if false {
-		} else if z.HasExtensions() && z.DecExt(yyv19) {
-		} else {
-			*((*int64)(yyv19)) = int64(r.DecodeInt(64))
-		}
-	}
-	for {
-		yyj12++
-		if yyhl12 {
-			yyb12 = yyj12 > l
-		} else {
-			yyb12 = r.CheckBreak()
-		}
-		if yyb12 {
-			break
-		}
-		r.ReadArrayElem()
-		z.DecStructFieldNotFound(yyj12-1, "")
-	}
-	r.ReadArrayEnd()
-}
-
-func (x codecSelfer7612) encNodes(v Nodes, e *codec1978.Encoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperEncoder(e)
-	_, _, _ = h, z, r
-	r.WriteArrayStart(len(v))
-	for _, yyv1 := range v {
-		r.WriteArrayElem()
-		if yyv1 == nil {
-			r.EncodeNil()
-		} else {
-			yyv1.CodecEncodeSelf(e)
-		}
-	}
-	r.WriteArrayEnd()
-}
-
-func (x codecSelfer7612) decNodes(v *Nodes, d *codec1978.Decoder) {
-	var h codecSelfer7612
-	z, r := codec1978.GenHelperDecoder(d)
-	_, _, _ = h, z, r
-
-	yyv1 := *v
-	yyh1, yyl1 := z.DecSliceHelperStart()
-	var yyc1 bool
-	_ = yyc1
-	if yyl1 == 0 {
-		if yyv1 == nil {
-			yyv1 = []*Node{}
-			yyc1 = true
-		} else if len(yyv1) != 0 {
-			yyv1 = yyv1[:0]
-			yyc1 = true
-		}
-	} else {
-		yyhl1 := yyl1 > 0
-		var yyrl1 int
-		_ = yyrl1
-		if yyhl1 {
-			if yyl1 > cap(yyv1) {
-				yyrl1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 8)
-				if yyrl1 <= cap(yyv1) {
-					yyv1 = yyv1[:yyrl1]
-				} else {
-					yyv1 = make([]*Node, yyrl1)
-				}
-				yyc1 = true
-			} else if yyl1 != len(yyv1) {
-				yyv1 = yyv1[:yyl1]
-				yyc1 = true
-			}
-		}
-		var yyj1 int
-		// var yydn1 bool
-		for ; (yyhl1 && yyj1 < yyl1) || !(yyhl1 || r.CheckBreak()); yyj1++ {
-			if yyj1 == 0 && len(yyv1) == 0 {
-				if yyhl1 {
-					yyrl1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 8)
-				} else {
-					yyrl1 = 8
-				}
-				yyv1 = make([]*Node, yyrl1)
-				yyc1 = true
-			}
-			yyh1.ElemContainerState(yyj1)
-			// yydn1 = r.TryDecodeAsNil()
-
-			// if indefinite, etc, then expand the slice if necessary
-			var yydb1 bool
-			if yyj1 >= len(yyv1) {
-				yyv1 = append(yyv1, nil)
-				yyc1 = true
-
-			}
-			if yydb1 {
-				z.DecSwallow()
-			} else {
-				if r.TryDecodeAsNil() {
-					if yyv1[yyj1] != nil {
-						*yyv1[yyj1] = Node{}
-					}
-				} else {
-					if yyv1[yyj1] == nil {
-						yyv1[yyj1] = new(Node)
-					}
-					yyw2 := yyv1[yyj1]
-					yyw2.CodecDecodeSelf(d)
-				}
-
-			}
-
-		}
-		if yyj1 < len(yyv1) {
-			yyv1 = yyv1[:yyj1]
-			yyc1 = true
-		} else if yyj1 == 0 && yyv1 == nil {
-			yyv1 = make([]*Node, 0)
-			yyc1 = true
-		}
-	}
-	yyh1.End()
-	if yyc1 {
-		*v = yyv1
-	}
-
-}
diff --git a/vendor/github.com/coreos/etcd/client/keys.go b/vendor/github.com/coreos/etcd/client/keys.go
deleted file mode 100644
index 8b9fd3f..0000000
--- a/vendor/github.com/coreos/etcd/client/keys.go
+++ /dev/null
@@ -1,681 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-//go:generate codecgen -d 1819 -r "Node|Response|Nodes" -o keys.generated.go keys.go
-
-import (
-	"context"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"net/http"
-	"net/url"
-	"strconv"
-	"strings"
-	"time"
-
-	"github.com/coreos/etcd/pkg/pathutil"
-	"github.com/ugorji/go/codec"
-)
-
-const (
-	ErrorCodeKeyNotFound  = 100
-	ErrorCodeTestFailed   = 101
-	ErrorCodeNotFile      = 102
-	ErrorCodeNotDir       = 104
-	ErrorCodeNodeExist    = 105
-	ErrorCodeRootROnly    = 107
-	ErrorCodeDirNotEmpty  = 108
-	ErrorCodeUnauthorized = 110
-
-	ErrorCodePrevValueRequired = 201
-	ErrorCodeTTLNaN            = 202
-	ErrorCodeIndexNaN          = 203
-	ErrorCodeInvalidField      = 209
-	ErrorCodeInvalidForm       = 210
-
-	ErrorCodeRaftInternal = 300
-	ErrorCodeLeaderElect  = 301
-
-	ErrorCodeWatcherCleared    = 400
-	ErrorCodeEventIndexCleared = 401
-)
-
-type Error struct {
-	Code    int    `json:"errorCode"`
-	Message string `json:"message"`
-	Cause   string `json:"cause"`
-	Index   uint64 `json:"index"`
-}
-
-func (e Error) Error() string {
-	return fmt.Sprintf("%v: %v (%v) [%v]", e.Code, e.Message, e.Cause, e.Index)
-}
-
-var (
-	ErrInvalidJSON = errors.New("client: response is invalid json. The endpoint is probably not valid etcd cluster endpoint.")
-	ErrEmptyBody   = errors.New("client: response body is empty")
-)
-
-// PrevExistType is used to define an existence condition when setting
-// or deleting Nodes.
-type PrevExistType string
-
-const (
-	PrevIgnore  = PrevExistType("")
-	PrevExist   = PrevExistType("true")
-	PrevNoExist = PrevExistType("false")
-)
-
-var (
-	defaultV2KeysPrefix = "/v2/keys"
-)
-
-// NewKeysAPI builds a KeysAPI that interacts with etcd's key-value
-// API over HTTP.
-func NewKeysAPI(c Client) KeysAPI {
-	return NewKeysAPIWithPrefix(c, defaultV2KeysPrefix)
-}
-
-// NewKeysAPIWithPrefix acts like NewKeysAPI, but allows the caller
-// to provide a custom base URL path. This should only be used in
-// very rare cases.
-func NewKeysAPIWithPrefix(c Client, p string) KeysAPI {
-	return &httpKeysAPI{
-		client: c,
-		prefix: p,
-	}
-}
-
-type KeysAPI interface {
-	// Get retrieves a set of Nodes from etcd
-	Get(ctx context.Context, key string, opts *GetOptions) (*Response, error)
-
-	// Set assigns a new value to a Node identified by a given key. The caller
-	// may define a set of conditions in the SetOptions. If SetOptions.Dir=true
-	// then value is ignored.
-	Set(ctx context.Context, key, value string, opts *SetOptions) (*Response, error)
-
-	// Delete removes a Node identified by the given key, optionally destroying
-	// all of its children as well. The caller may define a set of required
-	// conditions in an DeleteOptions object.
-	Delete(ctx context.Context, key string, opts *DeleteOptions) (*Response, error)
-
-	// Create is an alias for Set w/ PrevExist=false
-	Create(ctx context.Context, key, value string) (*Response, error)
-
-	// CreateInOrder is used to atomically create in-order keys within the given directory.
-	CreateInOrder(ctx context.Context, dir, value string, opts *CreateInOrderOptions) (*Response, error)
-
-	// Update is an alias for Set w/ PrevExist=true
-	Update(ctx context.Context, key, value string) (*Response, error)
-
-	// Watcher builds a new Watcher targeted at a specific Node identified
-	// by the given key. The Watcher may be configured at creation time
-	// through a WatcherOptions object. The returned Watcher is designed
-	// to emit events that happen to a Node, and optionally to its children.
-	Watcher(key string, opts *WatcherOptions) Watcher
-}
-
-type WatcherOptions struct {
-	// AfterIndex defines the index after-which the Watcher should
-	// start emitting events. For example, if a value of 5 is
-	// provided, the first event will have an index >= 6.
-	//
-	// Setting AfterIndex to 0 (default) means that the Watcher
-	// should start watching for events starting at the current
-	// index, whatever that may be.
-	AfterIndex uint64
-
-	// Recursive specifies whether or not the Watcher should emit
-	// events that occur in children of the given keyspace. If set
-	// to false (default), events will be limited to those that
-	// occur for the exact key.
-	Recursive bool
-}
-
-type CreateInOrderOptions struct {
-	// TTL defines a period of time after-which the Node should
-	// expire and no longer exist. Values <= 0 are ignored. Given
-	// that the zero-value is ignored, TTL cannot be used to set
-	// a TTL of 0.
-	TTL time.Duration
-}
-
-type SetOptions struct {
-	// PrevValue specifies what the current value of the Node must
-	// be in order for the Set operation to succeed.
-	//
-	// Leaving this field empty means that the caller wishes to
-	// ignore the current value of the Node. This cannot be used
-	// to compare the Node's current value to an empty string.
-	//
-	// PrevValue is ignored if Dir=true
-	PrevValue string
-
-	// PrevIndex indicates what the current ModifiedIndex of the
-	// Node must be in order for the Set operation to succeed.
-	//
-	// If PrevIndex is set to 0 (default), no comparison is made.
-	PrevIndex uint64
-
-	// PrevExist specifies whether the Node must currently exist
-	// (PrevExist) or not (PrevNoExist). If the caller does not
-	// care about existence, set PrevExist to PrevIgnore, or simply
-	// leave it unset.
-	PrevExist PrevExistType
-
-	// TTL defines a period of time after-which the Node should
-	// expire and no longer exist. Values <= 0 are ignored. Given
-	// that the zero-value is ignored, TTL cannot be used to set
-	// a TTL of 0.
-	TTL time.Duration
-
-	// Refresh set to true means a TTL value can be updated
-	// without firing a watch or changing the node value. A
-	// value must not be provided when refreshing a key.
-	Refresh bool
-
-	// Dir specifies whether or not this Node should be created as a directory.
-	Dir bool
-
-	// NoValueOnSuccess specifies whether the response contains the current value of the Node.
-	// If set, the response will only contain the current value when the request fails.
-	NoValueOnSuccess bool
-}
-
-type GetOptions struct {
-	// Recursive defines whether or not all children of the Node
-	// should be returned.
-	Recursive bool
-
-	// Sort instructs the server whether or not to sort the Nodes.
-	// If true, the Nodes are sorted alphabetically by key in
-	// ascending order (A to z). If false (default), the Nodes will
-	// not be sorted and the ordering used should not be considered
-	// predictable.
-	Sort bool
-
-	// Quorum specifies whether it gets the latest committed value that
-	// has been applied in quorum of members, which ensures external
-	// consistency (or linearizability).
-	Quorum bool
-}
-
-type DeleteOptions struct {
-	// PrevValue specifies what the current value of the Node must
-	// be in order for the Delete operation to succeed.
-	//
-	// Leaving this field empty means that the caller wishes to
-	// ignore the current value of the Node. This cannot be used
-	// to compare the Node's current value to an empty string.
-	PrevValue string
-
-	// PrevIndex indicates what the current ModifiedIndex of the
-	// Node must be in order for the Delete operation to succeed.
-	//
-	// If PrevIndex is set to 0 (default), no comparison is made.
-	PrevIndex uint64
-
-	// Recursive defines whether or not all children of the Node
-	// should be deleted. If set to true, all children of the Node
-	// identified by the given key will be deleted. If left unset
-	// or explicitly set to false, only a single Node will be
-	// deleted.
-	Recursive bool
-
-	// Dir specifies whether or not this Node should be removed as a directory.
-	Dir bool
-}
-
-type Watcher interface {
-	// Next blocks until an etcd event occurs, then returns a Response
-	// representing that event. The behavior of Next depends on the
-	// WatcherOptions used to construct the Watcher. Next is designed to
-	// be called repeatedly, each time blocking until a subsequent event
-	// is available.
-	//
-	// If the provided context is cancelled, Next will return a non-nil
-	// error. Any other failures encountered while waiting for the next
-	// event (connection issues, deserialization failures, etc) will
-	// also result in a non-nil error.
-	Next(context.Context) (*Response, error)
-}
-
-type Response struct {
-	// Action is the name of the operation that occurred. Possible values
-	// include get, set, delete, update, create, compareAndSwap,
-	// compareAndDelete and expire.
-	Action string `json:"action"`
-
-	// Node represents the state of the relevant etcd Node.
-	Node *Node `json:"node"`
-
-	// PrevNode represents the previous state of the Node. PrevNode is non-nil
-	// only if the Node existed before the action occurred and the action
-	// caused a change to the Node.
-	PrevNode *Node `json:"prevNode"`
-
-	// Index holds the cluster-level index at the time the Response was generated.
-	// This index is not tied to the Node(s) contained in this Response.
-	Index uint64 `json:"-"`
-
-	// ClusterID holds the cluster-level ID reported by the server.  This
-	// should be different for different etcd clusters.
-	ClusterID string `json:"-"`
-}
-
-type Node struct {
-	// Key represents the unique location of this Node (e.g. "/foo/bar").
-	Key string `json:"key"`
-
-	// Dir reports whether node describes a directory.
-	Dir bool `json:"dir,omitempty"`
-
-	// Value is the current data stored on this Node. If this Node
-	// is a directory, Value will be empty.
-	Value string `json:"value"`
-
-	// Nodes holds the children of this Node, only if this Node is a directory.
-	// This slice of will be arbitrarily deep (children, grandchildren, great-
-	// grandchildren, etc.) if a recursive Get or Watch request were made.
-	Nodes Nodes `json:"nodes"`
-
-	// CreatedIndex is the etcd index at-which this Node was created.
-	CreatedIndex uint64 `json:"createdIndex"`
-
-	// ModifiedIndex is the etcd index at-which this Node was last modified.
-	ModifiedIndex uint64 `json:"modifiedIndex"`
-
-	// Expiration is the server side expiration time of the key.
-	Expiration *time.Time `json:"expiration,omitempty"`
-
-	// TTL is the time to live of the key in second.
-	TTL int64 `json:"ttl,omitempty"`
-}
-
-func (n *Node) String() string {
-	return fmt.Sprintf("{Key: %s, CreatedIndex: %d, ModifiedIndex: %d, TTL: %d}", n.Key, n.CreatedIndex, n.ModifiedIndex, n.TTL)
-}
-
-// TTLDuration returns the Node's TTL as a time.Duration object
-func (n *Node) TTLDuration() time.Duration {
-	return time.Duration(n.TTL) * time.Second
-}
-
-type Nodes []*Node
-
-// interfaces for sorting
-
-func (ns Nodes) Len() int           { return len(ns) }
-func (ns Nodes) Less(i, j int) bool { return ns[i].Key < ns[j].Key }
-func (ns Nodes) Swap(i, j int)      { ns[i], ns[j] = ns[j], ns[i] }
-
-type httpKeysAPI struct {
-	client httpClient
-	prefix string
-}
-
-func (k *httpKeysAPI) Set(ctx context.Context, key, val string, opts *SetOptions) (*Response, error) {
-	act := &setAction{
-		Prefix: k.prefix,
-		Key:    key,
-		Value:  val,
-	}
-
-	if opts != nil {
-		act.PrevValue = opts.PrevValue
-		act.PrevIndex = opts.PrevIndex
-		act.PrevExist = opts.PrevExist
-		act.TTL = opts.TTL
-		act.Refresh = opts.Refresh
-		act.Dir = opts.Dir
-		act.NoValueOnSuccess = opts.NoValueOnSuccess
-	}
-
-	doCtx := ctx
-	if act.PrevExist == PrevNoExist {
-		doCtx = context.WithValue(doCtx, &oneShotCtxValue, &oneShotCtxValue)
-	}
-	resp, body, err := k.client.Do(doCtx, act)
-	if err != nil {
-		return nil, err
-	}
-
-	return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
-}
-
-func (k *httpKeysAPI) Create(ctx context.Context, key, val string) (*Response, error) {
-	return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevNoExist})
-}
-
-func (k *httpKeysAPI) CreateInOrder(ctx context.Context, dir, val string, opts *CreateInOrderOptions) (*Response, error) {
-	act := &createInOrderAction{
-		Prefix: k.prefix,
-		Dir:    dir,
-		Value:  val,
-	}
-
-	if opts != nil {
-		act.TTL = opts.TTL
-	}
-
-	resp, body, err := k.client.Do(ctx, act)
-	if err != nil {
-		return nil, err
-	}
-
-	return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
-}
-
-func (k *httpKeysAPI) Update(ctx context.Context, key, val string) (*Response, error) {
-	return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevExist})
-}
-
-func (k *httpKeysAPI) Delete(ctx context.Context, key string, opts *DeleteOptions) (*Response, error) {
-	act := &deleteAction{
-		Prefix: k.prefix,
-		Key:    key,
-	}
-
-	if opts != nil {
-		act.PrevValue = opts.PrevValue
-		act.PrevIndex = opts.PrevIndex
-		act.Dir = opts.Dir
-		act.Recursive = opts.Recursive
-	}
-
-	doCtx := context.WithValue(ctx, &oneShotCtxValue, &oneShotCtxValue)
-	resp, body, err := k.client.Do(doCtx, act)
-	if err != nil {
-		return nil, err
-	}
-
-	return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
-}
-
-func (k *httpKeysAPI) Get(ctx context.Context, key string, opts *GetOptions) (*Response, error) {
-	act := &getAction{
-		Prefix: k.prefix,
-		Key:    key,
-	}
-
-	if opts != nil {
-		act.Recursive = opts.Recursive
-		act.Sorted = opts.Sort
-		act.Quorum = opts.Quorum
-	}
-
-	resp, body, err := k.client.Do(ctx, act)
-	if err != nil {
-		return nil, err
-	}
-
-	return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
-}
-
-func (k *httpKeysAPI) Watcher(key string, opts *WatcherOptions) Watcher {
-	act := waitAction{
-		Prefix: k.prefix,
-		Key:    key,
-	}
-
-	if opts != nil {
-		act.Recursive = opts.Recursive
-		if opts.AfterIndex > 0 {
-			act.WaitIndex = opts.AfterIndex + 1
-		}
-	}
-
-	return &httpWatcher{
-		client:   k.client,
-		nextWait: act,
-	}
-}
-
-type httpWatcher struct {
-	client   httpClient
-	nextWait waitAction
-}
-
-func (hw *httpWatcher) Next(ctx context.Context) (*Response, error) {
-	for {
-		httpresp, body, err := hw.client.Do(ctx, &hw.nextWait)
-		if err != nil {
-			return nil, err
-		}
-
-		resp, err := unmarshalHTTPResponse(httpresp.StatusCode, httpresp.Header, body)
-		if err != nil {
-			if err == ErrEmptyBody {
-				continue
-			}
-			return nil, err
-		}
-
-		hw.nextWait.WaitIndex = resp.Node.ModifiedIndex + 1
-		return resp, nil
-	}
-}
-
-// v2KeysURL forms a URL representing the location of a key.
-// The endpoint argument represents the base URL of an etcd
-// server. The prefix is the path needed to route from the
-// provided endpoint's path to the root of the keys API
-// (typically "/v2/keys").
-func v2KeysURL(ep url.URL, prefix, key string) *url.URL {
-	// We concatenate all parts together manually. We cannot use
-	// path.Join because it does not reserve trailing slash.
-	// We call CanonicalURLPath to further cleanup the path.
-	if prefix != "" && prefix[0] != '/' {
-		prefix = "/" + prefix
-	}
-	if key != "" && key[0] != '/' {
-		key = "/" + key
-	}
-	ep.Path = pathutil.CanonicalURLPath(ep.Path + prefix + key)
-	return &ep
-}
-
-type getAction struct {
-	Prefix    string
-	Key       string
-	Recursive bool
-	Sorted    bool
-	Quorum    bool
-}
-
-func (g *getAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2KeysURL(ep, g.Prefix, g.Key)
-
-	params := u.Query()
-	params.Set("recursive", strconv.FormatBool(g.Recursive))
-	params.Set("sorted", strconv.FormatBool(g.Sorted))
-	params.Set("quorum", strconv.FormatBool(g.Quorum))
-	u.RawQuery = params.Encode()
-
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	return req
-}
-
-type waitAction struct {
-	Prefix    string
-	Key       string
-	WaitIndex uint64
-	Recursive bool
-}
-
-func (w *waitAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2KeysURL(ep, w.Prefix, w.Key)
-
-	params := u.Query()
-	params.Set("wait", "true")
-	params.Set("waitIndex", strconv.FormatUint(w.WaitIndex, 10))
-	params.Set("recursive", strconv.FormatBool(w.Recursive))
-	u.RawQuery = params.Encode()
-
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	return req
-}
-
-type setAction struct {
-	Prefix           string
-	Key              string
-	Value            string
-	PrevValue        string
-	PrevIndex        uint64
-	PrevExist        PrevExistType
-	TTL              time.Duration
-	Refresh          bool
-	Dir              bool
-	NoValueOnSuccess bool
-}
-
-func (a *setAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2KeysURL(ep, a.Prefix, a.Key)
-
-	params := u.Query()
-	form := url.Values{}
-
-	// we're either creating a directory or setting a key
-	if a.Dir {
-		params.Set("dir", strconv.FormatBool(a.Dir))
-	} else {
-		// These options are only valid for setting a key
-		if a.PrevValue != "" {
-			params.Set("prevValue", a.PrevValue)
-		}
-		form.Add("value", a.Value)
-	}
-
-	// Options which apply to both setting a key and creating a dir
-	if a.PrevIndex != 0 {
-		params.Set("prevIndex", strconv.FormatUint(a.PrevIndex, 10))
-	}
-	if a.PrevExist != PrevIgnore {
-		params.Set("prevExist", string(a.PrevExist))
-	}
-	if a.TTL > 0 {
-		form.Add("ttl", strconv.FormatUint(uint64(a.TTL.Seconds()), 10))
-	}
-
-	if a.Refresh {
-		form.Add("refresh", "true")
-	}
-	if a.NoValueOnSuccess {
-		params.Set("noValueOnSuccess", strconv.FormatBool(a.NoValueOnSuccess))
-	}
-
-	u.RawQuery = params.Encode()
-	body := strings.NewReader(form.Encode())
-
-	req, _ := http.NewRequest("PUT", u.String(), body)
-	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-
-	return req
-}
-
-type deleteAction struct {
-	Prefix    string
-	Key       string
-	PrevValue string
-	PrevIndex uint64
-	Dir       bool
-	Recursive bool
-}
-
-func (a *deleteAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2KeysURL(ep, a.Prefix, a.Key)
-
-	params := u.Query()
-	if a.PrevValue != "" {
-		params.Set("prevValue", a.PrevValue)
-	}
-	if a.PrevIndex != 0 {
-		params.Set("prevIndex", strconv.FormatUint(a.PrevIndex, 10))
-	}
-	if a.Dir {
-		params.Set("dir", "true")
-	}
-	if a.Recursive {
-		params.Set("recursive", "true")
-	}
-	u.RawQuery = params.Encode()
-
-	req, _ := http.NewRequest("DELETE", u.String(), nil)
-	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-
-	return req
-}
-
-type createInOrderAction struct {
-	Prefix string
-	Dir    string
-	Value  string
-	TTL    time.Duration
-}
-
-func (a *createInOrderAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2KeysURL(ep, a.Prefix, a.Dir)
-
-	form := url.Values{}
-	form.Add("value", a.Value)
-	if a.TTL > 0 {
-		form.Add("ttl", strconv.FormatUint(uint64(a.TTL.Seconds()), 10))
-	}
-	body := strings.NewReader(form.Encode())
-
-	req, _ := http.NewRequest("POST", u.String(), body)
-	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-	return req
-}
-
-func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Response, err error) {
-	switch code {
-	case http.StatusOK, http.StatusCreated:
-		if len(body) == 0 {
-			return nil, ErrEmptyBody
-		}
-		res, err = unmarshalSuccessfulKeysResponse(header, body)
-	default:
-		err = unmarshalFailedKeysResponse(body)
-	}
-	return res, err
-}
-
-func unmarshalSuccessfulKeysResponse(header http.Header, body []byte) (*Response, error) {
-	var res Response
-	err := codec.NewDecoderBytes(body, new(codec.JsonHandle)).Decode(&res)
-	if err != nil {
-		return nil, ErrInvalidJSON
-	}
-	if header.Get("X-Etcd-Index") != "" {
-		res.Index, err = strconv.ParseUint(header.Get("X-Etcd-Index"), 10, 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-	res.ClusterID = header.Get("X-Etcd-Cluster-ID")
-	return &res, nil
-}
-
-func unmarshalFailedKeysResponse(body []byte) error {
-	var etcdErr Error
-	if err := json.Unmarshal(body, &etcdErr); err != nil {
-		return ErrInvalidJSON
-	}
-	return etcdErr
-}
diff --git a/vendor/github.com/coreos/etcd/client/members.go b/vendor/github.com/coreos/etcd/client/members.go
deleted file mode 100644
index aafa3d1..0000000
--- a/vendor/github.com/coreos/etcd/client/members.go
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"net/url"
-	"path"
-
-	"github.com/coreos/etcd/pkg/types"
-)
-
-var (
-	defaultV2MembersPrefix = "/v2/members"
-	defaultLeaderSuffix    = "/leader"
-)
-
-type Member struct {
-	// ID is the unique identifier of this Member.
-	ID string `json:"id"`
-
-	// Name is a human-readable, non-unique identifier of this Member.
-	Name string `json:"name"`
-
-	// PeerURLs represents the HTTP(S) endpoints this Member uses to
-	// participate in etcd's consensus protocol.
-	PeerURLs []string `json:"peerURLs"`
-
-	// ClientURLs represents the HTTP(S) endpoints on which this Member
-	// serves its client-facing APIs.
-	ClientURLs []string `json:"clientURLs"`
-}
-
-type memberCollection []Member
-
-func (c *memberCollection) UnmarshalJSON(data []byte) error {
-	d := struct {
-		Members []Member
-	}{}
-
-	if err := json.Unmarshal(data, &d); err != nil {
-		return err
-	}
-
-	if d.Members == nil {
-		*c = make([]Member, 0)
-		return nil
-	}
-
-	*c = d.Members
-	return nil
-}
-
-type memberCreateOrUpdateRequest struct {
-	PeerURLs types.URLs
-}
-
-func (m *memberCreateOrUpdateRequest) MarshalJSON() ([]byte, error) {
-	s := struct {
-		PeerURLs []string `json:"peerURLs"`
-	}{
-		PeerURLs: make([]string, len(m.PeerURLs)),
-	}
-
-	for i, u := range m.PeerURLs {
-		s.PeerURLs[i] = u.String()
-	}
-
-	return json.Marshal(&s)
-}
-
-// NewMembersAPI constructs a new MembersAPI that uses HTTP to
-// interact with etcd's membership API.
-func NewMembersAPI(c Client) MembersAPI {
-	return &httpMembersAPI{
-		client: c,
-	}
-}
-
-type MembersAPI interface {
-	// List enumerates the current cluster membership.
-	List(ctx context.Context) ([]Member, error)
-
-	// Add instructs etcd to accept a new Member into the cluster.
-	Add(ctx context.Context, peerURL string) (*Member, error)
-
-	// Remove demotes an existing Member out of the cluster.
-	Remove(ctx context.Context, mID string) error
-
-	// Update instructs etcd to update an existing Member in the cluster.
-	Update(ctx context.Context, mID string, peerURLs []string) error
-
-	// Leader gets current leader of the cluster
-	Leader(ctx context.Context) (*Member, error)
-}
-
-type httpMembersAPI struct {
-	client httpClient
-}
-
-func (m *httpMembersAPI) List(ctx context.Context) ([]Member, error) {
-	req := &membersAPIActionList{}
-	resp, body, err := m.client.Do(ctx, req)
-	if err != nil {
-		return nil, err
-	}
-
-	if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		return nil, err
-	}
-
-	var mCollection memberCollection
-	if err := json.Unmarshal(body, &mCollection); err != nil {
-		return nil, err
-	}
-
-	return []Member(mCollection), nil
-}
-
-func (m *httpMembersAPI) Add(ctx context.Context, peerURL string) (*Member, error) {
-	urls, err := types.NewURLs([]string{peerURL})
-	if err != nil {
-		return nil, err
-	}
-
-	req := &membersAPIActionAdd{peerURLs: urls}
-	resp, body, err := m.client.Do(ctx, req)
-	if err != nil {
-		return nil, err
-	}
-
-	if err := assertStatusCode(resp.StatusCode, http.StatusCreated, http.StatusConflict); err != nil {
-		return nil, err
-	}
-
-	if resp.StatusCode != http.StatusCreated {
-		var merr membersError
-		if err := json.Unmarshal(body, &merr); err != nil {
-			return nil, err
-		}
-		return nil, merr
-	}
-
-	var memb Member
-	if err := json.Unmarshal(body, &memb); err != nil {
-		return nil, err
-	}
-
-	return &memb, nil
-}
-
-func (m *httpMembersAPI) Update(ctx context.Context, memberID string, peerURLs []string) error {
-	urls, err := types.NewURLs(peerURLs)
-	if err != nil {
-		return err
-	}
-
-	req := &membersAPIActionUpdate{peerURLs: urls, memberID: memberID}
-	resp, body, err := m.client.Do(ctx, req)
-	if err != nil {
-		return err
-	}
-
-	if err := assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusNotFound, http.StatusConflict); err != nil {
-		return err
-	}
-
-	if resp.StatusCode != http.StatusNoContent {
-		var merr membersError
-		if err := json.Unmarshal(body, &merr); err != nil {
-			return err
-		}
-		return merr
-	}
-
-	return nil
-}
-
-func (m *httpMembersAPI) Remove(ctx context.Context, memberID string) error {
-	req := &membersAPIActionRemove{memberID: memberID}
-	resp, _, err := m.client.Do(ctx, req)
-	if err != nil {
-		return err
-	}
-
-	return assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusGone)
-}
-
-func (m *httpMembersAPI) Leader(ctx context.Context) (*Member, error) {
-	req := &membersAPIActionLeader{}
-	resp, body, err := m.client.Do(ctx, req)
-	if err != nil {
-		return nil, err
-	}
-
-	if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		return nil, err
-	}
-
-	var leader Member
-	if err := json.Unmarshal(body, &leader); err != nil {
-		return nil, err
-	}
-
-	return &leader, nil
-}
-
-type membersAPIActionList struct{}
-
-func (l *membersAPIActionList) HTTPRequest(ep url.URL) *http.Request {
-	u := v2MembersURL(ep)
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	return req
-}
-
-type membersAPIActionRemove struct {
-	memberID string
-}
-
-func (d *membersAPIActionRemove) HTTPRequest(ep url.URL) *http.Request {
-	u := v2MembersURL(ep)
-	u.Path = path.Join(u.Path, d.memberID)
-	req, _ := http.NewRequest("DELETE", u.String(), nil)
-	return req
-}
-
-type membersAPIActionAdd struct {
-	peerURLs types.URLs
-}
-
-func (a *membersAPIActionAdd) HTTPRequest(ep url.URL) *http.Request {
-	u := v2MembersURL(ep)
-	m := memberCreateOrUpdateRequest{PeerURLs: a.peerURLs}
-	b, _ := json.Marshal(&m)
-	req, _ := http.NewRequest("POST", u.String(), bytes.NewReader(b))
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-type membersAPIActionUpdate struct {
-	memberID string
-	peerURLs types.URLs
-}
-
-func (a *membersAPIActionUpdate) HTTPRequest(ep url.URL) *http.Request {
-	u := v2MembersURL(ep)
-	m := memberCreateOrUpdateRequest{PeerURLs: a.peerURLs}
-	u.Path = path.Join(u.Path, a.memberID)
-	b, _ := json.Marshal(&m)
-	req, _ := http.NewRequest("PUT", u.String(), bytes.NewReader(b))
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-func assertStatusCode(got int, want ...int) (err error) {
-	for _, w := range want {
-		if w == got {
-			return nil
-		}
-	}
-	return fmt.Errorf("unexpected status code %d", got)
-}
-
-type membersAPIActionLeader struct{}
-
-func (l *membersAPIActionLeader) HTTPRequest(ep url.URL) *http.Request {
-	u := v2MembersURL(ep)
-	u.Path = path.Join(u.Path, defaultLeaderSuffix)
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	return req
-}
-
-// v2MembersURL add the necessary path to the provided endpoint
-// to route requests to the default v2 members API.
-func v2MembersURL(ep url.URL) *url.URL {
-	ep.Path = path.Join(ep.Path, defaultV2MembersPrefix)
-	return &ep
-}
-
-type membersError struct {
-	Message string `json:"message"`
-	Code    int    `json:"-"`
-}
-
-func (e membersError) Error() string {
-	return e.Message
-}
diff --git a/vendor/github.com/coreos/etcd/client/util.go b/vendor/github.com/coreos/etcd/client/util.go
deleted file mode 100644
index 15a8bab..0000000
--- a/vendor/github.com/coreos/etcd/client/util.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import (
-	"regexp"
-)
-
-var (
-	roleNotFoundRegExp *regexp.Regexp
-	userNotFoundRegExp *regexp.Regexp
-)
-
-func init() {
-	roleNotFoundRegExp = regexp.MustCompile("auth: Role .* does not exist.")
-	userNotFoundRegExp = regexp.MustCompile("auth: User .* does not exist.")
-}
-
-// IsKeyNotFound returns true if the error code is ErrorCodeKeyNotFound.
-func IsKeyNotFound(err error) bool {
-	if cErr, ok := err.(Error); ok {
-		return cErr.Code == ErrorCodeKeyNotFound
-	}
-	return false
-}
-
-// IsRoleNotFound returns true if the error means role not found of v2 API.
-func IsRoleNotFound(err error) bool {
-	if ae, ok := err.(authError); ok {
-		return roleNotFoundRegExp.MatchString(ae.Message)
-	}
-	return false
-}
-
-// IsUserNotFound returns true if the error means user not found of v2 API.
-func IsUserNotFound(err error) bool {
-	if ae, ok := err.(authError); ok {
-		return userNotFoundRegExp.MatchString(ae.Message)
-	}
-	return false
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/README.md b/vendor/github.com/coreos/etcd/clientv3/README.md
deleted file mode 100644
index 376bfba..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/README.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# etcd/clientv3
-
-[![Godoc](https://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/github.com/coreos/etcd/clientv3)
-
-`etcd/clientv3` is the official Go etcd client for v3.
-
-## Install
-
-```bash
-go get github.com/coreos/etcd/clientv3
-```
-
-## Get started
-
-Create client using `clientv3.New`:
-
-```go
-cli, err := clientv3.New(clientv3.Config{
-	Endpoints:   []string{"localhost:2379", "localhost:22379", "localhost:32379"},
-	DialTimeout: 5 * time.Second,
-})
-if err != nil {
-	// handle error!
-}
-defer cli.Close()
-```
-
-etcd v3 uses [`gRPC`](http://www.grpc.io) for remote procedure calls. And `clientv3` uses
-[`grpc-go`](https://github.com/grpc/grpc-go) to connect to etcd. Make sure to close the client after using it. 
-If the client is not closed, the connection will have leaky goroutines. To specify client request timeout,
-pass `context.WithTimeout` to APIs:
-
-```go
-ctx, cancel := context.WithTimeout(context.Background(), timeout)
-resp, err := cli.Put(ctx, "sample_key", "sample_value")
-cancel()
-if err != nil {
-    // handle error!
-}
-// use the response
-```
-
-etcd uses `cmd/vendor` directory to store external dependencies, which are
-to be compiled into etcd release binaries. `client` can be imported without
-vendoring. For full compatibility, it is recommended to vendor builds using
-etcd's vendored packages, using tools like godep, as in
-[vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories).
-For more detail, please read [Go vendor design](https://golang.org/s/go15vendor).
-
-## Error Handling
-
-etcd client returns 2 types of errors:
-
-1. context error: canceled or deadline exceeded.
-2. gRPC error: see [api/v3rpc/rpctypes](https://godoc.org/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes).
-
-Here is the example code to handle client errors:
-
-```go
-resp, err := cli.Put(ctx, "", "")
-if err != nil {
-	switch err {
-	case context.Canceled:
-		log.Fatalf("ctx is canceled by another routine: %v", err)
-	case context.DeadlineExceeded:
-		log.Fatalf("ctx is attached with a deadline is exceeded: %v", err)
-	case rpctypes.ErrEmptyKey:
-		log.Fatalf("client-side error: %v", err)
-	default:
-		log.Fatalf("bad cluster endpoints, which are not etcd servers: %v", err)
-	}
-}
-```
-
-## Metrics
-
-The etcd client optionally exposes RPC metrics through [go-grpc-prometheus](https://github.com/grpc-ecosystem/go-grpc-prometheus). See the [examples](https://github.com/coreos/etcd/blob/master/clientv3/example_metrics_test.go).
-
-## Namespacing
-
-The [namespace](https://godoc.org/github.com/coreos/etcd/clientv3/namespace) package provides `clientv3` interface wrappers to transparently isolate client requests to a user-defined prefix.
-
-## Examples
-
-More code examples can be found at [GoDoc](https://godoc.org/github.com/coreos/etcd/clientv3).
diff --git a/vendor/github.com/coreos/etcd/clientv3/auth.go b/vendor/github.com/coreos/etcd/clientv3/auth.go
deleted file mode 100644
index 7545bb6..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/auth.go
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-	"fmt"
-	"strings"
-
-	"github.com/coreos/etcd/auth/authpb"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-)
-
-type (
-	AuthEnableResponse               pb.AuthEnableResponse
-	AuthDisableResponse              pb.AuthDisableResponse
-	AuthenticateResponse             pb.AuthenticateResponse
-	AuthUserAddResponse              pb.AuthUserAddResponse
-	AuthUserDeleteResponse           pb.AuthUserDeleteResponse
-	AuthUserChangePasswordResponse   pb.AuthUserChangePasswordResponse
-	AuthUserGrantRoleResponse        pb.AuthUserGrantRoleResponse
-	AuthUserGetResponse              pb.AuthUserGetResponse
-	AuthUserRevokeRoleResponse       pb.AuthUserRevokeRoleResponse
-	AuthRoleAddResponse              pb.AuthRoleAddResponse
-	AuthRoleGrantPermissionResponse  pb.AuthRoleGrantPermissionResponse
-	AuthRoleGetResponse              pb.AuthRoleGetResponse
-	AuthRoleRevokePermissionResponse pb.AuthRoleRevokePermissionResponse
-	AuthRoleDeleteResponse           pb.AuthRoleDeleteResponse
-	AuthUserListResponse             pb.AuthUserListResponse
-	AuthRoleListResponse             pb.AuthRoleListResponse
-
-	PermissionType authpb.Permission_Type
-	Permission     authpb.Permission
-)
-
-const (
-	PermRead      = authpb.READ
-	PermWrite     = authpb.WRITE
-	PermReadWrite = authpb.READWRITE
-)
-
-type Auth interface {
-	// AuthEnable enables auth of an etcd cluster.
-	AuthEnable(ctx context.Context) (*AuthEnableResponse, error)
-
-	// AuthDisable disables auth of an etcd cluster.
-	AuthDisable(ctx context.Context) (*AuthDisableResponse, error)
-
-	// UserAdd adds a new user to an etcd cluster.
-	UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error)
-
-	// UserDelete deletes a user from an etcd cluster.
-	UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error)
-
-	// UserChangePassword changes a password of a user.
-	UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error)
-
-	// UserGrantRole grants a role to a user.
-	UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error)
-
-	// UserGet gets a detailed information of a user.
-	UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error)
-
-	// UserList gets a list of all users.
-	UserList(ctx context.Context) (*AuthUserListResponse, error)
-
-	// UserRevokeRole revokes a role of a user.
-	UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error)
-
-	// RoleAdd adds a new role to an etcd cluster.
-	RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error)
-
-	// RoleGrantPermission grants a permission to a role.
-	RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error)
-
-	// RoleGet gets a detailed information of a role.
-	RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error)
-
-	// RoleList gets a list of all roles.
-	RoleList(ctx context.Context) (*AuthRoleListResponse, error)
-
-	// RoleRevokePermission revokes a permission from a role.
-	RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error)
-
-	// RoleDelete deletes a role.
-	RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error)
-}
-
-type auth struct {
-	remote   pb.AuthClient
-	callOpts []grpc.CallOption
-}
-
-func NewAuth(c *Client) Auth {
-	api := &auth{remote: RetryAuthClient(c)}
-	if c != nil {
-		api.callOpts = c.callOpts
-	}
-	return api
-}
-
-func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) {
-	resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}, auth.callOpts...)
-	return (*AuthEnableResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) {
-	resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}, auth.callOpts...)
-	return (*AuthDisableResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) {
-	resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password}, auth.callOpts...)
-	return (*AuthUserAddResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) {
-	resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}, auth.callOpts...)
-	return (*AuthUserDeleteResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) {
-	resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}, auth.callOpts...)
-	return (*AuthUserChangePasswordResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) {
-	resp, err := auth.remote.UserGrantRole(ctx, &pb.AuthUserGrantRoleRequest{User: user, Role: role}, auth.callOpts...)
-	return (*AuthUserGrantRoleResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) {
-	resp, err := auth.remote.UserGet(ctx, &pb.AuthUserGetRequest{Name: name}, auth.callOpts...)
-	return (*AuthUserGetResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) UserList(ctx context.Context) (*AuthUserListResponse, error) {
-	resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{}, auth.callOpts...)
-	return (*AuthUserListResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) {
-	resp, err := auth.remote.UserRevokeRole(ctx, &pb.AuthUserRevokeRoleRequest{Name: name, Role: role}, auth.callOpts...)
-	return (*AuthUserRevokeRoleResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) {
-	resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}, auth.callOpts...)
-	return (*AuthRoleAddResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error) {
-	perm := &authpb.Permission{
-		Key:      []byte(key),
-		RangeEnd: []byte(rangeEnd),
-		PermType: authpb.Permission_Type(permType),
-	}
-	resp, err := auth.remote.RoleGrantPermission(ctx, &pb.AuthRoleGrantPermissionRequest{Name: name, Perm: perm}, auth.callOpts...)
-	return (*AuthRoleGrantPermissionResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) {
-	resp, err := auth.remote.RoleGet(ctx, &pb.AuthRoleGetRequest{Role: role}, auth.callOpts...)
-	return (*AuthRoleGetResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) RoleList(ctx context.Context) (*AuthRoleListResponse, error) {
-	resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{}, auth.callOpts...)
-	return (*AuthRoleListResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) {
-	resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: key, RangeEnd: rangeEnd}, auth.callOpts...)
-	return (*AuthRoleRevokePermissionResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *auth) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) {
-	resp, err := auth.remote.RoleDelete(ctx, &pb.AuthRoleDeleteRequest{Role: role}, auth.callOpts...)
-	return (*AuthRoleDeleteResponse)(resp), toErr(ctx, err)
-}
-
-func StrToPermissionType(s string) (PermissionType, error) {
-	val, ok := authpb.Permission_Type_value[strings.ToUpper(s)]
-	if ok {
-		return PermissionType(val), nil
-	}
-	return PermissionType(-1), fmt.Errorf("invalid permission type: %s", s)
-}
-
-type authenticator struct {
-	conn     *grpc.ClientConn // conn in-use
-	remote   pb.AuthClient
-	callOpts []grpc.CallOption
-}
-
-func (auth *authenticator) authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error) {
-	resp, err := auth.remote.Authenticate(ctx, &pb.AuthenticateRequest{Name: name, Password: password}, auth.callOpts...)
-	return (*AuthenticateResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *authenticator) close() {
-	auth.conn.Close()
-}
-
-func newAuthenticator(endpoint string, opts []grpc.DialOption, c *Client) (*authenticator, error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return nil, err
-	}
-
-	api := &authenticator{
-		conn:   conn,
-		remote: pb.NewAuthClient(conn),
-	}
-	if c != nil {
-		api.callOpts = c.callOpts
-	}
-	return api, nil
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/client.go b/vendor/github.com/coreos/etcd/clientv3/client.go
deleted file mode 100644
index 7132807..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/client.go
+++ /dev/null
@@ -1,576 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"net"
-	"net/url"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/credentials"
-	"google.golang.org/grpc/keepalive"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/status"
-)
-
-var (
-	ErrNoAvailableEndpoints = errors.New("etcdclient: no available endpoints")
-	ErrOldCluster           = errors.New("etcdclient: old cluster version")
-)
-
-// Client provides and manages an etcd v3 client session.
-type Client struct {
-	Cluster
-	KV
-	Lease
-	Watcher
-	Auth
-	Maintenance
-
-	conn     *grpc.ClientConn
-	dialerrc chan error
-
-	cfg      Config
-	creds    *credentials.TransportCredentials
-	balancer *healthBalancer
-	mu       *sync.Mutex
-
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	// Username is a user name for authentication.
-	Username string
-	// Password is a password for authentication.
-	Password string
-	// tokenCred is an instance of WithPerRPCCredentials()'s argument
-	tokenCred *authTokenCredential
-
-	callOpts []grpc.CallOption
-}
-
-// New creates a new etcdv3 client from a given configuration.
-func New(cfg Config) (*Client, error) {
-	if len(cfg.Endpoints) == 0 {
-		return nil, ErrNoAvailableEndpoints
-	}
-
-	return newClient(&cfg)
-}
-
-// NewCtxClient creates a client with a context but no underlying grpc
-// connection. This is useful for embedded cases that override the
-// service interface implementations and do not need connection management.
-func NewCtxClient(ctx context.Context) *Client {
-	cctx, cancel := context.WithCancel(ctx)
-	return &Client{ctx: cctx, cancel: cancel}
-}
-
-// NewFromURL creates a new etcdv3 client from a URL.
-func NewFromURL(url string) (*Client, error) {
-	return New(Config{Endpoints: []string{url}})
-}
-
-// Close shuts down the client's etcd connections.
-func (c *Client) Close() error {
-	c.cancel()
-	c.Watcher.Close()
-	c.Lease.Close()
-	if c.conn != nil {
-		return toErr(c.ctx, c.conn.Close())
-	}
-	return c.ctx.Err()
-}
-
-// Ctx is a context for "out of band" messages (e.g., for sending
-// "clean up" message when another context is canceled). It is
-// canceled on client Close().
-func (c *Client) Ctx() context.Context { return c.ctx }
-
-// Endpoints lists the registered endpoints for the client.
-func (c *Client) Endpoints() (eps []string) {
-	// copy the slice; protect original endpoints from being changed
-	eps = make([]string, len(c.cfg.Endpoints))
-	copy(eps, c.cfg.Endpoints)
-	return
-}
-
-// SetEndpoints updates client's endpoints.
-func (c *Client) SetEndpoints(eps ...string) {
-	c.mu.Lock()
-	c.cfg.Endpoints = eps
-	c.mu.Unlock()
-	c.balancer.updateAddrs(eps...)
-
-	// updating notifyCh can trigger new connections,
-	// need update addrs if all connections are down
-	// or addrs does not include pinAddr.
-	c.balancer.mu.RLock()
-	update := !hasAddr(c.balancer.addrs, c.balancer.pinAddr)
-	c.balancer.mu.RUnlock()
-	if update {
-		select {
-		case c.balancer.updateAddrsC <- notifyNext:
-		case <-c.balancer.stopc:
-		}
-	}
-}
-
-// Sync synchronizes client's endpoints with the known endpoints from the etcd membership.
-func (c *Client) Sync(ctx context.Context) error {
-	mresp, err := c.MemberList(ctx)
-	if err != nil {
-		return err
-	}
-	var eps []string
-	for _, m := range mresp.Members {
-		eps = append(eps, m.ClientURLs...)
-	}
-	c.SetEndpoints(eps...)
-	return nil
-}
-
-func (c *Client) autoSync() {
-	if c.cfg.AutoSyncInterval == time.Duration(0) {
-		return
-	}
-
-	for {
-		select {
-		case <-c.ctx.Done():
-			return
-		case <-time.After(c.cfg.AutoSyncInterval):
-			ctx, cancel := context.WithTimeout(c.ctx, 5*time.Second)
-			err := c.Sync(ctx)
-			cancel()
-			if err != nil && err != c.ctx.Err() {
-				logger.Println("Auto sync endpoints failed:", err)
-			}
-		}
-	}
-}
-
-type authTokenCredential struct {
-	token   string
-	tokenMu *sync.RWMutex
-}
-
-func (cred authTokenCredential) RequireTransportSecurity() bool {
-	return false
-}
-
-func (cred authTokenCredential) GetRequestMetadata(ctx context.Context, s ...string) (map[string]string, error) {
-	cred.tokenMu.RLock()
-	defer cred.tokenMu.RUnlock()
-	return map[string]string{
-		"token": cred.token,
-	}, nil
-}
-
-func parseEndpoint(endpoint string) (proto string, host string, scheme string) {
-	proto = "tcp"
-	host = endpoint
-	url, uerr := url.Parse(endpoint)
-	if uerr != nil || !strings.Contains(endpoint, "://") {
-		return proto, host, scheme
-	}
-	scheme = url.Scheme
-
-	// strip scheme:// prefix since grpc dials by host
-	host = url.Host
-	switch url.Scheme {
-	case "http", "https":
-	case "unix", "unixs":
-		proto = "unix"
-		host = url.Host + url.Path
-	default:
-		proto, host = "", ""
-	}
-	return proto, host, scheme
-}
-
-func (c *Client) processCreds(scheme string) (creds *credentials.TransportCredentials) {
-	creds = c.creds
-	switch scheme {
-	case "unix":
-	case "http":
-		creds = nil
-	case "https", "unixs":
-		if creds != nil {
-			break
-		}
-		tlsconfig := &tls.Config{}
-		emptyCreds := credentials.NewTLS(tlsconfig)
-		creds = &emptyCreds
-	default:
-		creds = nil
-	}
-	return creds
-}
-
-// dialSetupOpts gives the dial opts prior to any authentication
-func (c *Client) dialSetupOpts(endpoint string, dopts ...grpc.DialOption) (opts []grpc.DialOption) {
-	if c.cfg.DialTimeout > 0 {
-		opts = []grpc.DialOption{grpc.WithTimeout(c.cfg.DialTimeout)}
-	}
-	if c.cfg.DialKeepAliveTime > 0 {
-		params := keepalive.ClientParameters{
-			Time:    c.cfg.DialKeepAliveTime,
-			Timeout: c.cfg.DialKeepAliveTimeout,
-		}
-		opts = append(opts, grpc.WithKeepaliveParams(params))
-	}
-	opts = append(opts, dopts...)
-
-	f := func(host string, t time.Duration) (net.Conn, error) {
-		proto, host, _ := parseEndpoint(c.balancer.endpoint(host))
-		if host == "" && endpoint != "" {
-			// dialing an endpoint not in the balancer; use
-			// endpoint passed into dial
-			proto, host, _ = parseEndpoint(endpoint)
-		}
-		if proto == "" {
-			return nil, fmt.Errorf("unknown scheme for %q", host)
-		}
-		select {
-		case <-c.ctx.Done():
-			return nil, c.ctx.Err()
-		default:
-		}
-		dialer := &net.Dialer{Timeout: t}
-		conn, err := dialer.DialContext(c.ctx, proto, host)
-		if err != nil {
-			select {
-			case c.dialerrc <- err:
-			default:
-			}
-		}
-		return conn, err
-	}
-	opts = append(opts, grpc.WithDialer(f))
-
-	creds := c.creds
-	if _, _, scheme := parseEndpoint(endpoint); len(scheme) != 0 {
-		creds = c.processCreds(scheme)
-	}
-	if creds != nil {
-		opts = append(opts, grpc.WithTransportCredentials(*creds))
-	} else {
-		opts = append(opts, grpc.WithInsecure())
-	}
-
-	return opts
-}
-
-// Dial connects to a single endpoint using the client's config.
-func (c *Client) Dial(endpoint string) (*grpc.ClientConn, error) {
-	return c.dial(endpoint)
-}
-
-func (c *Client) getToken(ctx context.Context) error {
-	var err error // return last error in a case of fail
-	var auth *authenticator
-
-	for i := 0; i < len(c.cfg.Endpoints); i++ {
-		endpoint := c.cfg.Endpoints[i]
-		host := getHost(endpoint)
-		// use dial options without dopts to avoid reusing the client balancer
-		auth, err = newAuthenticator(host, c.dialSetupOpts(endpoint), c)
-		if err != nil {
-			continue
-		}
-		defer auth.close()
-
-		var resp *AuthenticateResponse
-		resp, err = auth.authenticate(ctx, c.Username, c.Password)
-		if err != nil {
-			continue
-		}
-
-		c.tokenCred.tokenMu.Lock()
-		c.tokenCred.token = resp.Token
-		c.tokenCred.tokenMu.Unlock()
-
-		return nil
-	}
-
-	return err
-}
-
-func (c *Client) dial(endpoint string, dopts ...grpc.DialOption) (*grpc.ClientConn, error) {
-	opts := c.dialSetupOpts(endpoint, dopts...)
-	host := getHost(endpoint)
-	if c.Username != "" && c.Password != "" {
-		c.tokenCred = &authTokenCredential{
-			tokenMu: &sync.RWMutex{},
-		}
-
-		ctx := c.ctx
-		if c.cfg.DialTimeout > 0 {
-			cctx, cancel := context.WithTimeout(ctx, c.cfg.DialTimeout)
-			defer cancel()
-			ctx = cctx
-		}
-
-		err := c.getToken(ctx)
-		if err != nil {
-			if toErr(ctx, err) != rpctypes.ErrAuthNotEnabled {
-				if err == ctx.Err() && ctx.Err() != c.ctx.Err() {
-					err = context.DeadlineExceeded
-				}
-				return nil, err
-			}
-		} else {
-			opts = append(opts, grpc.WithPerRPCCredentials(c.tokenCred))
-		}
-	}
-
-	opts = append(opts, c.cfg.DialOptions...)
-
-	conn, err := grpc.DialContext(c.ctx, host, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return conn, nil
-}
-
-// WithRequireLeader requires client requests to only succeed
-// when the cluster has a leader.
-func WithRequireLeader(ctx context.Context) context.Context {
-	md := metadata.Pairs(rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader)
-	return metadata.NewOutgoingContext(ctx, md)
-}
-
-func newClient(cfg *Config) (*Client, error) {
-	if cfg == nil {
-		cfg = &Config{}
-	}
-	var creds *credentials.TransportCredentials
-	if cfg.TLS != nil {
-		c := credentials.NewTLS(cfg.TLS)
-		creds = &c
-	}
-
-	// use a temporary skeleton client to bootstrap first connection
-	baseCtx := context.TODO()
-	if cfg.Context != nil {
-		baseCtx = cfg.Context
-	}
-
-	ctx, cancel := context.WithCancel(baseCtx)
-	client := &Client{
-		conn:     nil,
-		dialerrc: make(chan error, 1),
-		cfg:      *cfg,
-		creds:    creds,
-		ctx:      ctx,
-		cancel:   cancel,
-		mu:       new(sync.Mutex),
-		callOpts: defaultCallOpts,
-	}
-	if cfg.Username != "" && cfg.Password != "" {
-		client.Username = cfg.Username
-		client.Password = cfg.Password
-	}
-	if cfg.MaxCallSendMsgSize > 0 || cfg.MaxCallRecvMsgSize > 0 {
-		if cfg.MaxCallRecvMsgSize > 0 && cfg.MaxCallSendMsgSize > cfg.MaxCallRecvMsgSize {
-			return nil, fmt.Errorf("gRPC message recv limit (%d bytes) must be greater than send limit (%d bytes)", cfg.MaxCallRecvMsgSize, cfg.MaxCallSendMsgSize)
-		}
-		callOpts := []grpc.CallOption{
-			defaultFailFast,
-			defaultMaxCallSendMsgSize,
-			defaultMaxCallRecvMsgSize,
-		}
-		if cfg.MaxCallSendMsgSize > 0 {
-			callOpts[1] = grpc.MaxCallSendMsgSize(cfg.MaxCallSendMsgSize)
-		}
-		if cfg.MaxCallRecvMsgSize > 0 {
-			callOpts[2] = grpc.MaxCallRecvMsgSize(cfg.MaxCallRecvMsgSize)
-		}
-		client.callOpts = callOpts
-	}
-
-	client.balancer = newHealthBalancer(cfg.Endpoints, cfg.DialTimeout, func(ep string) (bool, error) {
-		return grpcHealthCheck(client, ep)
-	})
-
-	// use Endpoints[0] so that for https:// without any tls config given, then
-	// grpc will assume the certificate server name is the endpoint host.
-	conn, err := client.dial(cfg.Endpoints[0], grpc.WithBalancer(client.balancer))
-	if err != nil {
-		client.cancel()
-		client.balancer.Close()
-		return nil, err
-	}
-	client.conn = conn
-
-	// wait for a connection
-	if cfg.DialTimeout > 0 {
-		hasConn := false
-		waitc := time.After(cfg.DialTimeout)
-		select {
-		case <-client.balancer.ready():
-			hasConn = true
-		case <-ctx.Done():
-		case <-waitc:
-		}
-		if !hasConn {
-			err := context.DeadlineExceeded
-			select {
-			case err = <-client.dialerrc:
-			default:
-			}
-			client.cancel()
-			client.balancer.Close()
-			conn.Close()
-			return nil, err
-		}
-	}
-
-	client.Cluster = NewCluster(client)
-	client.KV = NewKV(client)
-	client.Lease = NewLease(client)
-	client.Watcher = NewWatcher(client)
-	client.Auth = NewAuth(client)
-	client.Maintenance = NewMaintenance(client)
-
-	if cfg.RejectOldCluster {
-		if err := client.checkVersion(); err != nil {
-			client.Close()
-			return nil, err
-		}
-	}
-
-	go client.autoSync()
-	return client, nil
-}
-
-func (c *Client) checkVersion() (err error) {
-	var wg sync.WaitGroup
-	errc := make(chan error, len(c.cfg.Endpoints))
-	ctx, cancel := context.WithCancel(c.ctx)
-	if c.cfg.DialTimeout > 0 {
-		ctx, cancel = context.WithTimeout(ctx, c.cfg.DialTimeout)
-	}
-	wg.Add(len(c.cfg.Endpoints))
-	for _, ep := range c.cfg.Endpoints {
-		// if cluster is current, any endpoint gives a recent version
-		go func(e string) {
-			defer wg.Done()
-			resp, rerr := c.Status(ctx, e)
-			if rerr != nil {
-				errc <- rerr
-				return
-			}
-			vs := strings.Split(resp.Version, ".")
-			maj, min := 0, 0
-			if len(vs) >= 2 {
-				maj, _ = strconv.Atoi(vs[0])
-				min, rerr = strconv.Atoi(vs[1])
-			}
-			if maj < 3 || (maj == 3 && min < 2) {
-				rerr = ErrOldCluster
-			}
-			errc <- rerr
-		}(ep)
-	}
-	// wait for success
-	for i := 0; i < len(c.cfg.Endpoints); i++ {
-		if err = <-errc; err == nil {
-			break
-		}
-	}
-	cancel()
-	wg.Wait()
-	return err
-}
-
-// ActiveConnection returns the current in-use connection
-func (c *Client) ActiveConnection() *grpc.ClientConn { return c.conn }
-
-// isHaltErr returns true if the given error and context indicate no forward
-// progress can be made, even after reconnecting.
-func isHaltErr(ctx context.Context, err error) bool {
-	if ctx != nil && ctx.Err() != nil {
-		return true
-	}
-	if err == nil {
-		return false
-	}
-	ev, _ := status.FromError(err)
-	// Unavailable codes mean the system will be right back.
-	// (e.g., can't connect, lost leader)
-	// Treat Internal codes as if something failed, leaving the
-	// system in an inconsistent state, but retrying could make progress.
-	// (e.g., failed in middle of send, corrupted frame)
-	// TODO: are permanent Internal errors possible from grpc?
-	return ev.Code() != codes.Unavailable && ev.Code() != codes.Internal
-}
-
-// isUnavailableErr returns true if the given error is an unavailable error
-func isUnavailableErr(ctx context.Context, err error) bool {
-	if ctx != nil && ctx.Err() != nil {
-		return false
-	}
-	if err == nil {
-		return false
-	}
-	ev, _ := status.FromError(err)
-	// Unavailable codes mean the system will be right back.
-	// (e.g., can't connect, lost leader)
-	return ev.Code() == codes.Unavailable
-}
-
-func toErr(ctx context.Context, err error) error {
-	if err == nil {
-		return nil
-	}
-	err = rpctypes.Error(err)
-	if _, ok := err.(rpctypes.EtcdError); ok {
-		return err
-	}
-	ev, _ := status.FromError(err)
-	code := ev.Code()
-	switch code {
-	case codes.DeadlineExceeded:
-		fallthrough
-	case codes.Canceled:
-		if ctx.Err() != nil {
-			err = ctx.Err()
-		}
-	case codes.Unavailable:
-	case codes.FailedPrecondition:
-		err = grpc.ErrClientConnClosing
-	}
-	return err
-}
-
-func canceledByCaller(stopCtx context.Context, err error) bool {
-	if stopCtx.Err() == nil || err == nil {
-		return false
-	}
-
-	return err == context.Canceled || err == context.DeadlineExceeded
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/cluster.go b/vendor/github.com/coreos/etcd/clientv3/cluster.go
deleted file mode 100644
index 785672b..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/cluster.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/pkg/types"
-
-	"google.golang.org/grpc"
-)
-
-type (
-	Member               pb.Member
-	MemberListResponse   pb.MemberListResponse
-	MemberAddResponse    pb.MemberAddResponse
-	MemberRemoveResponse pb.MemberRemoveResponse
-	MemberUpdateResponse pb.MemberUpdateResponse
-)
-
-type Cluster interface {
-	// MemberList lists the current cluster membership.
-	MemberList(ctx context.Context) (*MemberListResponse, error)
-
-	// MemberAdd adds a new member into the cluster.
-	MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error)
-
-	// MemberRemove removes an existing member from the cluster.
-	MemberRemove(ctx context.Context, id uint64) (*MemberRemoveResponse, error)
-
-	// MemberUpdate updates the peer addresses of the member.
-	MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error)
-}
-
-type cluster struct {
-	remote   pb.ClusterClient
-	callOpts []grpc.CallOption
-}
-
-func NewCluster(c *Client) Cluster {
-	api := &cluster{remote: RetryClusterClient(c)}
-	if c != nil {
-		api.callOpts = c.callOpts
-	}
-	return api
-}
-
-func NewClusterFromClusterClient(remote pb.ClusterClient, c *Client) Cluster {
-	api := &cluster{remote: remote}
-	if c != nil {
-		api.callOpts = c.callOpts
-	}
-	return api
-}
-
-func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) {
-	// fail-fast before panic in rafthttp
-	if _, err := types.NewURLs(peerAddrs); err != nil {
-		return nil, err
-	}
-
-	r := &pb.MemberAddRequest{PeerURLs: peerAddrs}
-	resp, err := c.remote.MemberAdd(ctx, r, c.callOpts...)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-	return (*MemberAddResponse)(resp), nil
-}
-
-func (c *cluster) MemberRemove(ctx context.Context, id uint64) (*MemberRemoveResponse, error) {
-	r := &pb.MemberRemoveRequest{ID: id}
-	resp, err := c.remote.MemberRemove(ctx, r, c.callOpts...)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-	return (*MemberRemoveResponse)(resp), nil
-}
-
-func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error) {
-	// fail-fast before panic in rafthttp
-	if _, err := types.NewURLs(peerAddrs); err != nil {
-		return nil, err
-	}
-
-	// it is safe to retry on update.
-	r := &pb.MemberUpdateRequest{ID: id, PeerURLs: peerAddrs}
-	resp, err := c.remote.MemberUpdate(ctx, r, c.callOpts...)
-	if err == nil {
-		return (*MemberUpdateResponse)(resp), nil
-	}
-	return nil, toErr(ctx, err)
-}
-
-func (c *cluster) MemberList(ctx context.Context) (*MemberListResponse, error) {
-	// it is safe to retry on list.
-	resp, err := c.remote.MemberList(ctx, &pb.MemberListRequest{}, c.callOpts...)
-	if err == nil {
-		return (*MemberListResponse)(resp), nil
-	}
-	return nil, toErr(ctx, err)
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/compact_op.go b/vendor/github.com/coreos/etcd/clientv3/compact_op.go
deleted file mode 100644
index 41e80c1..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/compact_op.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-// CompactOp represents a compact operation.
-type CompactOp struct {
-	revision int64
-	physical bool
-}
-
-// CompactOption configures compact operation.
-type CompactOption func(*CompactOp)
-
-func (op *CompactOp) applyCompactOpts(opts []CompactOption) {
-	for _, opt := range opts {
-		opt(op)
-	}
-}
-
-// OpCompact wraps slice CompactOption to create a CompactOp.
-func OpCompact(rev int64, opts ...CompactOption) CompactOp {
-	ret := CompactOp{revision: rev}
-	ret.applyCompactOpts(opts)
-	return ret
-}
-
-func (op CompactOp) toRequest() *pb.CompactionRequest {
-	return &pb.CompactionRequest{Revision: op.revision, Physical: op.physical}
-}
-
-// WithCompactPhysical makes Compact wait until all compacted entries are
-// removed from the etcd server's storage.
-func WithCompactPhysical() CompactOption {
-	return func(op *CompactOp) { op.physical = true }
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/compare.go b/vendor/github.com/coreos/etcd/clientv3/compare.go
deleted file mode 100644
index b5f0a25..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/compare.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-type CompareTarget int
-type CompareResult int
-
-const (
-	CompareVersion CompareTarget = iota
-	CompareCreated
-	CompareModified
-	CompareValue
-)
-
-type Cmp pb.Compare
-
-func Compare(cmp Cmp, result string, v interface{}) Cmp {
-	var r pb.Compare_CompareResult
-
-	switch result {
-	case "=":
-		r = pb.Compare_EQUAL
-	case "!=":
-		r = pb.Compare_NOT_EQUAL
-	case ">":
-		r = pb.Compare_GREATER
-	case "<":
-		r = pb.Compare_LESS
-	default:
-		panic("Unknown result op")
-	}
-
-	cmp.Result = r
-	switch cmp.Target {
-	case pb.Compare_VALUE:
-		val, ok := v.(string)
-		if !ok {
-			panic("bad compare value")
-		}
-		cmp.TargetUnion = &pb.Compare_Value{Value: []byte(val)}
-	case pb.Compare_VERSION:
-		cmp.TargetUnion = &pb.Compare_Version{Version: mustInt64(v)}
-	case pb.Compare_CREATE:
-		cmp.TargetUnion = &pb.Compare_CreateRevision{CreateRevision: mustInt64(v)}
-	case pb.Compare_MOD:
-		cmp.TargetUnion = &pb.Compare_ModRevision{ModRevision: mustInt64(v)}
-	case pb.Compare_LEASE:
-		cmp.TargetUnion = &pb.Compare_Lease{Lease: mustInt64orLeaseID(v)}
-	default:
-		panic("Unknown compare type")
-	}
-	return cmp
-}
-
-func Value(key string) Cmp {
-	return Cmp{Key: []byte(key), Target: pb.Compare_VALUE}
-}
-
-func Version(key string) Cmp {
-	return Cmp{Key: []byte(key), Target: pb.Compare_VERSION}
-}
-
-func CreateRevision(key string) Cmp {
-	return Cmp{Key: []byte(key), Target: pb.Compare_CREATE}
-}
-
-func ModRevision(key string) Cmp {
-	return Cmp{Key: []byte(key), Target: pb.Compare_MOD}
-}
-
-// LeaseValue compares a key's LeaseID to a value of your choosing. The empty
-// LeaseID is 0, otherwise known as `NoLease`.
-func LeaseValue(key string) Cmp {
-	return Cmp{Key: []byte(key), Target: pb.Compare_LEASE}
-}
-
-// KeyBytes returns the byte slice holding with the comparison key.
-func (cmp *Cmp) KeyBytes() []byte { return cmp.Key }
-
-// WithKeyBytes sets the byte slice for the comparison key.
-func (cmp *Cmp) WithKeyBytes(key []byte) { cmp.Key = key }
-
-// ValueBytes returns the byte slice holding the comparison value, if any.
-func (cmp *Cmp) ValueBytes() []byte {
-	if tu, ok := cmp.TargetUnion.(*pb.Compare_Value); ok {
-		return tu.Value
-	}
-	return nil
-}
-
-// WithValueBytes sets the byte slice for the comparison's value.
-func (cmp *Cmp) WithValueBytes(v []byte) { cmp.TargetUnion.(*pb.Compare_Value).Value = v }
-
-// WithRange sets the comparison to scan the range [key, end).
-func (cmp Cmp) WithRange(end string) Cmp {
-	cmp.RangeEnd = []byte(end)
-	return cmp
-}
-
-// WithPrefix sets the comparison to scan all keys prefixed by the key.
-func (cmp Cmp) WithPrefix() Cmp {
-	cmp.RangeEnd = getPrefix(cmp.Key)
-	return cmp
-}
-
-// mustInt64 panics if val isn't an int or int64. It returns an int64 otherwise.
-func mustInt64(val interface{}) int64 {
-	if v, ok := val.(int64); ok {
-		return v
-	}
-	if v, ok := val.(int); ok {
-		return int64(v)
-	}
-	panic("bad value")
-}
-
-// mustInt64orLeaseID panics if val isn't a LeaseID, int or int64. It returns an
-// int64 otherwise.
-func mustInt64orLeaseID(val interface{}) int64 {
-	if v, ok := val.(LeaseID); ok {
-		return int64(v)
-	}
-	return mustInt64(val)
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/concurrency/doc.go b/vendor/github.com/coreos/etcd/clientv3/concurrency/doc.go
deleted file mode 100644
index dcdbf51..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/concurrency/doc.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package concurrency implements concurrency operations on top of
-// etcd such as distributed locks, barriers, and elections.
-package concurrency
diff --git a/vendor/github.com/coreos/etcd/clientv3/concurrency/election.go b/vendor/github.com/coreos/etcd/clientv3/concurrency/election.go
deleted file mode 100644
index e18a0ed..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/concurrency/election.go
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package concurrency
-
-import (
-	"context"
-	"errors"
-	"fmt"
-
-	v3 "github.com/coreos/etcd/clientv3"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-var (
-	ErrElectionNotLeader = errors.New("election: not leader")
-	ErrElectionNoLeader  = errors.New("election: no leader")
-)
-
-type Election struct {
-	session *Session
-
-	keyPrefix string
-
-	leaderKey     string
-	leaderRev     int64
-	leaderSession *Session
-	hdr           *pb.ResponseHeader
-}
-
-// NewElection returns a new election on a given key prefix.
-func NewElection(s *Session, pfx string) *Election {
-	return &Election{session: s, keyPrefix: pfx + "/"}
-}
-
-// ResumeElection initializes an election with a known leader.
-func ResumeElection(s *Session, pfx string, leaderKey string, leaderRev int64) *Election {
-	return &Election{
-		session:       s,
-		leaderKey:     leaderKey,
-		leaderRev:     leaderRev,
-		leaderSession: s,
-	}
-}
-
-// Campaign puts a value as eligible for the election. It blocks until
-// it is elected, an error occurs, or the context is cancelled.
-func (e *Election) Campaign(ctx context.Context, val string) error {
-	s := e.session
-	client := e.session.Client()
-
-	k := fmt.Sprintf("%s%x", e.keyPrefix, s.Lease())
-	txn := client.Txn(ctx).If(v3.Compare(v3.CreateRevision(k), "=", 0))
-	txn = txn.Then(v3.OpPut(k, val, v3.WithLease(s.Lease())))
-	txn = txn.Else(v3.OpGet(k))
-	resp, err := txn.Commit()
-	if err != nil {
-		return err
-	}
-	e.leaderKey, e.leaderRev, e.leaderSession = k, resp.Header.Revision, s
-	if !resp.Succeeded {
-		kv := resp.Responses[0].GetResponseRange().Kvs[0]
-		e.leaderRev = kv.CreateRevision
-		if string(kv.Value) != val {
-			if err = e.Proclaim(ctx, val); err != nil {
-				e.Resign(ctx)
-				return err
-			}
-		}
-	}
-
-	_, err = waitDeletes(ctx, client, e.keyPrefix, e.leaderRev-1)
-	if err != nil {
-		// clean up in case of context cancel
-		select {
-		case <-ctx.Done():
-			e.Resign(client.Ctx())
-		default:
-			e.leaderSession = nil
-		}
-		return err
-	}
-	e.hdr = resp.Header
-
-	return nil
-}
-
-// Proclaim lets the leader announce a new value without another election.
-func (e *Election) Proclaim(ctx context.Context, val string) error {
-	if e.leaderSession == nil {
-		return ErrElectionNotLeader
-	}
-	client := e.session.Client()
-	cmp := v3.Compare(v3.CreateRevision(e.leaderKey), "=", e.leaderRev)
-	txn := client.Txn(ctx).If(cmp)
-	txn = txn.Then(v3.OpPut(e.leaderKey, val, v3.WithLease(e.leaderSession.Lease())))
-	tresp, terr := txn.Commit()
-	if terr != nil {
-		return terr
-	}
-	if !tresp.Succeeded {
-		e.leaderKey = ""
-		return ErrElectionNotLeader
-	}
-
-	e.hdr = tresp.Header
-	return nil
-}
-
-// Resign lets a leader start a new election.
-func (e *Election) Resign(ctx context.Context) (err error) {
-	if e.leaderSession == nil {
-		return nil
-	}
-	client := e.session.Client()
-	cmp := v3.Compare(v3.CreateRevision(e.leaderKey), "=", e.leaderRev)
-	resp, err := client.Txn(ctx).If(cmp).Then(v3.OpDelete(e.leaderKey)).Commit()
-	if err == nil {
-		e.hdr = resp.Header
-	}
-	e.leaderKey = ""
-	e.leaderSession = nil
-	return err
-}
-
-// Leader returns the leader value for the current election.
-func (e *Election) Leader(ctx context.Context) (*v3.GetResponse, error) {
-	client := e.session.Client()
-	resp, err := client.Get(ctx, e.keyPrefix, v3.WithFirstCreate()...)
-	if err != nil {
-		return nil, err
-	} else if len(resp.Kvs) == 0 {
-		// no leader currently elected
-		return nil, ErrElectionNoLeader
-	}
-	return resp, nil
-}
-
-// Observe returns a channel that reliably observes ordered leader proposals
-// as GetResponse values on every current elected leader key. It will not
-// necessarily fetch all historical leader updates, but will always post the
-// most recent leader value.
-//
-// The channel closes when the context is canceled or the underlying watcher
-// is otherwise disrupted.
-func (e *Election) Observe(ctx context.Context) <-chan v3.GetResponse {
-	retc := make(chan v3.GetResponse)
-	go e.observe(ctx, retc)
-	return retc
-}
-
-func (e *Election) observe(ctx context.Context, ch chan<- v3.GetResponse) {
-	client := e.session.Client()
-
-	defer close(ch)
-	for {
-		resp, err := client.Get(ctx, e.keyPrefix, v3.WithFirstCreate()...)
-		if err != nil {
-			return
-		}
-
-		var kv *mvccpb.KeyValue
-		var hdr *pb.ResponseHeader
-
-		if len(resp.Kvs) == 0 {
-			cctx, cancel := context.WithCancel(ctx)
-			// wait for first key put on prefix
-			opts := []v3.OpOption{v3.WithRev(resp.Header.Revision), v3.WithPrefix()}
-			wch := client.Watch(cctx, e.keyPrefix, opts...)
-			for kv == nil {
-				wr, ok := <-wch
-				if !ok || wr.Err() != nil {
-					cancel()
-					return
-				}
-				// only accept puts; a delete will make observe() spin
-				for _, ev := range wr.Events {
-					if ev.Type == mvccpb.PUT {
-						hdr, kv = &wr.Header, ev.Kv
-						// may have multiple revs; hdr.rev = the last rev
-						// set to kv's rev in case batch has multiple Puts
-						hdr.Revision = kv.ModRevision
-						break
-					}
-				}
-			}
-			cancel()
-		} else {
-			hdr, kv = resp.Header, resp.Kvs[0]
-		}
-
-		select {
-		case ch <- v3.GetResponse{Header: hdr, Kvs: []*mvccpb.KeyValue{kv}}:
-		case <-ctx.Done():
-			return
-		}
-
-		cctx, cancel := context.WithCancel(ctx)
-		wch := client.Watch(cctx, string(kv.Key), v3.WithRev(hdr.Revision+1))
-		keyDeleted := false
-		for !keyDeleted {
-			wr, ok := <-wch
-			if !ok {
-				cancel()
-				return
-			}
-			for _, ev := range wr.Events {
-				if ev.Type == mvccpb.DELETE {
-					keyDeleted = true
-					break
-				}
-				resp.Header = &wr.Header
-				resp.Kvs = []*mvccpb.KeyValue{ev.Kv}
-				select {
-				case ch <- *resp:
-				case <-cctx.Done():
-					cancel()
-					return
-				}
-			}
-		}
-		cancel()
-	}
-}
-
-// Key returns the leader key if elected, empty string otherwise.
-func (e *Election) Key() string { return e.leaderKey }
-
-// Rev returns the leader key's creation revision, if elected.
-func (e *Election) Rev() int64 { return e.leaderRev }
-
-// Header is the response header from the last successful election proposal.
-func (e *Election) Header() *pb.ResponseHeader { return e.hdr }
diff --git a/vendor/github.com/coreos/etcd/clientv3/concurrency/key.go b/vendor/github.com/coreos/etcd/clientv3/concurrency/key.go
deleted file mode 100644
index 4b6e399..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/concurrency/key.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package concurrency
-
-import (
-	"context"
-	"fmt"
-
-	v3 "github.com/coreos/etcd/clientv3"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-func waitDelete(ctx context.Context, client *v3.Client, key string, rev int64) error {
-	cctx, cancel := context.WithCancel(ctx)
-	defer cancel()
-
-	var wr v3.WatchResponse
-	wch := client.Watch(cctx, key, v3.WithRev(rev))
-	for wr = range wch {
-		for _, ev := range wr.Events {
-			if ev.Type == mvccpb.DELETE {
-				return nil
-			}
-		}
-	}
-	if err := wr.Err(); err != nil {
-		return err
-	}
-	if err := ctx.Err(); err != nil {
-		return err
-	}
-	return fmt.Errorf("lost watcher waiting for delete")
-}
-
-// waitDeletes efficiently waits until all keys matching the prefix and no greater
-// than the create revision.
-func waitDeletes(ctx context.Context, client *v3.Client, pfx string, maxCreateRev int64) (*pb.ResponseHeader, error) {
-	getOpts := append(v3.WithLastCreate(), v3.WithMaxCreateRev(maxCreateRev))
-	for {
-		resp, err := client.Get(ctx, pfx, getOpts...)
-		if err != nil {
-			return nil, err
-		}
-		if len(resp.Kvs) == 0 {
-			return resp.Header, nil
-		}
-		lastKey := string(resp.Kvs[0].Key)
-		if err = waitDelete(ctx, client, lastKey, resp.Header.Revision); err != nil {
-			return nil, err
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/concurrency/mutex.go b/vendor/github.com/coreos/etcd/clientv3/concurrency/mutex.go
deleted file mode 100644
index 77b3582..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/concurrency/mutex.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package concurrency
-
-import (
-	"context"
-	"fmt"
-	"sync"
-
-	v3 "github.com/coreos/etcd/clientv3"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-// Mutex implements the sync Locker interface with etcd
-type Mutex struct {
-	s *Session
-
-	pfx   string
-	myKey string
-	myRev int64
-	hdr   *pb.ResponseHeader
-}
-
-func NewMutex(s *Session, pfx string) *Mutex {
-	return &Mutex{s, pfx + "/", "", -1, nil}
-}
-
-// Lock locks the mutex with a cancelable context. If the context is canceled
-// while trying to acquire the lock, the mutex tries to clean its stale lock entry.
-func (m *Mutex) Lock(ctx context.Context) error {
-	s := m.s
-	client := m.s.Client()
-
-	m.myKey = fmt.Sprintf("%s%x", m.pfx, s.Lease())
-	cmp := v3.Compare(v3.CreateRevision(m.myKey), "=", 0)
-	// put self in lock waiters via myKey; oldest waiter holds lock
-	put := v3.OpPut(m.myKey, "", v3.WithLease(s.Lease()))
-	// reuse key in case this session already holds the lock
-	get := v3.OpGet(m.myKey)
-	// fetch current holder to complete uncontended path with only one RPC
-	getOwner := v3.OpGet(m.pfx, v3.WithFirstCreate()...)
-	resp, err := client.Txn(ctx).If(cmp).Then(put, getOwner).Else(get, getOwner).Commit()
-	if err != nil {
-		return err
-	}
-	m.myRev = resp.Header.Revision
-	if !resp.Succeeded {
-		m.myRev = resp.Responses[0].GetResponseRange().Kvs[0].CreateRevision
-	}
-	// if no key on prefix / the minimum rev is key, already hold the lock
-	ownerKey := resp.Responses[1].GetResponseRange().Kvs
-	if len(ownerKey) == 0 || ownerKey[0].CreateRevision == m.myRev {
-		m.hdr = resp.Header
-		return nil
-	}
-
-	// wait for deletion revisions prior to myKey
-	hdr, werr := waitDeletes(ctx, client, m.pfx, m.myRev-1)
-	// release lock key if wait failed
-	if werr != nil {
-		m.Unlock(client.Ctx())
-	} else {
-		m.hdr = hdr
-	}
-	return werr
-}
-
-func (m *Mutex) Unlock(ctx context.Context) error {
-	client := m.s.Client()
-	if _, err := client.Delete(ctx, m.myKey); err != nil {
-		return err
-	}
-	m.myKey = "\x00"
-	m.myRev = -1
-	return nil
-}
-
-func (m *Mutex) IsOwner() v3.Cmp {
-	return v3.Compare(v3.CreateRevision(m.myKey), "=", m.myRev)
-}
-
-func (m *Mutex) Key() string { return m.myKey }
-
-// Header is the response header received from etcd on acquiring the lock.
-func (m *Mutex) Header() *pb.ResponseHeader { return m.hdr }
-
-type lockerMutex struct{ *Mutex }
-
-func (lm *lockerMutex) Lock() {
-	client := lm.s.Client()
-	if err := lm.Mutex.Lock(client.Ctx()); err != nil {
-		panic(err)
-	}
-}
-func (lm *lockerMutex) Unlock() {
-	client := lm.s.Client()
-	if err := lm.Mutex.Unlock(client.Ctx()); err != nil {
-		panic(err)
-	}
-}
-
-// NewLocker creates a sync.Locker backed by an etcd mutex.
-func NewLocker(s *Session, pfx string) sync.Locker {
-	return &lockerMutex{NewMutex(s, pfx)}
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/concurrency/session.go b/vendor/github.com/coreos/etcd/clientv3/concurrency/session.go
deleted file mode 100644
index c399d64..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/concurrency/session.go
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package concurrency
-
-import (
-	"context"
-	"time"
-
-	v3 "github.com/coreos/etcd/clientv3"
-)
-
-const defaultSessionTTL = 60
-
-// Session represents a lease kept alive for the lifetime of a client.
-// Fault-tolerant applications may use sessions to reason about liveness.
-type Session struct {
-	client *v3.Client
-	opts   *sessionOptions
-	id     v3.LeaseID
-
-	cancel context.CancelFunc
-	donec  <-chan struct{}
-}
-
-// NewSession gets the leased session for a client.
-func NewSession(client *v3.Client, opts ...SessionOption) (*Session, error) {
-	ops := &sessionOptions{ttl: defaultSessionTTL, ctx: client.Ctx()}
-	for _, opt := range opts {
-		opt(ops)
-	}
-
-	id := ops.leaseID
-	if id == v3.NoLease {
-		resp, err := client.Grant(ops.ctx, int64(ops.ttl))
-		if err != nil {
-			return nil, err
-		}
-		id = v3.LeaseID(resp.ID)
-	}
-
-	ctx, cancel := context.WithCancel(ops.ctx)
-	keepAlive, err := client.KeepAlive(ctx, id)
-	if err != nil || keepAlive == nil {
-		cancel()
-		return nil, err
-	}
-
-	donec := make(chan struct{})
-	s := &Session{client: client, opts: ops, id: id, cancel: cancel, donec: donec}
-
-	// keep the lease alive until client error or cancelled context
-	go func() {
-		defer close(donec)
-		for range keepAlive {
-			// eat messages until keep alive channel closes
-		}
-	}()
-
-	return s, nil
-}
-
-// Client is the etcd client that is attached to the session.
-func (s *Session) Client() *v3.Client {
-	return s.client
-}
-
-// Lease is the lease ID for keys bound to the session.
-func (s *Session) Lease() v3.LeaseID { return s.id }
-
-// Done returns a channel that closes when the lease is orphaned, expires, or
-// is otherwise no longer being refreshed.
-func (s *Session) Done() <-chan struct{} { return s.donec }
-
-// Orphan ends the refresh for the session lease. This is useful
-// in case the state of the client connection is indeterminate (revoke
-// would fail) or when transferring lease ownership.
-func (s *Session) Orphan() {
-	s.cancel()
-	<-s.donec
-}
-
-// Close orphans the session and revokes the session lease.
-func (s *Session) Close() error {
-	s.Orphan()
-	// if revoke takes longer than the ttl, lease is expired anyway
-	ctx, cancel := context.WithTimeout(s.opts.ctx, time.Duration(s.opts.ttl)*time.Second)
-	_, err := s.client.Revoke(ctx, s.id)
-	cancel()
-	return err
-}
-
-type sessionOptions struct {
-	ttl     int
-	leaseID v3.LeaseID
-	ctx     context.Context
-}
-
-// SessionOption configures Session.
-type SessionOption func(*sessionOptions)
-
-// WithTTL configures the session's TTL in seconds.
-// If TTL is <= 0, the default 60 seconds TTL will be used.
-func WithTTL(ttl int) SessionOption {
-	return func(so *sessionOptions) {
-		if ttl > 0 {
-			so.ttl = ttl
-		}
-	}
-}
-
-// WithLease specifies the existing leaseID to be used for the session.
-// This is useful in process restart scenario, for example, to reclaim
-// leadership from an election prior to restart.
-func WithLease(leaseID v3.LeaseID) SessionOption {
-	return func(so *sessionOptions) {
-		so.leaseID = leaseID
-	}
-}
-
-// WithContext assigns a context to the session instead of defaulting to
-// using the client context. This is useful for canceling NewSession and
-// Close operations immediately without having to close the client. If the
-// context is canceled before Close() completes, the session's lease will be
-// abandoned and left to expire instead of being revoked.
-func WithContext(ctx context.Context) SessionOption {
-	return func(so *sessionOptions) {
-		so.ctx = ctx
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/concurrency/stm.go b/vendor/github.com/coreos/etcd/clientv3/concurrency/stm.go
deleted file mode 100644
index d11023e..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/concurrency/stm.go
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package concurrency
-
-import (
-	"context"
-	"math"
-
-	v3 "github.com/coreos/etcd/clientv3"
-)
-
-// STM is an interface for software transactional memory.
-type STM interface {
-	// Get returns the value for a key and inserts the key in the txn's read set.
-	// If Get fails, it aborts the transaction with an error, never returning.
-	Get(key ...string) string
-	// Put adds a value for a key to the write set.
-	Put(key, val string, opts ...v3.OpOption)
-	// Rev returns the revision of a key in the read set.
-	Rev(key string) int64
-	// Del deletes a key.
-	Del(key string)
-
-	// commit attempts to apply the txn's changes to the server.
-	commit() *v3.TxnResponse
-	reset()
-}
-
-// Isolation is an enumeration of transactional isolation levels which
-// describes how transactions should interfere and conflict.
-type Isolation int
-
-const (
-	// SerializableSnapshot provides serializable isolation and also checks
-	// for write conflicts.
-	SerializableSnapshot Isolation = iota
-	// Serializable reads within the same transaction attempt return data
-	// from the at the revision of the first read.
-	Serializable
-	// RepeatableReads reads within the same transaction attempt always
-	// return the same data.
-	RepeatableReads
-	// ReadCommitted reads keys from any committed revision.
-	ReadCommitted
-)
-
-// stmError safely passes STM errors through panic to the STM error channel.
-type stmError struct{ err error }
-
-type stmOptions struct {
-	iso      Isolation
-	ctx      context.Context
-	prefetch []string
-}
-
-type stmOption func(*stmOptions)
-
-// WithIsolation specifies the transaction isolation level.
-func WithIsolation(lvl Isolation) stmOption {
-	return func(so *stmOptions) { so.iso = lvl }
-}
-
-// WithAbortContext specifies the context for permanently aborting the transaction.
-func WithAbortContext(ctx context.Context) stmOption {
-	return func(so *stmOptions) { so.ctx = ctx }
-}
-
-// WithPrefetch is a hint to prefetch a list of keys before trying to apply.
-// If an STM transaction will unconditionally fetch a set of keys, prefetching
-// those keys will save the round-trip cost from requesting each key one by one
-// with Get().
-func WithPrefetch(keys ...string) stmOption {
-	return func(so *stmOptions) { so.prefetch = append(so.prefetch, keys...) }
-}
-
-// NewSTM initiates a new STM instance, using serializable snapshot isolation by default.
-func NewSTM(c *v3.Client, apply func(STM) error, so ...stmOption) (*v3.TxnResponse, error) {
-	opts := &stmOptions{ctx: c.Ctx()}
-	for _, f := range so {
-		f(opts)
-	}
-	if len(opts.prefetch) != 0 {
-		f := apply
-		apply = func(s STM) error {
-			s.Get(opts.prefetch...)
-			return f(s)
-		}
-	}
-	return runSTM(mkSTM(c, opts), apply)
-}
-
-func mkSTM(c *v3.Client, opts *stmOptions) STM {
-	switch opts.iso {
-	case SerializableSnapshot:
-		s := &stmSerializable{
-			stm:      stm{client: c, ctx: opts.ctx},
-			prefetch: make(map[string]*v3.GetResponse),
-		}
-		s.conflicts = func() []v3.Cmp {
-			return append(s.rset.cmps(), s.wset.cmps(s.rset.first()+1)...)
-		}
-		return s
-	case Serializable:
-		s := &stmSerializable{
-			stm:      stm{client: c, ctx: opts.ctx},
-			prefetch: make(map[string]*v3.GetResponse),
-		}
-		s.conflicts = func() []v3.Cmp { return s.rset.cmps() }
-		return s
-	case RepeatableReads:
-		s := &stm{client: c, ctx: opts.ctx, getOpts: []v3.OpOption{v3.WithSerializable()}}
-		s.conflicts = func() []v3.Cmp { return s.rset.cmps() }
-		return s
-	case ReadCommitted:
-		s := &stm{client: c, ctx: opts.ctx, getOpts: []v3.OpOption{v3.WithSerializable()}}
-		s.conflicts = func() []v3.Cmp { return nil }
-		return s
-	default:
-		panic("unsupported stm")
-	}
-}
-
-type stmResponse struct {
-	resp *v3.TxnResponse
-	err  error
-}
-
-func runSTM(s STM, apply func(STM) error) (*v3.TxnResponse, error) {
-	outc := make(chan stmResponse, 1)
-	go func() {
-		defer func() {
-			if r := recover(); r != nil {
-				e, ok := r.(stmError)
-				if !ok {
-					// client apply panicked
-					panic(r)
-				}
-				outc <- stmResponse{nil, e.err}
-			}
-		}()
-		var out stmResponse
-		for {
-			s.reset()
-			if out.err = apply(s); out.err != nil {
-				break
-			}
-			if out.resp = s.commit(); out.resp != nil {
-				break
-			}
-		}
-		outc <- out
-	}()
-	r := <-outc
-	return r.resp, r.err
-}
-
-// stm implements repeatable-read software transactional memory over etcd
-type stm struct {
-	client *v3.Client
-	ctx    context.Context
-	// rset holds read key values and revisions
-	rset readSet
-	// wset holds overwritten keys and their values
-	wset writeSet
-	// getOpts are the opts used for gets
-	getOpts []v3.OpOption
-	// conflicts computes the current conflicts on the txn
-	conflicts func() []v3.Cmp
-}
-
-type stmPut struct {
-	val string
-	op  v3.Op
-}
-
-type readSet map[string]*v3.GetResponse
-
-func (rs readSet) add(keys []string, txnresp *v3.TxnResponse) {
-	for i, resp := range txnresp.Responses {
-		rs[keys[i]] = (*v3.GetResponse)(resp.GetResponseRange())
-	}
-}
-
-// first returns the store revision from the first fetch
-func (rs readSet) first() int64 {
-	ret := int64(math.MaxInt64 - 1)
-	for _, resp := range rs {
-		if rev := resp.Header.Revision; rev < ret {
-			ret = rev
-		}
-	}
-	return ret
-}
-
-// cmps guards the txn from updates to read set
-func (rs readSet) cmps() []v3.Cmp {
-	cmps := make([]v3.Cmp, 0, len(rs))
-	for k, rk := range rs {
-		cmps = append(cmps, isKeyCurrent(k, rk))
-	}
-	return cmps
-}
-
-type writeSet map[string]stmPut
-
-func (ws writeSet) get(keys ...string) *stmPut {
-	for _, key := range keys {
-		if wv, ok := ws[key]; ok {
-			return &wv
-		}
-	}
-	return nil
-}
-
-// cmps returns a cmp list testing no writes have happened past rev
-func (ws writeSet) cmps(rev int64) []v3.Cmp {
-	cmps := make([]v3.Cmp, 0, len(ws))
-	for key := range ws {
-		cmps = append(cmps, v3.Compare(v3.ModRevision(key), "<", rev))
-	}
-	return cmps
-}
-
-// puts is the list of ops for all pending writes
-func (ws writeSet) puts() []v3.Op {
-	puts := make([]v3.Op, 0, len(ws))
-	for _, v := range ws {
-		puts = append(puts, v.op)
-	}
-	return puts
-}
-
-func (s *stm) Get(keys ...string) string {
-	if wv := s.wset.get(keys...); wv != nil {
-		return wv.val
-	}
-	return respToValue(s.fetch(keys...))
-}
-
-func (s *stm) Put(key, val string, opts ...v3.OpOption) {
-	s.wset[key] = stmPut{val, v3.OpPut(key, val, opts...)}
-}
-
-func (s *stm) Del(key string) { s.wset[key] = stmPut{"", v3.OpDelete(key)} }
-
-func (s *stm) Rev(key string) int64 {
-	if resp := s.fetch(key); resp != nil && len(resp.Kvs) != 0 {
-		return resp.Kvs[0].ModRevision
-	}
-	return 0
-}
-
-func (s *stm) commit() *v3.TxnResponse {
-	txnresp, err := s.client.Txn(s.ctx).If(s.conflicts()...).Then(s.wset.puts()...).Commit()
-	if err != nil {
-		panic(stmError{err})
-	}
-	if txnresp.Succeeded {
-		return txnresp
-	}
-	return nil
-}
-
-func (s *stm) fetch(keys ...string) *v3.GetResponse {
-	if len(keys) == 0 {
-		return nil
-	}
-	ops := make([]v3.Op, len(keys))
-	for i, key := range keys {
-		if resp, ok := s.rset[key]; ok {
-			return resp
-		}
-		ops[i] = v3.OpGet(key, s.getOpts...)
-	}
-	txnresp, err := s.client.Txn(s.ctx).Then(ops...).Commit()
-	if err != nil {
-		panic(stmError{err})
-	}
-	s.rset.add(keys, txnresp)
-	return (*v3.GetResponse)(txnresp.Responses[0].GetResponseRange())
-}
-
-func (s *stm) reset() {
-	s.rset = make(map[string]*v3.GetResponse)
-	s.wset = make(map[string]stmPut)
-}
-
-type stmSerializable struct {
-	stm
-	prefetch map[string]*v3.GetResponse
-}
-
-func (s *stmSerializable) Get(keys ...string) string {
-	if wv := s.wset.get(keys...); wv != nil {
-		return wv.val
-	}
-	firstRead := len(s.rset) == 0
-	for _, key := range keys {
-		if resp, ok := s.prefetch[key]; ok {
-			delete(s.prefetch, key)
-			s.rset[key] = resp
-		}
-	}
-	resp := s.stm.fetch(keys...)
-	if firstRead {
-		// txn's base revision is defined by the first read
-		s.getOpts = []v3.OpOption{
-			v3.WithRev(resp.Header.Revision),
-			v3.WithSerializable(),
-		}
-	}
-	return respToValue(resp)
-}
-
-func (s *stmSerializable) Rev(key string) int64 {
-	s.Get(key)
-	return s.stm.Rev(key)
-}
-
-func (s *stmSerializable) gets() ([]string, []v3.Op) {
-	keys := make([]string, 0, len(s.rset))
-	ops := make([]v3.Op, 0, len(s.rset))
-	for k := range s.rset {
-		keys = append(keys, k)
-		ops = append(ops, v3.OpGet(k))
-	}
-	return keys, ops
-}
-
-func (s *stmSerializable) commit() *v3.TxnResponse {
-	keys, getops := s.gets()
-	txn := s.client.Txn(s.ctx).If(s.conflicts()...).Then(s.wset.puts()...)
-	// use Else to prefetch keys in case of conflict to save a round trip
-	txnresp, err := txn.Else(getops...).Commit()
-	if err != nil {
-		panic(stmError{err})
-	}
-	if txnresp.Succeeded {
-		return txnresp
-	}
-	// load prefetch with Else data
-	s.rset.add(keys, txnresp)
-	s.prefetch = s.rset
-	s.getOpts = nil
-	return nil
-}
-
-func isKeyCurrent(k string, r *v3.GetResponse) v3.Cmp {
-	if len(r.Kvs) != 0 {
-		return v3.Compare(v3.ModRevision(k), "=", r.Kvs[0].ModRevision)
-	}
-	return v3.Compare(v3.ModRevision(k), "=", 0)
-}
-
-func respToValue(resp *v3.GetResponse) string {
-	if resp == nil || len(resp.Kvs) == 0 {
-		return ""
-	}
-	return string(resp.Kvs[0].Value)
-}
-
-// NewSTMRepeatable is deprecated.
-func NewSTMRepeatable(ctx context.Context, c *v3.Client, apply func(STM) error) (*v3.TxnResponse, error) {
-	return NewSTM(c, apply, WithAbortContext(ctx), WithIsolation(RepeatableReads))
-}
-
-// NewSTMSerializable is deprecated.
-func NewSTMSerializable(ctx context.Context, c *v3.Client, apply func(STM) error) (*v3.TxnResponse, error) {
-	return NewSTM(c, apply, WithAbortContext(ctx), WithIsolation(Serializable))
-}
-
-// NewSTMReadCommitted is deprecated.
-func NewSTMReadCommitted(ctx context.Context, c *v3.Client, apply func(STM) error) (*v3.TxnResponse, error) {
-	return NewSTM(c, apply, WithAbortContext(ctx), WithIsolation(ReadCommitted))
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/config.go b/vendor/github.com/coreos/etcd/clientv3/config.go
deleted file mode 100644
index 79d6e2a..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/config.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-	"crypto/tls"
-	"time"
-
-	"google.golang.org/grpc"
-)
-
-type Config struct {
-	// Endpoints is a list of URLs.
-	Endpoints []string `json:"endpoints"`
-
-	// AutoSyncInterval is the interval to update endpoints with its latest members.
-	// 0 disables auto-sync. By default auto-sync is disabled.
-	AutoSyncInterval time.Duration `json:"auto-sync-interval"`
-
-	// DialTimeout is the timeout for failing to establish a connection.
-	DialTimeout time.Duration `json:"dial-timeout"`
-
-	// DialKeepAliveTime is the time after which client pings the server to see if
-	// transport is alive.
-	DialKeepAliveTime time.Duration `json:"dial-keep-alive-time"`
-
-	// DialKeepAliveTimeout is the time that the client waits for a response for the
-	// keep-alive probe. If the response is not received in this time, the connection is closed.
-	DialKeepAliveTimeout time.Duration `json:"dial-keep-alive-timeout"`
-
-	// MaxCallSendMsgSize is the client-side request send limit in bytes.
-	// If 0, it defaults to 2.0 MiB (2 * 1024 * 1024).
-	// Make sure that "MaxCallSendMsgSize" < server-side default send/recv limit.
-	// ("--max-request-bytes" flag to etcd or "embed.Config.MaxRequestBytes").
-	MaxCallSendMsgSize int
-
-	// MaxCallRecvMsgSize is the client-side response receive limit.
-	// If 0, it defaults to "math.MaxInt32", because range response can
-	// easily exceed request send limits.
-	// Make sure that "MaxCallRecvMsgSize" >= server-side default send/recv limit.
-	// ("--max-request-bytes" flag to etcd or "embed.Config.MaxRequestBytes").
-	MaxCallRecvMsgSize int
-
-	// TLS holds the client secure credentials, if any.
-	TLS *tls.Config
-
-	// Username is a user name for authentication.
-	Username string `json:"username"`
-
-	// Password is a password for authentication.
-	Password string `json:"password"`
-
-	// RejectOldCluster when set will refuse to create a client against an outdated cluster.
-	RejectOldCluster bool `json:"reject-old-cluster"`
-
-	// DialOptions is a list of dial options for the grpc client (e.g., for interceptors).
-	DialOptions []grpc.DialOption
-
-	// Context is the default client context; it can be used to cancel grpc dial out and
-	// other operations that do not have an explicit context.
-	Context context.Context
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/doc.go b/vendor/github.com/coreos/etcd/clientv3/doc.go
deleted file mode 100644
index 717fbe4..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/doc.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package clientv3 implements the official Go etcd client for v3.
-//
-// Create client using `clientv3.New`:
-//
-//	// expect dial time-out on ipv4 blackhole
-//	_, err := clientv3.New(clientv3.Config{
-//		Endpoints:   []string{"http://254.0.0.1:12345"},
-//		DialTimeout: 2 * time.Second
-//	})
-//
-//	// etcd clientv3 >= v3.2.10, grpc/grpc-go >= v1.7.3
-//	if err == context.DeadlineExceeded {
-//		// handle errors
-//	}
-//
-//	// etcd clientv3 <= v3.2.9, grpc/grpc-go <= v1.2.1
-//	if err == grpc.ErrClientConnTimeout {
-//		// handle errors
-//	}
-//
-//	cli, err := clientv3.New(clientv3.Config{
-//		Endpoints:   []string{"localhost:2379", "localhost:22379", "localhost:32379"},
-//		DialTimeout: 5 * time.Second,
-//	})
-//	if err != nil {
-//		// handle error!
-//	}
-//	defer cli.Close()
-//
-// Make sure to close the client after using it. If the client is not closed, the
-// connection will have leaky goroutines.
-//
-// To specify a client request timeout, wrap the context with context.WithTimeout:
-//
-//	ctx, cancel := context.WithTimeout(context.Background(), timeout)
-//	resp, err := kvc.Put(ctx, "sample_key", "sample_value")
-//	cancel()
-//	if err != nil {
-//	    // handle error!
-//	}
-//	// use the response
-//
-// The Client has internal state (watchers and leases), so Clients should be reused instead of created as needed.
-// Clients are safe for concurrent use by multiple goroutines.
-//
-// etcd client returns 3 types of errors:
-//
-//  1. context error: canceled or deadline exceeded.
-//  2. gRPC status error: e.g. when clock drifts in server-side before client's context deadline exceeded.
-//  3. gRPC error: see https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/rpctypes/error.go
-//
-// Here is the example code to handle client errors:
-//
-//	resp, err := kvc.Put(ctx, "", "")
-//	if err != nil {
-//		if err == context.Canceled {
-//			// ctx is canceled by another routine
-//		} else if err == context.DeadlineExceeded {
-//			// ctx is attached with a deadline and it exceeded
-//		} else if ev, ok := status.FromError(err); ok {
-//			code := ev.Code()
-//			if code == codes.DeadlineExceeded {
-//				// server-side context might have timed-out first (due to clock skew)
-//				// while original client-side context is not timed-out yet
-//			}
-//		} else if verr, ok := err.(*v3rpc.ErrEmptyKey); ok {
-//			// process (verr.Errors)
-//		} else {
-//			// bad cluster endpoints, which are not etcd servers
-//		}
-//	}
-//
-//	go func() { cli.Close() }()
-//	_, err := kvc.Get(ctx, "a")
-//	if err != nil {
-//		if err == context.Canceled {
-//			// grpc balancer calls 'Get' with an inflight client.Close
-//		} else if err == grpc.ErrClientConnClosing {
-//			// grpc balancer calls 'Get' after client.Close.
-//		}
-//	}
-//
-package clientv3
diff --git a/vendor/github.com/coreos/etcd/clientv3/health_balancer.go b/vendor/github.com/coreos/etcd/clientv3/health_balancer.go
deleted file mode 100644
index 5918cba..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/health_balancer.go
+++ /dev/null
@@ -1,609 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-	"errors"
-	"net/url"
-	"strings"
-	"sync"
-	"time"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	healthpb "google.golang.org/grpc/health/grpc_health_v1"
-	"google.golang.org/grpc/status"
-)
-
-const (
-	minHealthRetryDuration = 3 * time.Second
-	unknownService         = "unknown service grpc.health.v1.Health"
-)
-
-// ErrNoAddrAvilable is returned by Get() when the balancer does not have
-// any active connection to endpoints at the time.
-// This error is returned only when opts.BlockingWait is true.
-var ErrNoAddrAvilable = status.Error(codes.Unavailable, "there is no address available")
-
-type healthCheckFunc func(ep string) (bool, error)
-
-type notifyMsg int
-
-const (
-	notifyReset notifyMsg = iota
-	notifyNext
-)
-
-// healthBalancer does the bare minimum to expose multiple eps
-// to the grpc reconnection code path
-type healthBalancer struct {
-	// addrs are the client's endpoint addresses for grpc
-	addrs []grpc.Address
-
-	// eps holds the raw endpoints from the client
-	eps []string
-
-	// notifyCh notifies grpc of the set of addresses for connecting
-	notifyCh chan []grpc.Address
-
-	// readyc closes once the first connection is up
-	readyc    chan struct{}
-	readyOnce sync.Once
-
-	// healthCheck checks an endpoint's health.
-	healthCheck        healthCheckFunc
-	healthCheckTimeout time.Duration
-
-	unhealthyMu        sync.RWMutex
-	unhealthyHostPorts map[string]time.Time
-
-	// mu protects all fields below.
-	mu sync.RWMutex
-
-	// upc closes when pinAddr transitions from empty to non-empty or the balancer closes.
-	upc chan struct{}
-
-	// downc closes when grpc calls down() on pinAddr
-	downc chan struct{}
-
-	// stopc is closed to signal updateNotifyLoop should stop.
-	stopc    chan struct{}
-	stopOnce sync.Once
-	wg       sync.WaitGroup
-
-	// donec closes when all goroutines are exited
-	donec chan struct{}
-
-	// updateAddrsC notifies updateNotifyLoop to update addrs.
-	updateAddrsC chan notifyMsg
-
-	// grpc issues TLS cert checks using the string passed into dial so
-	// that string must be the host. To recover the full scheme://host URL,
-	// have a map from hosts to the original endpoint.
-	hostPort2ep map[string]string
-
-	// pinAddr is the currently pinned address; set to the empty string on
-	// initialization and shutdown.
-	pinAddr string
-
-	closed bool
-}
-
-func newHealthBalancer(eps []string, timeout time.Duration, hc healthCheckFunc) *healthBalancer {
-	notifyCh := make(chan []grpc.Address)
-	addrs := eps2addrs(eps)
-	hb := &healthBalancer{
-		addrs:              addrs,
-		eps:                eps,
-		notifyCh:           notifyCh,
-		readyc:             make(chan struct{}),
-		healthCheck:        hc,
-		unhealthyHostPorts: make(map[string]time.Time),
-		upc:                make(chan struct{}),
-		stopc:              make(chan struct{}),
-		downc:              make(chan struct{}),
-		donec:              make(chan struct{}),
-		updateAddrsC:       make(chan notifyMsg),
-		hostPort2ep:        getHostPort2ep(eps),
-	}
-	if timeout < minHealthRetryDuration {
-		timeout = minHealthRetryDuration
-	}
-	hb.healthCheckTimeout = timeout
-
-	close(hb.downc)
-	go hb.updateNotifyLoop()
-	hb.wg.Add(1)
-	go func() {
-		defer hb.wg.Done()
-		hb.updateUnhealthy()
-	}()
-	return hb
-}
-
-func (b *healthBalancer) Start(target string, config grpc.BalancerConfig) error { return nil }
-
-func (b *healthBalancer) ConnectNotify() <-chan struct{} {
-	b.mu.Lock()
-	defer b.mu.Unlock()
-	return b.upc
-}
-
-func (b *healthBalancer) ready() <-chan struct{} { return b.readyc }
-
-func (b *healthBalancer) endpoint(hostPort string) string {
-	b.mu.RLock()
-	defer b.mu.RUnlock()
-	return b.hostPort2ep[hostPort]
-}
-
-func (b *healthBalancer) pinned() string {
-	b.mu.RLock()
-	defer b.mu.RUnlock()
-	return b.pinAddr
-}
-
-func (b *healthBalancer) hostPortError(hostPort string, err error) {
-	if b.endpoint(hostPort) == "" {
-		logger.Lvl(4).Infof("clientv3/balancer: %q is stale (skip marking as unhealthy on %q)", hostPort, err.Error())
-		return
-	}
-
-	b.unhealthyMu.Lock()
-	b.unhealthyHostPorts[hostPort] = time.Now()
-	b.unhealthyMu.Unlock()
-	logger.Lvl(4).Infof("clientv3/balancer: %q is marked unhealthy (%q)", hostPort, err.Error())
-}
-
-func (b *healthBalancer) removeUnhealthy(hostPort, msg string) {
-	if b.endpoint(hostPort) == "" {
-		logger.Lvl(4).Infof("clientv3/balancer: %q was not in unhealthy (%q)", hostPort, msg)
-		return
-	}
-
-	b.unhealthyMu.Lock()
-	delete(b.unhealthyHostPorts, hostPort)
-	b.unhealthyMu.Unlock()
-	logger.Lvl(4).Infof("clientv3/balancer: %q is removed from unhealthy (%q)", hostPort, msg)
-}
-
-func (b *healthBalancer) countUnhealthy() (count int) {
-	b.unhealthyMu.RLock()
-	count = len(b.unhealthyHostPorts)
-	b.unhealthyMu.RUnlock()
-	return count
-}
-
-func (b *healthBalancer) isUnhealthy(hostPort string) (unhealthy bool) {
-	b.unhealthyMu.RLock()
-	_, unhealthy = b.unhealthyHostPorts[hostPort]
-	b.unhealthyMu.RUnlock()
-	return unhealthy
-}
-
-func (b *healthBalancer) cleanupUnhealthy() {
-	b.unhealthyMu.Lock()
-	for k, v := range b.unhealthyHostPorts {
-		if time.Since(v) > b.healthCheckTimeout {
-			delete(b.unhealthyHostPorts, k)
-			logger.Lvl(4).Infof("clientv3/balancer: removed %q from unhealthy after %v", k, b.healthCheckTimeout)
-		}
-	}
-	b.unhealthyMu.Unlock()
-}
-
-func (b *healthBalancer) liveAddrs() ([]grpc.Address, map[string]struct{}) {
-	unhealthyCnt := b.countUnhealthy()
-
-	b.mu.RLock()
-	defer b.mu.RUnlock()
-
-	hbAddrs := b.addrs
-	if len(b.addrs) == 1 || unhealthyCnt == 0 || unhealthyCnt == len(b.addrs) {
-		liveHostPorts := make(map[string]struct{}, len(b.hostPort2ep))
-		for k := range b.hostPort2ep {
-			liveHostPorts[k] = struct{}{}
-		}
-		return hbAddrs, liveHostPorts
-	}
-
-	addrs := make([]grpc.Address, 0, len(b.addrs)-unhealthyCnt)
-	liveHostPorts := make(map[string]struct{}, len(addrs))
-	for _, addr := range b.addrs {
-		if !b.isUnhealthy(addr.Addr) {
-			addrs = append(addrs, addr)
-			liveHostPorts[addr.Addr] = struct{}{}
-		}
-	}
-	return addrs, liveHostPorts
-}
-
-func (b *healthBalancer) updateUnhealthy() {
-	for {
-		select {
-		case <-time.After(b.healthCheckTimeout):
-			b.cleanupUnhealthy()
-			pinned := b.pinned()
-			if pinned == "" || b.isUnhealthy(pinned) {
-				select {
-				case b.updateAddrsC <- notifyNext:
-				case <-b.stopc:
-					return
-				}
-			}
-		case <-b.stopc:
-			return
-		}
-	}
-}
-
-func (b *healthBalancer) updateAddrs(eps ...string) {
-	np := getHostPort2ep(eps)
-
-	b.mu.Lock()
-	defer b.mu.Unlock()
-
-	match := len(np) == len(b.hostPort2ep)
-	if match {
-		for k, v := range np {
-			if b.hostPort2ep[k] != v {
-				match = false
-				break
-			}
-		}
-	}
-	if match {
-		// same endpoints, so no need to update address
-		return
-	}
-
-	b.hostPort2ep = np
-	b.addrs, b.eps = eps2addrs(eps), eps
-
-	b.unhealthyMu.Lock()
-	b.unhealthyHostPorts = make(map[string]time.Time)
-	b.unhealthyMu.Unlock()
-}
-
-func (b *healthBalancer) next() {
-	b.mu.RLock()
-	downc := b.downc
-	b.mu.RUnlock()
-	select {
-	case b.updateAddrsC <- notifyNext:
-	case <-b.stopc:
-	}
-	// wait until disconnect so new RPCs are not issued on old connection
-	select {
-	case <-downc:
-	case <-b.stopc:
-	}
-}
-
-func (b *healthBalancer) updateNotifyLoop() {
-	defer close(b.donec)
-
-	for {
-		b.mu.RLock()
-		upc, downc, addr := b.upc, b.downc, b.pinAddr
-		b.mu.RUnlock()
-		// downc or upc should be closed
-		select {
-		case <-downc:
-			downc = nil
-		default:
-		}
-		select {
-		case <-upc:
-			upc = nil
-		default:
-		}
-		switch {
-		case downc == nil && upc == nil:
-			// stale
-			select {
-			case <-b.stopc:
-				return
-			default:
-			}
-		case downc == nil:
-			b.notifyAddrs(notifyReset)
-			select {
-			case <-upc:
-			case msg := <-b.updateAddrsC:
-				b.notifyAddrs(msg)
-			case <-b.stopc:
-				return
-			}
-		case upc == nil:
-			select {
-			// close connections that are not the pinned address
-			case b.notifyCh <- []grpc.Address{{Addr: addr}}:
-			case <-downc:
-			case <-b.stopc:
-				return
-			}
-			select {
-			case <-downc:
-				b.notifyAddrs(notifyReset)
-			case msg := <-b.updateAddrsC:
-				b.notifyAddrs(msg)
-			case <-b.stopc:
-				return
-			}
-		}
-	}
-}
-
-func (b *healthBalancer) notifyAddrs(msg notifyMsg) {
-	if msg == notifyNext {
-		select {
-		case b.notifyCh <- []grpc.Address{}:
-		case <-b.stopc:
-			return
-		}
-	}
-	b.mu.RLock()
-	pinAddr := b.pinAddr
-	downc := b.downc
-	b.mu.RUnlock()
-	addrs, hostPorts := b.liveAddrs()
-
-	var waitDown bool
-	if pinAddr != "" {
-		_, ok := hostPorts[pinAddr]
-		waitDown = !ok
-	}
-
-	select {
-	case b.notifyCh <- addrs:
-		if waitDown {
-			select {
-			case <-downc:
-			case <-b.stopc:
-			}
-		}
-	case <-b.stopc:
-	}
-}
-
-func (b *healthBalancer) Up(addr grpc.Address) func(error) {
-	if !b.mayPin(addr) {
-		return func(err error) {}
-	}
-
-	b.mu.Lock()
-	defer b.mu.Unlock()
-
-	// gRPC might call Up after it called Close. We add this check
-	// to "fix" it up at application layer. Otherwise, will panic
-	// if b.upc is already closed.
-	if b.closed {
-		return func(err error) {}
-	}
-
-	// gRPC might call Up on a stale address.
-	// Prevent updating pinAddr with a stale address.
-	if !hasAddr(b.addrs, addr.Addr) {
-		return func(err error) {}
-	}
-
-	if b.pinAddr != "" {
-		logger.Lvl(4).Infof("clientv3/balancer: %q is up but not pinned (already pinned %q)", addr.Addr, b.pinAddr)
-		return func(err error) {}
-	}
-
-	// notify waiting Get()s and pin first connected address
-	close(b.upc)
-	b.downc = make(chan struct{})
-	b.pinAddr = addr.Addr
-	logger.Lvl(4).Infof("clientv3/balancer: pin %q", addr.Addr)
-
-	// notify client that a connection is up
-	b.readyOnce.Do(func() { close(b.readyc) })
-
-	return func(err error) {
-		// If connected to a black hole endpoint or a killed server, the gRPC ping
-		// timeout will induce a network I/O error, and retrying until success;
-		// finding healthy endpoint on retry could take several timeouts and redials.
-		// To avoid wasting retries, gray-list unhealthy endpoints.
-		b.hostPortError(addr.Addr, err)
-
-		b.mu.Lock()
-		b.upc = make(chan struct{})
-		close(b.downc)
-		b.pinAddr = ""
-		b.mu.Unlock()
-		logger.Lvl(4).Infof("clientv3/balancer: unpin %q (%q)", addr.Addr, err.Error())
-	}
-}
-
-func (b *healthBalancer) mayPin(addr grpc.Address) bool {
-	if b.endpoint(addr.Addr) == "" { // stale host:port
-		return false
-	}
-
-	b.unhealthyMu.RLock()
-	unhealthyCnt := len(b.unhealthyHostPorts)
-	failedTime, bad := b.unhealthyHostPorts[addr.Addr]
-	b.unhealthyMu.RUnlock()
-
-	b.mu.RLock()
-	skip := len(b.addrs) == 1 || unhealthyCnt == 0 || len(b.addrs) == unhealthyCnt
-	b.mu.RUnlock()
-	if skip || !bad {
-		return true
-	}
-
-	// prevent isolated member's endpoint from being infinitely retried, as follows:
-	//   1. keepalive pings detects GoAway with http2.ErrCodeEnhanceYourCalm
-	//   2. balancer 'Up' unpins with grpc: failed with network I/O error
-	//   3. grpc-healthcheck still SERVING, thus retry to pin
-	// instead, return before grpc-healthcheck if failed within healthcheck timeout
-	if elapsed := time.Since(failedTime); elapsed < b.healthCheckTimeout {
-		logger.Lvl(4).Infof("clientv3/balancer: %q is up but not pinned (failed %v ago, require minimum %v after failure)", addr.Addr, elapsed, b.healthCheckTimeout)
-		return false
-	}
-
-	if ok, _ := b.healthCheck(addr.Addr); ok {
-		b.removeUnhealthy(addr.Addr, "health check success")
-		return true
-	}
-
-	b.hostPortError(addr.Addr, errors.New("health check failed"))
-	return false
-}
-
-func (b *healthBalancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (grpc.Address, func(), error) {
-	var (
-		addr   string
-		closed bool
-	)
-
-	// If opts.BlockingWait is false (for fail-fast RPCs), it should return
-	// an address it has notified via Notify immediately instead of blocking.
-	if !opts.BlockingWait {
-		b.mu.RLock()
-		closed = b.closed
-		addr = b.pinAddr
-		b.mu.RUnlock()
-		if closed {
-			return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing
-		}
-		if addr == "" {
-			return grpc.Address{Addr: ""}, nil, ErrNoAddrAvilable
-		}
-		return grpc.Address{Addr: addr}, func() {}, nil
-	}
-
-	for {
-		b.mu.RLock()
-		ch := b.upc
-		b.mu.RUnlock()
-		select {
-		case <-ch:
-		case <-b.donec:
-			return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing
-		case <-ctx.Done():
-			return grpc.Address{Addr: ""}, nil, ctx.Err()
-		}
-		b.mu.RLock()
-		closed = b.closed
-		addr = b.pinAddr
-		b.mu.RUnlock()
-		// Close() which sets b.closed = true can be called before Get(), Get() must exit if balancer is closed.
-		if closed {
-			return grpc.Address{Addr: ""}, nil, grpc.ErrClientConnClosing
-		}
-		if addr != "" {
-			break
-		}
-	}
-	return grpc.Address{Addr: addr}, func() {}, nil
-}
-
-func (b *healthBalancer) Notify() <-chan []grpc.Address { return b.notifyCh }
-
-func (b *healthBalancer) Close() error {
-	b.mu.Lock()
-	// In case gRPC calls close twice. TODO: remove the checking
-	// when we are sure that gRPC wont call close twice.
-	if b.closed {
-		b.mu.Unlock()
-		<-b.donec
-		return nil
-	}
-	b.closed = true
-	b.stopOnce.Do(func() { close(b.stopc) })
-	b.pinAddr = ""
-
-	// In the case of following scenario:
-	//	1. upc is not closed; no pinned address
-	// 	2. client issues an RPC, calling invoke(), which calls Get(), enters for loop, blocks
-	// 	3. client.conn.Close() calls balancer.Close(); closed = true
-	// 	4. for loop in Get() never exits since ctx is the context passed in by the client and may not be canceled
-	// we must close upc so Get() exits from blocking on upc
-	select {
-	case <-b.upc:
-	default:
-		// terminate all waiting Get()s
-		close(b.upc)
-	}
-
-	b.mu.Unlock()
-	b.wg.Wait()
-
-	// wait for updateNotifyLoop to finish
-	<-b.donec
-	close(b.notifyCh)
-
-	return nil
-}
-
-func grpcHealthCheck(client *Client, ep string) (bool, error) {
-	conn, err := client.dial(ep)
-	if err != nil {
-		return false, err
-	}
-	defer conn.Close()
-	cli := healthpb.NewHealthClient(conn)
-	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
-	resp, err := cli.Check(ctx, &healthpb.HealthCheckRequest{})
-	cancel()
-	if err != nil {
-		if s, ok := status.FromError(err); ok && s.Code() == codes.Unavailable {
-			if s.Message() == unknownService { // etcd < v3.3.0
-				return true, nil
-			}
-		}
-		return false, err
-	}
-	return resp.Status == healthpb.HealthCheckResponse_SERVING, nil
-}
-
-func hasAddr(addrs []grpc.Address, targetAddr string) bool {
-	for _, addr := range addrs {
-		if targetAddr == addr.Addr {
-			return true
-		}
-	}
-	return false
-}
-
-func getHost(ep string) string {
-	url, uerr := url.Parse(ep)
-	if uerr != nil || !strings.Contains(ep, "://") {
-		return ep
-	}
-	return url.Host
-}
-
-func eps2addrs(eps []string) []grpc.Address {
-	addrs := make([]grpc.Address, len(eps))
-	for i := range eps {
-		addrs[i].Addr = getHost(eps[i])
-	}
-	return addrs
-}
-
-func getHostPort2ep(eps []string) map[string]string {
-	hm := make(map[string]string, len(eps))
-	for i := range eps {
-		_, host, _ := parseEndpoint(eps[i])
-		hm[host] = eps[i]
-	}
-	return hm
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/kv.go b/vendor/github.com/coreos/etcd/clientv3/kv.go
deleted file mode 100644
index 5a7469b..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/kv.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-)
-
-type (
-	CompactResponse pb.CompactionResponse
-	PutResponse     pb.PutResponse
-	GetResponse     pb.RangeResponse
-	DeleteResponse  pb.DeleteRangeResponse
-	TxnResponse     pb.TxnResponse
-)
-
-type KV interface {
-	// Put puts a key-value pair into etcd.
-	// Note that key,value can be plain bytes array and string is
-	// an immutable representation of that bytes array.
-	// To get a string of bytes, do string([]byte{0x10, 0x20}).
-	Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error)
-
-	// Get retrieves keys.
-	// By default, Get will return the value for "key", if any.
-	// When passed WithRange(end), Get will return the keys in the range [key, end).
-	// When passed WithFromKey(), Get returns keys greater than or equal to key.
-	// When passed WithRev(rev) with rev > 0, Get retrieves keys at the given revision;
-	// if the required revision is compacted, the request will fail with ErrCompacted .
-	// When passed WithLimit(limit), the number of returned keys is bounded by limit.
-	// When passed WithSort(), the keys will be sorted.
-	Get(ctx context.Context, key string, opts ...OpOption) (*GetResponse, error)
-
-	// Delete deletes a key, or optionally using WithRange(end), [key, end).
-	Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error)
-
-	// Compact compacts etcd KV history before the given rev.
-	Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error)
-
-	// Do applies a single Op on KV without a transaction.
-	// Do is useful when creating arbitrary operations to be issued at a
-	// later time; the user can range over the operations, calling Do to
-	// execute them. Get/Put/Delete, on the other hand, are best suited
-	// for when the operation should be issued at the time of declaration.
-	Do(ctx context.Context, op Op) (OpResponse, error)
-
-	// Txn creates a transaction.
-	Txn(ctx context.Context) Txn
-}
-
-type OpResponse struct {
-	put *PutResponse
-	get *GetResponse
-	del *DeleteResponse
-	txn *TxnResponse
-}
-
-func (op OpResponse) Put() *PutResponse    { return op.put }
-func (op OpResponse) Get() *GetResponse    { return op.get }
-func (op OpResponse) Del() *DeleteResponse { return op.del }
-func (op OpResponse) Txn() *TxnResponse    { return op.txn }
-
-func (resp *PutResponse) OpResponse() OpResponse {
-	return OpResponse{put: resp}
-}
-func (resp *GetResponse) OpResponse() OpResponse {
-	return OpResponse{get: resp}
-}
-func (resp *DeleteResponse) OpResponse() OpResponse {
-	return OpResponse{del: resp}
-}
-func (resp *TxnResponse) OpResponse() OpResponse {
-	return OpResponse{txn: resp}
-}
-
-type kv struct {
-	remote   pb.KVClient
-	callOpts []grpc.CallOption
-}
-
-func NewKV(c *Client) KV {
-	api := &kv{remote: RetryKVClient(c)}
-	if c != nil {
-		api.callOpts = c.callOpts
-	}
-	return api
-}
-
-func NewKVFromKVClient(remote pb.KVClient, c *Client) KV {
-	api := &kv{remote: remote}
-	if c != nil {
-		api.callOpts = c.callOpts
-	}
-	return api
-}
-
-func (kv *kv) Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error) {
-	r, err := kv.Do(ctx, OpPut(key, val, opts...))
-	return r.put, toErr(ctx, err)
-}
-
-func (kv *kv) Get(ctx context.Context, key string, opts ...OpOption) (*GetResponse, error) {
-	r, err := kv.Do(ctx, OpGet(key, opts...))
-	return r.get, toErr(ctx, err)
-}
-
-func (kv *kv) Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error) {
-	r, err := kv.Do(ctx, OpDelete(key, opts...))
-	return r.del, toErr(ctx, err)
-}
-
-func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error) {
-	resp, err := kv.remote.Compact(ctx, OpCompact(rev, opts...).toRequest(), kv.callOpts...)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-	return (*CompactResponse)(resp), err
-}
-
-func (kv *kv) Txn(ctx context.Context) Txn {
-	return &txn{
-		kv:       kv,
-		ctx:      ctx,
-		callOpts: kv.callOpts,
-	}
-}
-
-func (kv *kv) Do(ctx context.Context, op Op) (OpResponse, error) {
-	var err error
-	switch op.t {
-	case tRange:
-		var resp *pb.RangeResponse
-		resp, err = kv.remote.Range(ctx, op.toRangeRequest(), kv.callOpts...)
-		if err == nil {
-			return OpResponse{get: (*GetResponse)(resp)}, nil
-		}
-	case tPut:
-		var resp *pb.PutResponse
-		r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV, IgnoreValue: op.ignoreValue, IgnoreLease: op.ignoreLease}
-		resp, err = kv.remote.Put(ctx, r, kv.callOpts...)
-		if err == nil {
-			return OpResponse{put: (*PutResponse)(resp)}, nil
-		}
-	case tDeleteRange:
-		var resp *pb.DeleteRangeResponse
-		r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV}
-		resp, err = kv.remote.DeleteRange(ctx, r, kv.callOpts...)
-		if err == nil {
-			return OpResponse{del: (*DeleteResponse)(resp)}, nil
-		}
-	case tTxn:
-		var resp *pb.TxnResponse
-		resp, err = kv.remote.Txn(ctx, op.toTxnRequest(), kv.callOpts...)
-		if err == nil {
-			return OpResponse{txn: (*TxnResponse)(resp)}, nil
-		}
-	default:
-		panic("Unknown op")
-	}
-	return OpResponse{}, toErr(ctx, err)
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/lease.go b/vendor/github.com/coreos/etcd/clientv3/lease.go
deleted file mode 100644
index 3729cf3..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/lease.go
+++ /dev/null
@@ -1,588 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/metadata"
-)
-
-type (
-	LeaseRevokeResponse pb.LeaseRevokeResponse
-	LeaseID             int64
-)
-
-// LeaseGrantResponse wraps the protobuf message LeaseGrantResponse.
-type LeaseGrantResponse struct {
-	*pb.ResponseHeader
-	ID    LeaseID
-	TTL   int64
-	Error string
-}
-
-// LeaseKeepAliveResponse wraps the protobuf message LeaseKeepAliveResponse.
-type LeaseKeepAliveResponse struct {
-	*pb.ResponseHeader
-	ID  LeaseID
-	TTL int64
-}
-
-// LeaseTimeToLiveResponse wraps the protobuf message LeaseTimeToLiveResponse.
-type LeaseTimeToLiveResponse struct {
-	*pb.ResponseHeader
-	ID LeaseID `json:"id"`
-
-	// TTL is the remaining TTL in seconds for the lease; the lease will expire in under TTL+1 seconds. Expired lease will return -1.
-	TTL int64 `json:"ttl"`
-
-	// GrantedTTL is the initial granted time in seconds upon lease creation/renewal.
-	GrantedTTL int64 `json:"granted-ttl"`
-
-	// Keys is the list of keys attached to this lease.
-	Keys [][]byte `json:"keys"`
-}
-
-// LeaseStatus represents a lease status.
-type LeaseStatus struct {
-	ID LeaseID `json:"id"`
-	// TODO: TTL int64
-}
-
-// LeaseLeasesResponse wraps the protobuf message LeaseLeasesResponse.
-type LeaseLeasesResponse struct {
-	*pb.ResponseHeader
-	Leases []LeaseStatus `json:"leases"`
-}
-
-const (
-	// defaultTTL is the assumed lease TTL used for the first keepalive
-	// deadline before the actual TTL is known to the client.
-	defaultTTL = 5 * time.Second
-	// NoLease is a lease ID for the absence of a lease.
-	NoLease LeaseID = 0
-
-	// retryConnWait is how long to wait before retrying request due to an error
-	retryConnWait = 500 * time.Millisecond
-)
-
-// LeaseResponseChSize is the size of buffer to store unsent lease responses.
-// WARNING: DO NOT UPDATE.
-// Only for testing purposes.
-var LeaseResponseChSize = 16
-
-// ErrKeepAliveHalted is returned if client keep alive loop halts with an unexpected error.
-//
-// This usually means that automatic lease renewal via KeepAlive is broken, but KeepAliveOnce will still work as expected.
-type ErrKeepAliveHalted struct {
-	Reason error
-}
-
-func (e ErrKeepAliveHalted) Error() string {
-	s := "etcdclient: leases keep alive halted"
-	if e.Reason != nil {
-		s += ": " + e.Reason.Error()
-	}
-	return s
-}
-
-type Lease interface {
-	// Grant creates a new lease.
-	Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error)
-
-	// Revoke revokes the given lease.
-	Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error)
-
-	// TimeToLive retrieves the lease information of the given lease ID.
-	TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error)
-
-	// Leases retrieves all leases.
-	Leases(ctx context.Context) (*LeaseLeasesResponse, error)
-
-	// KeepAlive keeps the given lease alive forever. If the keepalive response
-	// posted to the channel is not consumed immediately, the lease client will
-	// continue sending keep alive requests to the etcd server at least every
-	// second until latest response is consumed.
-	//
-	// The returned "LeaseKeepAliveResponse" channel closes if underlying keep
-	// alive stream is interrupted in some way the client cannot handle itself;
-	// given context "ctx" is canceled or timed out. "LeaseKeepAliveResponse"
-	// from this closed channel is nil.
-	//
-	// If client keep alive loop halts with an unexpected error (e.g. "etcdserver:
-	// no leader") or canceled by the caller (e.g. context.Canceled), the error
-	// is returned. Otherwise, it retries.
-	//
-	// TODO(v4.0): post errors to last keep alive message before closing
-	// (see https://github.com/coreos/etcd/pull/7866)
-	KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error)
-
-	// KeepAliveOnce renews the lease once. The response corresponds to the
-	// first message from calling KeepAlive. If the response has a recoverable
-	// error, KeepAliveOnce will retry the RPC with a new keep alive message.
-	//
-	// In most of the cases, Keepalive should be used instead of KeepAliveOnce.
-	KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error)
-
-	// Close releases all resources Lease keeps for efficient communication
-	// with the etcd server.
-	Close() error
-}
-
-type lessor struct {
-	mu sync.Mutex // guards all fields
-
-	// donec is closed and loopErr is set when recvKeepAliveLoop stops
-	donec   chan struct{}
-	loopErr error
-
-	remote pb.LeaseClient
-
-	stream       pb.Lease_LeaseKeepAliveClient
-	streamCancel context.CancelFunc
-
-	stopCtx    context.Context
-	stopCancel context.CancelFunc
-
-	keepAlives map[LeaseID]*keepAlive
-
-	// firstKeepAliveTimeout is the timeout for the first keepalive request
-	// before the actual TTL is known to the lease client
-	firstKeepAliveTimeout time.Duration
-
-	// firstKeepAliveOnce ensures stream starts after first KeepAlive call.
-	firstKeepAliveOnce sync.Once
-
-	callOpts []grpc.CallOption
-}
-
-// keepAlive multiplexes a keepalive for a lease over multiple channels
-type keepAlive struct {
-	chs  []chan<- *LeaseKeepAliveResponse
-	ctxs []context.Context
-	// deadline is the time the keep alive channels close if no response
-	deadline time.Time
-	// nextKeepAlive is when to send the next keep alive message
-	nextKeepAlive time.Time
-	// donec is closed on lease revoke, expiration, or cancel.
-	donec chan struct{}
-}
-
-func NewLease(c *Client) Lease {
-	return NewLeaseFromLeaseClient(RetryLeaseClient(c), c, c.cfg.DialTimeout+time.Second)
-}
-
-func NewLeaseFromLeaseClient(remote pb.LeaseClient, c *Client, keepAliveTimeout time.Duration) Lease {
-	l := &lessor{
-		donec:                 make(chan struct{}),
-		keepAlives:            make(map[LeaseID]*keepAlive),
-		remote:                remote,
-		firstKeepAliveTimeout: keepAliveTimeout,
-	}
-	if l.firstKeepAliveTimeout == time.Second {
-		l.firstKeepAliveTimeout = defaultTTL
-	}
-	if c != nil {
-		l.callOpts = c.callOpts
-	}
-	reqLeaderCtx := WithRequireLeader(context.Background())
-	l.stopCtx, l.stopCancel = context.WithCancel(reqLeaderCtx)
-	return l
-}
-
-func (l *lessor) Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error) {
-	r := &pb.LeaseGrantRequest{TTL: ttl}
-	resp, err := l.remote.LeaseGrant(ctx, r, l.callOpts...)
-	if err == nil {
-		gresp := &LeaseGrantResponse{
-			ResponseHeader: resp.GetHeader(),
-			ID:             LeaseID(resp.ID),
-			TTL:            resp.TTL,
-			Error:          resp.Error,
-		}
-		return gresp, nil
-	}
-	return nil, toErr(ctx, err)
-}
-
-func (l *lessor) Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error) {
-	r := &pb.LeaseRevokeRequest{ID: int64(id)}
-	resp, err := l.remote.LeaseRevoke(ctx, r, l.callOpts...)
-	if err == nil {
-		return (*LeaseRevokeResponse)(resp), nil
-	}
-	return nil, toErr(ctx, err)
-}
-
-func (l *lessor) TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error) {
-	r := toLeaseTimeToLiveRequest(id, opts...)
-	resp, err := l.remote.LeaseTimeToLive(ctx, r, l.callOpts...)
-	if err == nil {
-		gresp := &LeaseTimeToLiveResponse{
-			ResponseHeader: resp.GetHeader(),
-			ID:             LeaseID(resp.ID),
-			TTL:            resp.TTL,
-			GrantedTTL:     resp.GrantedTTL,
-			Keys:           resp.Keys,
-		}
-		return gresp, nil
-	}
-	return nil, toErr(ctx, err)
-}
-
-func (l *lessor) Leases(ctx context.Context) (*LeaseLeasesResponse, error) {
-	resp, err := l.remote.LeaseLeases(ctx, &pb.LeaseLeasesRequest{}, l.callOpts...)
-	if err == nil {
-		leases := make([]LeaseStatus, len(resp.Leases))
-		for i := range resp.Leases {
-			leases[i] = LeaseStatus{ID: LeaseID(resp.Leases[i].ID)}
-		}
-		return &LeaseLeasesResponse{ResponseHeader: resp.GetHeader(), Leases: leases}, nil
-	}
-	return nil, toErr(ctx, err)
-}
-
-func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) {
-	ch := make(chan *LeaseKeepAliveResponse, LeaseResponseChSize)
-
-	l.mu.Lock()
-	// ensure that recvKeepAliveLoop is still running
-	select {
-	case <-l.donec:
-		err := l.loopErr
-		l.mu.Unlock()
-		close(ch)
-		return ch, ErrKeepAliveHalted{Reason: err}
-	default:
-	}
-	ka, ok := l.keepAlives[id]
-	if !ok {
-		// create fresh keep alive
-		ka = &keepAlive{
-			chs:           []chan<- *LeaseKeepAliveResponse{ch},
-			ctxs:          []context.Context{ctx},
-			deadline:      time.Now().Add(l.firstKeepAliveTimeout),
-			nextKeepAlive: time.Now(),
-			donec:         make(chan struct{}),
-		}
-		l.keepAlives[id] = ka
-	} else {
-		// add channel and context to existing keep alive
-		ka.ctxs = append(ka.ctxs, ctx)
-		ka.chs = append(ka.chs, ch)
-	}
-	l.mu.Unlock()
-
-	go l.keepAliveCtxCloser(id, ctx, ka.donec)
-	l.firstKeepAliveOnce.Do(func() {
-		go l.recvKeepAliveLoop()
-		go l.deadlineLoop()
-	})
-
-	return ch, nil
-}
-
-func (l *lessor) KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error) {
-	for {
-		resp, err := l.keepAliveOnce(ctx, id)
-		if err == nil {
-			if resp.TTL <= 0 {
-				err = rpctypes.ErrLeaseNotFound
-			}
-			return resp, err
-		}
-		if isHaltErr(ctx, err) {
-			return nil, toErr(ctx, err)
-		}
-	}
-}
-
-func (l *lessor) Close() error {
-	l.stopCancel()
-	// close for synchronous teardown if stream goroutines never launched
-	l.firstKeepAliveOnce.Do(func() { close(l.donec) })
-	<-l.donec
-	return nil
-}
-
-func (l *lessor) keepAliveCtxCloser(id LeaseID, ctx context.Context, donec <-chan struct{}) {
-	select {
-	case <-donec:
-		return
-	case <-l.donec:
-		return
-	case <-ctx.Done():
-	}
-
-	l.mu.Lock()
-	defer l.mu.Unlock()
-
-	ka, ok := l.keepAlives[id]
-	if !ok {
-		return
-	}
-
-	// close channel and remove context if still associated with keep alive
-	for i, c := range ka.ctxs {
-		if c == ctx {
-			close(ka.chs[i])
-			ka.ctxs = append(ka.ctxs[:i], ka.ctxs[i+1:]...)
-			ka.chs = append(ka.chs[:i], ka.chs[i+1:]...)
-			break
-		}
-	}
-	// remove if no one more listeners
-	if len(ka.chs) == 0 {
-		delete(l.keepAlives, id)
-	}
-}
-
-// closeRequireLeader scans keepAlives for ctxs that have require leader
-// and closes the associated channels.
-func (l *lessor) closeRequireLeader() {
-	l.mu.Lock()
-	defer l.mu.Unlock()
-	for _, ka := range l.keepAlives {
-		reqIdxs := 0
-		// find all required leader channels, close, mark as nil
-		for i, ctx := range ka.ctxs {
-			md, ok := metadata.FromOutgoingContext(ctx)
-			if !ok {
-				continue
-			}
-			ks := md[rpctypes.MetadataRequireLeaderKey]
-			if len(ks) < 1 || ks[0] != rpctypes.MetadataHasLeader {
-				continue
-			}
-			close(ka.chs[i])
-			ka.chs[i] = nil
-			reqIdxs++
-		}
-		if reqIdxs == 0 {
-			continue
-		}
-		// remove all channels that required a leader from keepalive
-		newChs := make([]chan<- *LeaseKeepAliveResponse, len(ka.chs)-reqIdxs)
-		newCtxs := make([]context.Context, len(newChs))
-		newIdx := 0
-		for i := range ka.chs {
-			if ka.chs[i] == nil {
-				continue
-			}
-			newChs[newIdx], newCtxs[newIdx] = ka.chs[i], ka.ctxs[newIdx]
-			newIdx++
-		}
-		ka.chs, ka.ctxs = newChs, newCtxs
-	}
-}
-
-func (l *lessor) keepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error) {
-	cctx, cancel := context.WithCancel(ctx)
-	defer cancel()
-
-	stream, err := l.remote.LeaseKeepAlive(cctx, l.callOpts...)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-
-	err = stream.Send(&pb.LeaseKeepAliveRequest{ID: int64(id)})
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-
-	resp, rerr := stream.Recv()
-	if rerr != nil {
-		return nil, toErr(ctx, rerr)
-	}
-
-	karesp := &LeaseKeepAliveResponse{
-		ResponseHeader: resp.GetHeader(),
-		ID:             LeaseID(resp.ID),
-		TTL:            resp.TTL,
-	}
-	return karesp, nil
-}
-
-func (l *lessor) recvKeepAliveLoop() (gerr error) {
-	defer func() {
-		l.mu.Lock()
-		close(l.donec)
-		l.loopErr = gerr
-		for _, ka := range l.keepAlives {
-			ka.close()
-		}
-		l.keepAlives = make(map[LeaseID]*keepAlive)
-		l.mu.Unlock()
-	}()
-
-	for {
-		stream, err := l.resetRecv()
-		if err != nil {
-			if canceledByCaller(l.stopCtx, err) {
-				return err
-			}
-		} else {
-			for {
-				resp, err := stream.Recv()
-				if err != nil {
-					if canceledByCaller(l.stopCtx, err) {
-						return err
-					}
-
-					if toErr(l.stopCtx, err) == rpctypes.ErrNoLeader {
-						l.closeRequireLeader()
-					}
-					break
-				}
-
-				l.recvKeepAlive(resp)
-			}
-		}
-
-		select {
-		case <-time.After(retryConnWait):
-			continue
-		case <-l.stopCtx.Done():
-			return l.stopCtx.Err()
-		}
-	}
-}
-
-// resetRecv opens a new lease stream and starts sending keep alive requests.
-func (l *lessor) resetRecv() (pb.Lease_LeaseKeepAliveClient, error) {
-	sctx, cancel := context.WithCancel(l.stopCtx)
-	stream, err := l.remote.LeaseKeepAlive(sctx, l.callOpts...)
-	if err != nil {
-		cancel()
-		return nil, err
-	}
-
-	l.mu.Lock()
-	defer l.mu.Unlock()
-	if l.stream != nil && l.streamCancel != nil {
-		l.streamCancel()
-	}
-
-	l.streamCancel = cancel
-	l.stream = stream
-
-	go l.sendKeepAliveLoop(stream)
-	return stream, nil
-}
-
-// recvKeepAlive updates a lease based on its LeaseKeepAliveResponse
-func (l *lessor) recvKeepAlive(resp *pb.LeaseKeepAliveResponse) {
-	karesp := &LeaseKeepAliveResponse{
-		ResponseHeader: resp.GetHeader(),
-		ID:             LeaseID(resp.ID),
-		TTL:            resp.TTL,
-	}
-
-	l.mu.Lock()
-	defer l.mu.Unlock()
-
-	ka, ok := l.keepAlives[karesp.ID]
-	if !ok {
-		return
-	}
-
-	if karesp.TTL <= 0 {
-		// lease expired; close all keep alive channels
-		delete(l.keepAlives, karesp.ID)
-		ka.close()
-		return
-	}
-
-	// send update to all channels
-	nextKeepAlive := time.Now().Add((time.Duration(karesp.TTL) * time.Second) / 3.0)
-	ka.deadline = time.Now().Add(time.Duration(karesp.TTL) * time.Second)
-	for _, ch := range ka.chs {
-		select {
-		case ch <- karesp:
-		default:
-		}
-		// still advance in order to rate-limit keep-alive sends
-		ka.nextKeepAlive = nextKeepAlive
-	}
-}
-
-// deadlineLoop reaps any keep alive channels that have not received a response
-// within the lease TTL
-func (l *lessor) deadlineLoop() {
-	for {
-		select {
-		case <-time.After(time.Second):
-		case <-l.donec:
-			return
-		}
-		now := time.Now()
-		l.mu.Lock()
-		for id, ka := range l.keepAlives {
-			if ka.deadline.Before(now) {
-				// waited too long for response; lease may be expired
-				ka.close()
-				delete(l.keepAlives, id)
-			}
-		}
-		l.mu.Unlock()
-	}
-}
-
-// sendKeepAliveLoop sends keep alive requests for the lifetime of the given stream.
-func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) {
-	for {
-		var tosend []LeaseID
-
-		now := time.Now()
-		l.mu.Lock()
-		for id, ka := range l.keepAlives {
-			if ka.nextKeepAlive.Before(now) {
-				tosend = append(tosend, id)
-			}
-		}
-		l.mu.Unlock()
-
-		for _, id := range tosend {
-			r := &pb.LeaseKeepAliveRequest{ID: int64(id)}
-			if err := stream.Send(r); err != nil {
-				// TODO do something with this error?
-				return
-			}
-		}
-
-		select {
-		case <-time.After(500 * time.Millisecond):
-		case <-stream.Context().Done():
-			return
-		case <-l.donec:
-			return
-		case <-l.stopCtx.Done():
-			return
-		}
-	}
-}
-
-func (ka *keepAlive) close() {
-	close(ka.donec)
-	for _, ch := range ka.chs {
-		close(ch)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/leasing/cache.go b/vendor/github.com/coreos/etcd/clientv3/leasing/cache.go
deleted file mode 100644
index 6903a78..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/leasing/cache.go
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package leasing
-
-import (
-	"context"
-	"strings"
-	"sync"
-	"time"
-
-	v3 "github.com/coreos/etcd/clientv3"
-	v3pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-const revokeBackoff = 2 * time.Second
-
-type leaseCache struct {
-	mu      sync.RWMutex
-	entries map[string]*leaseKey
-	revokes map[string]time.Time
-	header  *v3pb.ResponseHeader
-}
-
-type leaseKey struct {
-	response *v3.GetResponse
-	// rev is the leasing key revision.
-	rev   int64
-	waitc chan struct{}
-}
-
-func (lc *leaseCache) Rev(key string) int64 {
-	lc.mu.RLock()
-	defer lc.mu.RUnlock()
-	if li := lc.entries[key]; li != nil {
-		return li.rev
-	}
-	return 0
-}
-
-func (lc *leaseCache) Lock(key string) (chan<- struct{}, int64) {
-	lc.mu.Lock()
-	defer lc.mu.Unlock()
-	if li := lc.entries[key]; li != nil {
-		li.waitc = make(chan struct{})
-		return li.waitc, li.rev
-	}
-	return nil, 0
-}
-
-func (lc *leaseCache) LockRange(begin, end string) (ret []chan<- struct{}) {
-	lc.mu.Lock()
-	defer lc.mu.Unlock()
-	for k, li := range lc.entries {
-		if inRange(k, begin, end) {
-			li.waitc = make(chan struct{})
-			ret = append(ret, li.waitc)
-		}
-	}
-	return ret
-}
-
-func inRange(k, begin, end string) bool {
-	if strings.Compare(k, begin) < 0 {
-		return false
-	}
-	if end != "\x00" && strings.Compare(k, end) >= 0 {
-		return false
-	}
-	return true
-}
-
-func (lc *leaseCache) LockWriteOps(ops []v3.Op) (ret []chan<- struct{}) {
-	for _, op := range ops {
-		if op.IsGet() {
-			continue
-		}
-		key := string(op.KeyBytes())
-		if end := string(op.RangeBytes()); end == "" {
-			if wc, _ := lc.Lock(key); wc != nil {
-				ret = append(ret, wc)
-			}
-		} else {
-			for k := range lc.entries {
-				if !inRange(k, key, end) {
-					continue
-				}
-				if wc, _ := lc.Lock(k); wc != nil {
-					ret = append(ret, wc)
-				}
-			}
-		}
-	}
-	return ret
-}
-
-func (lc *leaseCache) NotifyOps(ops []v3.Op) (wcs []<-chan struct{}) {
-	for _, op := range ops {
-		if op.IsGet() {
-			if _, wc := lc.notify(string(op.KeyBytes())); wc != nil {
-				wcs = append(wcs, wc)
-			}
-		}
-	}
-	return wcs
-}
-
-func (lc *leaseCache) MayAcquire(key string) bool {
-	lc.mu.RLock()
-	lr, ok := lc.revokes[key]
-	lc.mu.RUnlock()
-	return !ok || time.Since(lr) > revokeBackoff
-}
-
-func (lc *leaseCache) Add(key string, resp *v3.GetResponse, op v3.Op) *v3.GetResponse {
-	lk := &leaseKey{resp, resp.Header.Revision, closedCh}
-	lc.mu.Lock()
-	if lc.header == nil || lc.header.Revision < resp.Header.Revision {
-		lc.header = resp.Header
-	}
-	lc.entries[key] = lk
-	ret := lk.get(op)
-	lc.mu.Unlock()
-	return ret
-}
-
-func (lc *leaseCache) Update(key, val []byte, respHeader *v3pb.ResponseHeader) {
-	li := lc.entries[string(key)]
-	if li == nil {
-		return
-	}
-	cacheResp := li.response
-	if len(cacheResp.Kvs) == 0 {
-		kv := &mvccpb.KeyValue{
-			Key:            key,
-			CreateRevision: respHeader.Revision,
-		}
-		cacheResp.Kvs = append(cacheResp.Kvs, kv)
-		cacheResp.Count = 1
-	}
-	cacheResp.Kvs[0].Version++
-	if cacheResp.Kvs[0].ModRevision < respHeader.Revision {
-		cacheResp.Header = respHeader
-		cacheResp.Kvs[0].ModRevision = respHeader.Revision
-		cacheResp.Kvs[0].Value = val
-	}
-}
-
-func (lc *leaseCache) Delete(key string, hdr *v3pb.ResponseHeader) {
-	lc.mu.Lock()
-	defer lc.mu.Unlock()
-	lc.delete(key, hdr)
-}
-
-func (lc *leaseCache) delete(key string, hdr *v3pb.ResponseHeader) {
-	if li := lc.entries[key]; li != nil && hdr.Revision >= li.response.Header.Revision {
-		li.response.Kvs = nil
-		li.response.Header = copyHeader(hdr)
-	}
-}
-
-func (lc *leaseCache) Evict(key string) (rev int64) {
-	lc.mu.Lock()
-	defer lc.mu.Unlock()
-	if li := lc.entries[key]; li != nil {
-		rev = li.rev
-		delete(lc.entries, key)
-		lc.revokes[key] = time.Now()
-	}
-	return rev
-}
-
-func (lc *leaseCache) EvictRange(key, end string) {
-	lc.mu.Lock()
-	defer lc.mu.Unlock()
-	for k := range lc.entries {
-		if inRange(k, key, end) {
-			delete(lc.entries, key)
-			lc.revokes[key] = time.Now()
-		}
-	}
-}
-
-func isBadOp(op v3.Op) bool { return op.Rev() > 0 || len(op.RangeBytes()) > 0 }
-
-func (lc *leaseCache) Get(ctx context.Context, op v3.Op) (*v3.GetResponse, bool) {
-	if isBadOp(op) {
-		return nil, false
-	}
-	key := string(op.KeyBytes())
-	li, wc := lc.notify(key)
-	if li == nil {
-		return nil, true
-	}
-	select {
-	case <-wc:
-	case <-ctx.Done():
-		return nil, true
-	}
-	lc.mu.RLock()
-	lk := *li
-	ret := lk.get(op)
-	lc.mu.RUnlock()
-	return ret, true
-}
-
-func (lk *leaseKey) get(op v3.Op) *v3.GetResponse {
-	ret := *lk.response
-	ret.Header = copyHeader(ret.Header)
-	empty := len(ret.Kvs) == 0 || op.IsCountOnly()
-	empty = empty || (op.MinModRev() > ret.Kvs[0].ModRevision)
-	empty = empty || (op.MaxModRev() != 0 && op.MaxModRev() < ret.Kvs[0].ModRevision)
-	empty = empty || (op.MinCreateRev() > ret.Kvs[0].CreateRevision)
-	empty = empty || (op.MaxCreateRev() != 0 && op.MaxCreateRev() < ret.Kvs[0].CreateRevision)
-	if empty {
-		ret.Kvs = nil
-	} else {
-		kv := *ret.Kvs[0]
-		kv.Key = make([]byte, len(kv.Key))
-		copy(kv.Key, ret.Kvs[0].Key)
-		if !op.IsKeysOnly() {
-			kv.Value = make([]byte, len(kv.Value))
-			copy(kv.Value, ret.Kvs[0].Value)
-		}
-		ret.Kvs = []*mvccpb.KeyValue{&kv}
-	}
-	return &ret
-}
-
-func (lc *leaseCache) notify(key string) (*leaseKey, <-chan struct{}) {
-	lc.mu.RLock()
-	defer lc.mu.RUnlock()
-	if li := lc.entries[key]; li != nil {
-		return li, li.waitc
-	}
-	return nil, nil
-}
-
-func (lc *leaseCache) clearOldRevokes(ctx context.Context) {
-	for {
-		select {
-		case <-ctx.Done():
-			return
-		case <-time.After(time.Second):
-			lc.mu.Lock()
-			for k, lr := range lc.revokes {
-				if time.Now().Sub(lr.Add(revokeBackoff)) > 0 {
-					delete(lc.revokes, k)
-				}
-			}
-			lc.mu.Unlock()
-		}
-	}
-}
-
-func (lc *leaseCache) evalCmp(cmps []v3.Cmp) (cmpVal bool, ok bool) {
-	for _, cmp := range cmps {
-		if len(cmp.RangeEnd) > 0 {
-			return false, false
-		}
-		lk := lc.entries[string(cmp.Key)]
-		if lk == nil {
-			return false, false
-		}
-		if !evalCmp(lk.response, cmp) {
-			return false, true
-		}
-	}
-	return true, true
-}
-
-func (lc *leaseCache) evalOps(ops []v3.Op) ([]*v3pb.ResponseOp, bool) {
-	resps := make([]*v3pb.ResponseOp, len(ops))
-	for i, op := range ops {
-		if !op.IsGet() || isBadOp(op) {
-			// TODO: support read-only Txn
-			return nil, false
-		}
-		lk := lc.entries[string(op.KeyBytes())]
-		if lk == nil {
-			return nil, false
-		}
-		resp := lk.get(op)
-		if resp == nil {
-			return nil, false
-		}
-		resps[i] = &v3pb.ResponseOp{
-			Response: &v3pb.ResponseOp_ResponseRange{
-				(*v3pb.RangeResponse)(resp),
-			},
-		}
-	}
-	return resps, true
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/leasing/doc.go b/vendor/github.com/coreos/etcd/clientv3/leasing/doc.go
deleted file mode 100644
index fc97fc8..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/leasing/doc.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package leasing serves linearizable reads from a local cache by acquiring
-// exclusive write access to keys through a client-side leasing protocol. This
-// leasing layer can either directly wrap the etcd client or it can be exposed
-// through the etcd grpc proxy server, granting multiple clients write access.
-//
-// First, create a leasing KV from a clientv3.Client 'cli':
-//
-//     lkv, err := leasing.NewKV(cli, "leasing-prefix")
-//     if err != nil {
-//         // handle error
-//     }
-//
-// A range request for a key "abc" tries to acquire a leasing key so it can cache the range's
-// key locally. On the server, the leasing key is stored to "leasing-prefix/abc":
-//
-//     resp, err := lkv.Get(context.TODO(), "abc")
-//
-// Future linearized read requests using 'lkv' will be served locally for the lease's lifetime:
-//
-//     resp, err = lkv.Get(context.TODO(), "abc")
-//
-// If another leasing client writes to a leased key, then the owner relinquishes its exclusive
-// access, permitting the writer to modify the key:
-//
-//     lkv2, err := leasing.NewKV(cli, "leasing-prefix")
-//     if err != nil {
-//         // handle error
-//     }
-//     lkv2.Put(context.TODO(), "abc", "456")
-//     resp, err = lkv.Get("abc")
-//
-package leasing
diff --git a/vendor/github.com/coreos/etcd/clientv3/leasing/kv.go b/vendor/github.com/coreos/etcd/clientv3/leasing/kv.go
deleted file mode 100644
index 5a5e231..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/leasing/kv.go
+++ /dev/null
@@ -1,479 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package leasing
-
-import (
-	"context"
-	"strings"
-	"sync"
-	"time"
-
-	v3 "github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/clientv3/concurrency"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/status"
-)
-
-type leasingKV struct {
-	cl     *v3.Client
-	kv     v3.KV
-	pfx    string
-	leases leaseCache
-
-	ctx    context.Context
-	cancel context.CancelFunc
-	wg     sync.WaitGroup
-
-	sessionOpts []concurrency.SessionOption
-	session     *concurrency.Session
-	sessionc    chan struct{}
-}
-
-var closedCh chan struct{}
-
-func init() {
-	closedCh = make(chan struct{})
-	close(closedCh)
-}
-
-// NewKV wraps a KV instance so that all requests are wired through a leasing protocol.
-func NewKV(cl *v3.Client, pfx string, opts ...concurrency.SessionOption) (v3.KV, func(), error) {
-	cctx, cancel := context.WithCancel(cl.Ctx())
-	lkv := &leasingKV{
-		cl:          cl,
-		kv:          cl.KV,
-		pfx:         pfx,
-		leases:      leaseCache{revokes: make(map[string]time.Time)},
-		ctx:         cctx,
-		cancel:      cancel,
-		sessionOpts: opts,
-		sessionc:    make(chan struct{}),
-	}
-	lkv.wg.Add(2)
-	go func() {
-		defer lkv.wg.Done()
-		lkv.monitorSession()
-	}()
-	go func() {
-		defer lkv.wg.Done()
-		lkv.leases.clearOldRevokes(cctx)
-	}()
-	return lkv, lkv.Close, lkv.waitSession(cctx)
-}
-
-func (lkv *leasingKV) Close() {
-	lkv.cancel()
-	lkv.wg.Wait()
-}
-
-func (lkv *leasingKV) Get(ctx context.Context, key string, opts ...v3.OpOption) (*v3.GetResponse, error) {
-	return lkv.get(ctx, v3.OpGet(key, opts...))
-}
-
-func (lkv *leasingKV) Put(ctx context.Context, key, val string, opts ...v3.OpOption) (*v3.PutResponse, error) {
-	return lkv.put(ctx, v3.OpPut(key, val, opts...))
-}
-
-func (lkv *leasingKV) Delete(ctx context.Context, key string, opts ...v3.OpOption) (*v3.DeleteResponse, error) {
-	return lkv.delete(ctx, v3.OpDelete(key, opts...))
-}
-
-func (lkv *leasingKV) Do(ctx context.Context, op v3.Op) (v3.OpResponse, error) {
-	switch {
-	case op.IsGet():
-		resp, err := lkv.get(ctx, op)
-		return resp.OpResponse(), err
-	case op.IsPut():
-		resp, err := lkv.put(ctx, op)
-		return resp.OpResponse(), err
-	case op.IsDelete():
-		resp, err := lkv.delete(ctx, op)
-		return resp.OpResponse(), err
-	case op.IsTxn():
-		cmps, thenOps, elseOps := op.Txn()
-		resp, err := lkv.Txn(ctx).If(cmps...).Then(thenOps...).Else(elseOps...).Commit()
-		return resp.OpResponse(), err
-	}
-	return v3.OpResponse{}, nil
-}
-
-func (lkv *leasingKV) Compact(ctx context.Context, rev int64, opts ...v3.CompactOption) (*v3.CompactResponse, error) {
-	return lkv.kv.Compact(ctx, rev, opts...)
-}
-
-func (lkv *leasingKV) Txn(ctx context.Context) v3.Txn {
-	return &txnLeasing{Txn: lkv.kv.Txn(ctx), lkv: lkv, ctx: ctx}
-}
-
-func (lkv *leasingKV) monitorSession() {
-	for lkv.ctx.Err() == nil {
-		if lkv.session != nil {
-			select {
-			case <-lkv.session.Done():
-			case <-lkv.ctx.Done():
-				return
-			}
-		}
-		lkv.leases.mu.Lock()
-		select {
-		case <-lkv.sessionc:
-			lkv.sessionc = make(chan struct{})
-		default:
-		}
-		lkv.leases.entries = make(map[string]*leaseKey)
-		lkv.leases.mu.Unlock()
-
-		s, err := concurrency.NewSession(lkv.cl, lkv.sessionOpts...)
-		if err != nil {
-			continue
-		}
-
-		lkv.leases.mu.Lock()
-		lkv.session = s
-		close(lkv.sessionc)
-		lkv.leases.mu.Unlock()
-	}
-}
-
-func (lkv *leasingKV) monitorLease(ctx context.Context, key string, rev int64) {
-	cctx, cancel := context.WithCancel(lkv.ctx)
-	defer cancel()
-	for cctx.Err() == nil {
-		if rev == 0 {
-			resp, err := lkv.kv.Get(ctx, lkv.pfx+key)
-			if err != nil {
-				continue
-			}
-			rev = resp.Header.Revision
-			if len(resp.Kvs) == 0 || string(resp.Kvs[0].Value) == "REVOKE" {
-				lkv.rescind(cctx, key, rev)
-				return
-			}
-		}
-		wch := lkv.cl.Watch(cctx, lkv.pfx+key, v3.WithRev(rev+1))
-		for resp := range wch {
-			for _, ev := range resp.Events {
-				if string(ev.Kv.Value) != "REVOKE" {
-					continue
-				}
-				if v3.LeaseID(ev.Kv.Lease) == lkv.leaseID() {
-					lkv.rescind(cctx, key, ev.Kv.ModRevision)
-				}
-				return
-			}
-		}
-		rev = 0
-	}
-}
-
-// rescind releases a lease from this client.
-func (lkv *leasingKV) rescind(ctx context.Context, key string, rev int64) {
-	if lkv.leases.Evict(key) > rev {
-		return
-	}
-	cmp := v3.Compare(v3.CreateRevision(lkv.pfx+key), "<", rev)
-	op := v3.OpDelete(lkv.pfx + key)
-	for ctx.Err() == nil {
-		if _, err := lkv.kv.Txn(ctx).If(cmp).Then(op).Commit(); err == nil {
-			return
-		}
-	}
-}
-
-func (lkv *leasingKV) waitRescind(ctx context.Context, key string, rev int64) error {
-	cctx, cancel := context.WithCancel(ctx)
-	defer cancel()
-	wch := lkv.cl.Watch(cctx, lkv.pfx+key, v3.WithRev(rev+1))
-	for resp := range wch {
-		for _, ev := range resp.Events {
-			if ev.Type == v3.EventTypeDelete {
-				return ctx.Err()
-			}
-		}
-	}
-	return ctx.Err()
-}
-
-func (lkv *leasingKV) tryModifyOp(ctx context.Context, op v3.Op) (*v3.TxnResponse, chan<- struct{}, error) {
-	key := string(op.KeyBytes())
-	wc, rev := lkv.leases.Lock(key)
-	cmp := v3.Compare(v3.CreateRevision(lkv.pfx+key), "<", rev+1)
-	resp, err := lkv.kv.Txn(ctx).If(cmp).Then(op).Commit()
-	switch {
-	case err != nil:
-		lkv.leases.Evict(key)
-		fallthrough
-	case !resp.Succeeded:
-		if wc != nil {
-			close(wc)
-		}
-		return nil, nil, err
-	}
-	return resp, wc, nil
-}
-
-func (lkv *leasingKV) put(ctx context.Context, op v3.Op) (pr *v3.PutResponse, err error) {
-	if err := lkv.waitSession(ctx); err != nil {
-		return nil, err
-	}
-	for ctx.Err() == nil {
-		resp, wc, err := lkv.tryModifyOp(ctx, op)
-		if err != nil || wc == nil {
-			resp, err = lkv.revoke(ctx, string(op.KeyBytes()), op)
-		}
-		if err != nil {
-			return nil, err
-		}
-		if resp.Succeeded {
-			lkv.leases.mu.Lock()
-			lkv.leases.Update(op.KeyBytes(), op.ValueBytes(), resp.Header)
-			lkv.leases.mu.Unlock()
-			pr = (*v3.PutResponse)(resp.Responses[0].GetResponsePut())
-			pr.Header = resp.Header
-		}
-		if wc != nil {
-			close(wc)
-		}
-		if resp.Succeeded {
-			return pr, nil
-		}
-	}
-	return nil, ctx.Err()
-}
-
-func (lkv *leasingKV) acquire(ctx context.Context, key string, op v3.Op) (*v3.TxnResponse, error) {
-	for ctx.Err() == nil {
-		if err := lkv.waitSession(ctx); err != nil {
-			return nil, err
-		}
-		lcmp := v3.Cmp{Key: []byte(key), Target: pb.Compare_LEASE}
-		resp, err := lkv.kv.Txn(ctx).If(
-			v3.Compare(v3.CreateRevision(lkv.pfx+key), "=", 0),
-			v3.Compare(lcmp, "=", 0)).
-			Then(
-				op,
-				v3.OpPut(lkv.pfx+key, "", v3.WithLease(lkv.leaseID()))).
-			Else(
-				op,
-				v3.OpGet(lkv.pfx+key),
-			).Commit()
-		if err == nil {
-			if !resp.Succeeded {
-				kvs := resp.Responses[1].GetResponseRange().Kvs
-				// if txn failed since already owner, lease is acquired
-				resp.Succeeded = len(kvs) > 0 && v3.LeaseID(kvs[0].Lease) == lkv.leaseID()
-			}
-			return resp, nil
-		}
-		// retry if transient error
-		if _, ok := err.(rpctypes.EtcdError); ok {
-			return nil, err
-		}
-		if ev, _ := status.FromError(err); ev.Code() != codes.Unavailable {
-			return nil, err
-		}
-	}
-	return nil, ctx.Err()
-}
-
-func (lkv *leasingKV) get(ctx context.Context, op v3.Op) (*v3.GetResponse, error) {
-	do := func() (*v3.GetResponse, error) {
-		r, err := lkv.kv.Do(ctx, op)
-		return r.Get(), err
-	}
-	if !lkv.readySession() {
-		return do()
-	}
-
-	if resp, ok := lkv.leases.Get(ctx, op); resp != nil {
-		return resp, nil
-	} else if !ok || op.IsSerializable() {
-		// must be handled by server or can skip linearization
-		return do()
-	}
-
-	key := string(op.KeyBytes())
-	if !lkv.leases.MayAcquire(key) {
-		resp, err := lkv.kv.Do(ctx, op)
-		return resp.Get(), err
-	}
-
-	resp, err := lkv.acquire(ctx, key, v3.OpGet(key))
-	if err != nil {
-		return nil, err
-	}
-	getResp := (*v3.GetResponse)(resp.Responses[0].GetResponseRange())
-	getResp.Header = resp.Header
-	if resp.Succeeded {
-		getResp = lkv.leases.Add(key, getResp, op)
-		lkv.wg.Add(1)
-		go func() {
-			defer lkv.wg.Done()
-			lkv.monitorLease(ctx, key, resp.Header.Revision)
-		}()
-	}
-	return getResp, nil
-}
-
-func (lkv *leasingKV) deleteRangeRPC(ctx context.Context, maxLeaseRev int64, key, end string) (*v3.DeleteResponse, error) {
-	lkey, lend := lkv.pfx+key, lkv.pfx+end
-	resp, err := lkv.kv.Txn(ctx).If(
-		v3.Compare(v3.CreateRevision(lkey).WithRange(lend), "<", maxLeaseRev+1),
-	).Then(
-		v3.OpGet(key, v3.WithRange(end), v3.WithKeysOnly()),
-		v3.OpDelete(key, v3.WithRange(end)),
-	).Commit()
-	if err != nil {
-		lkv.leases.EvictRange(key, end)
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, nil
-	}
-	for _, kv := range resp.Responses[0].GetResponseRange().Kvs {
-		lkv.leases.Delete(string(kv.Key), resp.Header)
-	}
-	delResp := (*v3.DeleteResponse)(resp.Responses[1].GetResponseDeleteRange())
-	delResp.Header = resp.Header
-	return delResp, nil
-}
-
-func (lkv *leasingKV) deleteRange(ctx context.Context, op v3.Op) (*v3.DeleteResponse, error) {
-	key, end := string(op.KeyBytes()), string(op.RangeBytes())
-	for ctx.Err() == nil {
-		maxLeaseRev, err := lkv.revokeRange(ctx, key, end)
-		if err != nil {
-			return nil, err
-		}
-		wcs := lkv.leases.LockRange(key, end)
-		delResp, err := lkv.deleteRangeRPC(ctx, maxLeaseRev, key, end)
-		closeAll(wcs)
-		if err != nil || delResp != nil {
-			return delResp, err
-		}
-	}
-	return nil, ctx.Err()
-}
-
-func (lkv *leasingKV) delete(ctx context.Context, op v3.Op) (dr *v3.DeleteResponse, err error) {
-	if err := lkv.waitSession(ctx); err != nil {
-		return nil, err
-	}
-	if len(op.RangeBytes()) > 0 {
-		return lkv.deleteRange(ctx, op)
-	}
-	key := string(op.KeyBytes())
-	for ctx.Err() == nil {
-		resp, wc, err := lkv.tryModifyOp(ctx, op)
-		if err != nil || wc == nil {
-			resp, err = lkv.revoke(ctx, key, op)
-		}
-		if err != nil {
-			// don't know if delete was processed
-			lkv.leases.Evict(key)
-			return nil, err
-		}
-		if resp.Succeeded {
-			dr = (*v3.DeleteResponse)(resp.Responses[0].GetResponseDeleteRange())
-			dr.Header = resp.Header
-			lkv.leases.Delete(key, dr.Header)
-		}
-		if wc != nil {
-			close(wc)
-		}
-		if resp.Succeeded {
-			return dr, nil
-		}
-	}
-	return nil, ctx.Err()
-}
-
-func (lkv *leasingKV) revoke(ctx context.Context, key string, op v3.Op) (*v3.TxnResponse, error) {
-	rev := lkv.leases.Rev(key)
-	txn := lkv.kv.Txn(ctx).If(v3.Compare(v3.CreateRevision(lkv.pfx+key), "<", rev+1)).Then(op)
-	resp, err := txn.Else(v3.OpPut(lkv.pfx+key, "REVOKE", v3.WithIgnoreLease())).Commit()
-	if err != nil || resp.Succeeded {
-		return resp, err
-	}
-	return resp, lkv.waitRescind(ctx, key, resp.Header.Revision)
-}
-
-func (lkv *leasingKV) revokeRange(ctx context.Context, begin, end string) (int64, error) {
-	lkey, lend := lkv.pfx+begin, ""
-	if len(end) > 0 {
-		lend = lkv.pfx + end
-	}
-	leaseKeys, err := lkv.kv.Get(ctx, lkey, v3.WithRange(lend))
-	if err != nil {
-		return 0, err
-	}
-	return lkv.revokeLeaseKvs(ctx, leaseKeys.Kvs)
-}
-
-func (lkv *leasingKV) revokeLeaseKvs(ctx context.Context, kvs []*mvccpb.KeyValue) (int64, error) {
-	maxLeaseRev := int64(0)
-	for _, kv := range kvs {
-		if rev := kv.CreateRevision; rev > maxLeaseRev {
-			maxLeaseRev = rev
-		}
-		if v3.LeaseID(kv.Lease) == lkv.leaseID() {
-			// don't revoke own keys
-			continue
-		}
-		key := strings.TrimPrefix(string(kv.Key), lkv.pfx)
-		if _, err := lkv.revoke(ctx, key, v3.OpGet(key)); err != nil {
-			return 0, err
-		}
-	}
-	return maxLeaseRev, nil
-}
-
-func (lkv *leasingKV) waitSession(ctx context.Context) error {
-	lkv.leases.mu.RLock()
-	sessionc := lkv.sessionc
-	lkv.leases.mu.RUnlock()
-	select {
-	case <-sessionc:
-		return nil
-	case <-lkv.ctx.Done():
-		return lkv.ctx.Err()
-	case <-ctx.Done():
-		return ctx.Err()
-	}
-}
-
-func (lkv *leasingKV) readySession() bool {
-	lkv.leases.mu.RLock()
-	defer lkv.leases.mu.RUnlock()
-	if lkv.session == nil {
-		return false
-	}
-	select {
-	case <-lkv.session.Done():
-	default:
-		return true
-	}
-	return false
-}
-
-func (lkv *leasingKV) leaseID() v3.LeaseID {
-	lkv.leases.mu.RLock()
-	defer lkv.leases.mu.RUnlock()
-	return lkv.session.Lease()
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/leasing/txn.go b/vendor/github.com/coreos/etcd/clientv3/leasing/txn.go
deleted file mode 100644
index da5b83a..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/leasing/txn.go
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package leasing
-
-import (
-	"context"
-	"strings"
-
-	v3 "github.com/coreos/etcd/clientv3"
-	v3pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-type txnLeasing struct {
-	v3.Txn
-	lkv  *leasingKV
-	ctx  context.Context
-	cs   []v3.Cmp
-	opst []v3.Op
-	opse []v3.Op
-}
-
-func (txn *txnLeasing) If(cs ...v3.Cmp) v3.Txn {
-	txn.cs = append(txn.cs, cs...)
-	txn.Txn = txn.Txn.If(cs...)
-	return txn
-}
-
-func (txn *txnLeasing) Then(ops ...v3.Op) v3.Txn {
-	txn.opst = append(txn.opst, ops...)
-	txn.Txn = txn.Txn.Then(ops...)
-	return txn
-}
-
-func (txn *txnLeasing) Else(ops ...v3.Op) v3.Txn {
-	txn.opse = append(txn.opse, ops...)
-	txn.Txn = txn.Txn.Else(ops...)
-	return txn
-}
-
-func (txn *txnLeasing) Commit() (*v3.TxnResponse, error) {
-	if resp, err := txn.eval(); resp != nil || err != nil {
-		return resp, err
-	}
-	return txn.serverTxn()
-}
-
-func (txn *txnLeasing) eval() (*v3.TxnResponse, error) {
-	// TODO: wait on keys in comparisons
-	thenOps, elseOps := gatherOps(txn.opst), gatherOps(txn.opse)
-	ops := make([]v3.Op, 0, len(thenOps)+len(elseOps))
-	ops = append(ops, thenOps...)
-	ops = append(ops, elseOps...)
-
-	for _, ch := range txn.lkv.leases.NotifyOps(ops) {
-		select {
-		case <-ch:
-		case <-txn.ctx.Done():
-			return nil, txn.ctx.Err()
-		}
-	}
-
-	txn.lkv.leases.mu.RLock()
-	defer txn.lkv.leases.mu.RUnlock()
-	succeeded, ok := txn.lkv.leases.evalCmp(txn.cs)
-	if !ok || txn.lkv.leases.header == nil {
-		return nil, nil
-	}
-	if ops = txn.opst; !succeeded {
-		ops = txn.opse
-	}
-
-	resps, ok := txn.lkv.leases.evalOps(ops)
-	if !ok {
-		return nil, nil
-	}
-	return &v3.TxnResponse{copyHeader(txn.lkv.leases.header), succeeded, resps}, nil
-}
-
-// fallback computes the ops to fetch all possible conflicting
-// leasing keys for a list of ops.
-func (txn *txnLeasing) fallback(ops []v3.Op) (fbOps []v3.Op) {
-	for _, op := range ops {
-		if op.IsGet() {
-			continue
-		}
-		lkey, lend := txn.lkv.pfx+string(op.KeyBytes()), ""
-		if len(op.RangeBytes()) > 0 {
-			lend = txn.lkv.pfx + string(op.RangeBytes())
-		}
-		fbOps = append(fbOps, v3.OpGet(lkey, v3.WithRange(lend)))
-	}
-	return fbOps
-}
-
-func (txn *txnLeasing) guardKeys(ops []v3.Op) (cmps []v3.Cmp) {
-	seen := make(map[string]bool)
-	for _, op := range ops {
-		key := string(op.KeyBytes())
-		if op.IsGet() || len(op.RangeBytes()) != 0 || seen[key] {
-			continue
-		}
-		rev := txn.lkv.leases.Rev(key)
-		cmps = append(cmps, v3.Compare(v3.CreateRevision(txn.lkv.pfx+key), "<", rev+1))
-		seen[key] = true
-	}
-	return cmps
-}
-
-func (txn *txnLeasing) guardRanges(ops []v3.Op) (cmps []v3.Cmp, err error) {
-	for _, op := range ops {
-		if op.IsGet() || len(op.RangeBytes()) == 0 {
-			continue
-		}
-
-		key, end := string(op.KeyBytes()), string(op.RangeBytes())
-		maxRevLK, err := txn.lkv.revokeRange(txn.ctx, key, end)
-		if err != nil {
-			return nil, err
-		}
-
-		opts := append(v3.WithLastRev(), v3.WithRange(end))
-		getResp, err := txn.lkv.kv.Get(txn.ctx, key, opts...)
-		if err != nil {
-			return nil, err
-		}
-		maxModRev := int64(0)
-		if len(getResp.Kvs) > 0 {
-			maxModRev = getResp.Kvs[0].ModRevision
-		}
-
-		noKeyUpdate := v3.Compare(v3.ModRevision(key).WithRange(end), "<", maxModRev+1)
-		noLeaseUpdate := v3.Compare(
-			v3.CreateRevision(txn.lkv.pfx+key).WithRange(txn.lkv.pfx+end),
-			"<",
-			maxRevLK+1)
-		cmps = append(cmps, noKeyUpdate, noLeaseUpdate)
-	}
-	return cmps, nil
-}
-
-func (txn *txnLeasing) guard(ops []v3.Op) ([]v3.Cmp, error) {
-	cmps := txn.guardKeys(ops)
-	rangeCmps, err := txn.guardRanges(ops)
-	return append(cmps, rangeCmps...), err
-}
-
-func (txn *txnLeasing) commitToCache(txnResp *v3pb.TxnResponse, userTxn v3.Op) {
-	ops := gatherResponseOps(txnResp.Responses, []v3.Op{userTxn})
-	txn.lkv.leases.mu.Lock()
-	for _, op := range ops {
-		key := string(op.KeyBytes())
-		if op.IsDelete() && len(op.RangeBytes()) > 0 {
-			end := string(op.RangeBytes())
-			for k := range txn.lkv.leases.entries {
-				if inRange(k, key, end) {
-					txn.lkv.leases.delete(k, txnResp.Header)
-				}
-			}
-		} else if op.IsDelete() {
-			txn.lkv.leases.delete(key, txnResp.Header)
-		}
-		if op.IsPut() {
-			txn.lkv.leases.Update(op.KeyBytes(), op.ValueBytes(), txnResp.Header)
-		}
-	}
-	txn.lkv.leases.mu.Unlock()
-}
-
-func (txn *txnLeasing) revokeFallback(fbResps []*v3pb.ResponseOp) error {
-	for _, resp := range fbResps {
-		_, err := txn.lkv.revokeLeaseKvs(txn.ctx, resp.GetResponseRange().Kvs)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (txn *txnLeasing) serverTxn() (*v3.TxnResponse, error) {
-	if err := txn.lkv.waitSession(txn.ctx); err != nil {
-		return nil, err
-	}
-
-	userOps := gatherOps(append(txn.opst, txn.opse...))
-	userTxn := v3.OpTxn(txn.cs, txn.opst, txn.opse)
-	fbOps := txn.fallback(userOps)
-
-	defer closeAll(txn.lkv.leases.LockWriteOps(userOps))
-	for {
-		cmps, err := txn.guard(userOps)
-		if err != nil {
-			return nil, err
-		}
-		resp, err := txn.lkv.kv.Txn(txn.ctx).If(cmps...).Then(userTxn).Else(fbOps...).Commit()
-		if err != nil {
-			for _, cmp := range cmps {
-				txn.lkv.leases.Evict(strings.TrimPrefix(string(cmp.Key), txn.lkv.pfx))
-			}
-			return nil, err
-		}
-		if resp.Succeeded {
-			txn.commitToCache((*v3pb.TxnResponse)(resp), userTxn)
-			userResp := resp.Responses[0].GetResponseTxn()
-			userResp.Header = resp.Header
-			return (*v3.TxnResponse)(userResp), nil
-		}
-		if err := txn.revokeFallback(resp.Responses); err != nil {
-			return nil, err
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/leasing/util.go b/vendor/github.com/coreos/etcd/clientv3/leasing/util.go
deleted file mode 100644
index 61f6e8c..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/leasing/util.go
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package leasing
-
-import (
-	"bytes"
-
-	v3 "github.com/coreos/etcd/clientv3"
-	v3pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-func compareInt64(a, b int64) int {
-	switch {
-	case a < b:
-		return -1
-	case a > b:
-		return 1
-	default:
-		return 0
-	}
-}
-
-func evalCmp(resp *v3.GetResponse, tcmp v3.Cmp) bool {
-	var result int
-	if len(resp.Kvs) != 0 {
-		kv := resp.Kvs[0]
-		switch tcmp.Target {
-		case v3pb.Compare_VALUE:
-			if tv, _ := tcmp.TargetUnion.(*v3pb.Compare_Value); tv != nil {
-				result = bytes.Compare(kv.Value, tv.Value)
-			}
-		case v3pb.Compare_CREATE:
-			if tv, _ := tcmp.TargetUnion.(*v3pb.Compare_CreateRevision); tv != nil {
-				result = compareInt64(kv.CreateRevision, tv.CreateRevision)
-			}
-		case v3pb.Compare_MOD:
-			if tv, _ := tcmp.TargetUnion.(*v3pb.Compare_ModRevision); tv != nil {
-				result = compareInt64(kv.ModRevision, tv.ModRevision)
-			}
-		case v3pb.Compare_VERSION:
-			if tv, _ := tcmp.TargetUnion.(*v3pb.Compare_Version); tv != nil {
-				result = compareInt64(kv.Version, tv.Version)
-			}
-		}
-	}
-	switch tcmp.Result {
-	case v3pb.Compare_EQUAL:
-		return result == 0
-	case v3pb.Compare_NOT_EQUAL:
-		return result != 0
-	case v3pb.Compare_GREATER:
-		return result > 0
-	case v3pb.Compare_LESS:
-		return result < 0
-	}
-	return true
-}
-
-func gatherOps(ops []v3.Op) (ret []v3.Op) {
-	for _, op := range ops {
-		if !op.IsTxn() {
-			ret = append(ret, op)
-			continue
-		}
-		_, thenOps, elseOps := op.Txn()
-		ret = append(ret, gatherOps(append(thenOps, elseOps...))...)
-	}
-	return ret
-}
-
-func gatherResponseOps(resp []*v3pb.ResponseOp, ops []v3.Op) (ret []v3.Op) {
-	for i, op := range ops {
-		if !op.IsTxn() {
-			ret = append(ret, op)
-			continue
-		}
-		_, thenOps, elseOps := op.Txn()
-		if txnResp := resp[i].GetResponseTxn(); txnResp.Succeeded {
-			ret = append(ret, gatherResponseOps(txnResp.Responses, thenOps)...)
-		} else {
-			ret = append(ret, gatherResponseOps(txnResp.Responses, elseOps)...)
-		}
-	}
-	return ret
-}
-
-func copyHeader(hdr *v3pb.ResponseHeader) *v3pb.ResponseHeader {
-	h := *hdr
-	return &h
-}
-
-func closeAll(chs []chan<- struct{}) {
-	for _, ch := range chs {
-		close(ch)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/logger.go b/vendor/github.com/coreos/etcd/clientv3/logger.go
deleted file mode 100644
index 782e313..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/logger.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"io/ioutil"
-	"sync"
-
-	"google.golang.org/grpc/grpclog"
-)
-
-// Logger is the logger used by client library.
-// It implements grpclog.LoggerV2 interface.
-type Logger interface {
-	grpclog.LoggerV2
-
-	// Lvl returns logger if logger's verbosity level >= "lvl".
-	// Otherwise, logger that discards all logs.
-	Lvl(lvl int) Logger
-
-	// to satisfy capnslog
-
-	Print(args ...interface{})
-	Printf(format string, args ...interface{})
-	Println(args ...interface{})
-}
-
-var (
-	loggerMu sync.RWMutex
-	logger   Logger
-)
-
-type settableLogger struct {
-	l  grpclog.LoggerV2
-	mu sync.RWMutex
-}
-
-func init() {
-	// disable client side logs by default
-	logger = &settableLogger{}
-	SetLogger(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard))
-}
-
-// SetLogger sets client-side Logger.
-func SetLogger(l grpclog.LoggerV2) {
-	loggerMu.Lock()
-	logger = NewLogger(l)
-	// override grpclog so that any changes happen with locking
-	grpclog.SetLoggerV2(logger)
-	loggerMu.Unlock()
-}
-
-// GetLogger returns the current logger.
-func GetLogger() Logger {
-	loggerMu.RLock()
-	l := logger
-	loggerMu.RUnlock()
-	return l
-}
-
-// NewLogger returns a new Logger with grpclog.LoggerV2.
-func NewLogger(gl grpclog.LoggerV2) Logger {
-	return &settableLogger{l: gl}
-}
-
-func (s *settableLogger) get() grpclog.LoggerV2 {
-	s.mu.RLock()
-	l := s.l
-	s.mu.RUnlock()
-	return l
-}
-
-// implement the grpclog.LoggerV2 interface
-
-func (s *settableLogger) Info(args ...interface{})                 { s.get().Info(args...) }
-func (s *settableLogger) Infof(format string, args ...interface{}) { s.get().Infof(format, args...) }
-func (s *settableLogger) Infoln(args ...interface{})               { s.get().Infoln(args...) }
-func (s *settableLogger) Warning(args ...interface{})              { s.get().Warning(args...) }
-func (s *settableLogger) Warningf(format string, args ...interface{}) {
-	s.get().Warningf(format, args...)
-}
-func (s *settableLogger) Warningln(args ...interface{}) { s.get().Warningln(args...) }
-func (s *settableLogger) Error(args ...interface{})     { s.get().Error(args...) }
-func (s *settableLogger) Errorf(format string, args ...interface{}) {
-	s.get().Errorf(format, args...)
-}
-func (s *settableLogger) Errorln(args ...interface{})               { s.get().Errorln(args...) }
-func (s *settableLogger) Fatal(args ...interface{})                 { s.get().Fatal(args...) }
-func (s *settableLogger) Fatalf(format string, args ...interface{}) { s.get().Fatalf(format, args...) }
-func (s *settableLogger) Fatalln(args ...interface{})               { s.get().Fatalln(args...) }
-func (s *settableLogger) Print(args ...interface{})                 { s.get().Info(args...) }
-func (s *settableLogger) Printf(format string, args ...interface{}) { s.get().Infof(format, args...) }
-func (s *settableLogger) Println(args ...interface{})               { s.get().Infoln(args...) }
-func (s *settableLogger) V(l int) bool                              { return s.get().V(l) }
-func (s *settableLogger) Lvl(lvl int) Logger {
-	s.mu.RLock()
-	l := s.l
-	s.mu.RUnlock()
-	if l.V(lvl) {
-		return s
-	}
-	return &noLogger{}
-}
-
-type noLogger struct{}
-
-func (*noLogger) Info(args ...interface{})                    {}
-func (*noLogger) Infof(format string, args ...interface{})    {}
-func (*noLogger) Infoln(args ...interface{})                  {}
-func (*noLogger) Warning(args ...interface{})                 {}
-func (*noLogger) Warningf(format string, args ...interface{}) {}
-func (*noLogger) Warningln(args ...interface{})               {}
-func (*noLogger) Error(args ...interface{})                   {}
-func (*noLogger) Errorf(format string, args ...interface{})   {}
-func (*noLogger) Errorln(args ...interface{})                 {}
-func (*noLogger) Fatal(args ...interface{})                   {}
-func (*noLogger) Fatalf(format string, args ...interface{})   {}
-func (*noLogger) Fatalln(args ...interface{})                 {}
-func (*noLogger) Print(args ...interface{})                   {}
-func (*noLogger) Printf(format string, args ...interface{})   {}
-func (*noLogger) Println(args ...interface{})                 {}
-func (*noLogger) V(l int) bool                                { return false }
-func (ng *noLogger) Lvl(lvl int) Logger                       { return ng }
diff --git a/vendor/github.com/coreos/etcd/clientv3/maintenance.go b/vendor/github.com/coreos/etcd/clientv3/maintenance.go
deleted file mode 100644
index f60cfbe..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/maintenance.go
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-	"io"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-)
-
-type (
-	DefragmentResponse pb.DefragmentResponse
-	AlarmResponse      pb.AlarmResponse
-	AlarmMember        pb.AlarmMember
-	StatusResponse     pb.StatusResponse
-	HashKVResponse     pb.HashKVResponse
-	MoveLeaderResponse pb.MoveLeaderResponse
-)
-
-type Maintenance interface {
-	// AlarmList gets all active alarms.
-	AlarmList(ctx context.Context) (*AlarmResponse, error)
-
-	// AlarmDisarm disarms a given alarm.
-	AlarmDisarm(ctx context.Context, m *AlarmMember) (*AlarmResponse, error)
-
-	// Defragment releases wasted space from internal fragmentation on a given etcd member.
-	// Defragment is only needed when deleting a large number of keys and want to reclaim
-	// the resources.
-	// Defragment is an expensive operation. User should avoid defragmenting multiple members
-	// at the same time.
-	// To defragment multiple members in the cluster, user need to call defragment multiple
-	// times with different endpoints.
-	Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error)
-
-	// Status gets the status of the endpoint.
-	Status(ctx context.Context, endpoint string) (*StatusResponse, error)
-
-	// HashKV returns a hash of the KV state at the time of the RPC.
-	// If revision is zero, the hash is computed on all keys. If the revision
-	// is non-zero, the hash is computed on all keys at or below the given revision.
-	HashKV(ctx context.Context, endpoint string, rev int64) (*HashKVResponse, error)
-
-	// Snapshot provides a reader for a point-in-time snapshot of etcd.
-	Snapshot(ctx context.Context) (io.ReadCloser, error)
-
-	// MoveLeader requests current leader to transfer its leadership to the transferee.
-	// Request must be made to the leader.
-	MoveLeader(ctx context.Context, transfereeID uint64) (*MoveLeaderResponse, error)
-}
-
-type maintenance struct {
-	dial     func(endpoint string) (pb.MaintenanceClient, func(), error)
-	remote   pb.MaintenanceClient
-	callOpts []grpc.CallOption
-}
-
-func NewMaintenance(c *Client) Maintenance {
-	api := &maintenance{
-		dial: func(endpoint string) (pb.MaintenanceClient, func(), error) {
-			conn, err := c.dial(endpoint)
-			if err != nil {
-				return nil, nil, err
-			}
-			cancel := func() { conn.Close() }
-			return RetryMaintenanceClient(c, conn), cancel, nil
-		},
-		remote: RetryMaintenanceClient(c, c.conn),
-	}
-	if c != nil {
-		api.callOpts = c.callOpts
-	}
-	return api
-}
-
-func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient, c *Client) Maintenance {
-	api := &maintenance{
-		dial: func(string) (pb.MaintenanceClient, func(), error) {
-			return remote, func() {}, nil
-		},
-		remote: remote,
-	}
-	if c != nil {
-		api.callOpts = c.callOpts
-	}
-	return api
-}
-
-func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) {
-	req := &pb.AlarmRequest{
-		Action:   pb.AlarmRequest_GET,
-		MemberID: 0,                 // all
-		Alarm:    pb.AlarmType_NONE, // all
-	}
-	resp, err := m.remote.Alarm(ctx, req, m.callOpts...)
-	if err == nil {
-		return (*AlarmResponse)(resp), nil
-	}
-	return nil, toErr(ctx, err)
-}
-
-func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember) (*AlarmResponse, error) {
-	req := &pb.AlarmRequest{
-		Action:   pb.AlarmRequest_DEACTIVATE,
-		MemberID: am.MemberID,
-		Alarm:    am.Alarm,
-	}
-
-	if req.MemberID == 0 && req.Alarm == pb.AlarmType_NONE {
-		ar, err := m.AlarmList(ctx)
-		if err != nil {
-			return nil, toErr(ctx, err)
-		}
-		ret := AlarmResponse{}
-		for _, am := range ar.Alarms {
-			dresp, derr := m.AlarmDisarm(ctx, (*AlarmMember)(am))
-			if derr != nil {
-				return nil, toErr(ctx, derr)
-			}
-			ret.Alarms = append(ret.Alarms, dresp.Alarms...)
-		}
-		return &ret, nil
-	}
-
-	resp, err := m.remote.Alarm(ctx, req, m.callOpts...)
-	if err == nil {
-		return (*AlarmResponse)(resp), nil
-	}
-	return nil, toErr(ctx, err)
-}
-
-func (m *maintenance) Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error) {
-	remote, cancel, err := m.dial(endpoint)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-	defer cancel()
-	resp, err := remote.Defragment(ctx, &pb.DefragmentRequest{}, m.callOpts...)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-	return (*DefragmentResponse)(resp), nil
-}
-
-func (m *maintenance) Status(ctx context.Context, endpoint string) (*StatusResponse, error) {
-	remote, cancel, err := m.dial(endpoint)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-	defer cancel()
-	resp, err := remote.Status(ctx, &pb.StatusRequest{}, m.callOpts...)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-	return (*StatusResponse)(resp), nil
-}
-
-func (m *maintenance) HashKV(ctx context.Context, endpoint string, rev int64) (*HashKVResponse, error) {
-	remote, cancel, err := m.dial(endpoint)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-	defer cancel()
-	resp, err := remote.HashKV(ctx, &pb.HashKVRequest{Revision: rev}, m.callOpts...)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-	return (*HashKVResponse)(resp), nil
-}
-
-func (m *maintenance) Snapshot(ctx context.Context) (io.ReadCloser, error) {
-	ss, err := m.remote.Snapshot(ctx, &pb.SnapshotRequest{}, m.callOpts...)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-
-	pr, pw := io.Pipe()
-	go func() {
-		for {
-			resp, err := ss.Recv()
-			if err != nil {
-				pw.CloseWithError(err)
-				return
-			}
-			if resp == nil && err == nil {
-				break
-			}
-			if _, werr := pw.Write(resp.Blob); werr != nil {
-				pw.CloseWithError(werr)
-				return
-			}
-		}
-		pw.Close()
-	}()
-	return &snapshotReadCloser{ctx: ctx, ReadCloser: pr}, nil
-}
-
-type snapshotReadCloser struct {
-	ctx context.Context
-	io.ReadCloser
-}
-
-func (rc *snapshotReadCloser) Read(p []byte) (n int, err error) {
-	n, err = rc.ReadCloser.Read(p)
-	return n, toErr(rc.ctx, err)
-}
-
-func (m *maintenance) MoveLeader(ctx context.Context, transfereeID uint64) (*MoveLeaderResponse, error) {
-	resp, err := m.remote.MoveLeader(ctx, &pb.MoveLeaderRequest{TargetID: transfereeID}, m.callOpts...)
-	return (*MoveLeaderResponse)(resp), toErr(ctx, err)
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/namespace/doc.go b/vendor/github.com/coreos/etcd/clientv3/namespace/doc.go
deleted file mode 100644
index 3f88332..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/namespace/doc.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package namespace is a clientv3 wrapper that translates all keys to begin
-// with a given prefix.
-//
-// First, create a client:
-//
-//	cli, err := clientv3.New(clientv3.Config{Endpoints: []string{"localhost:2379"}})
-//	if err != nil {
-//		// handle error!
-//	}
-//
-// Next, override the client interfaces:
-//
-//	unprefixedKV := cli.KV
-//	cli.KV = namespace.NewKV(cli.KV, "my-prefix/")
-//	cli.Watcher = namespace.NewWatcher(cli.Watcher, "my-prefix/")
-//	cli.Lease = namespace.NewLease(cli.Lease, "my-prefix/")
-//
-// Now calls using 'cli' will namespace / prefix all keys with "my-prefix/":
-//
-//	cli.Put(context.TODO(), "abc", "123")
-//	resp, _ := unprefixedKV.Get(context.TODO(), "my-prefix/abc")
-//	fmt.Printf("%s\n", resp.Kvs[0].Value)
-//	// Output: 123
-//	unprefixedKV.Put(context.TODO(), "my-prefix/abc", "456")
-//	resp, _ = cli.Get("abc")
-//	fmt.Printf("%s\n", resp.Kvs[0].Value)
-//	// Output: 456
-//
-package namespace
diff --git a/vendor/github.com/coreos/etcd/clientv3/namespace/kv.go b/vendor/github.com/coreos/etcd/clientv3/namespace/kv.go
deleted file mode 100644
index 13dd83a..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/namespace/kv.go
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package namespace
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-type kvPrefix struct {
-	clientv3.KV
-	pfx string
-}
-
-// NewKV wraps a KV instance so that all requests
-// are prefixed with a given string.
-func NewKV(kv clientv3.KV, prefix string) clientv3.KV {
-	return &kvPrefix{kv, prefix}
-}
-
-func (kv *kvPrefix) Put(ctx context.Context, key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error) {
-	if len(key) == 0 {
-		return nil, rpctypes.ErrEmptyKey
-	}
-	op := kv.prefixOp(clientv3.OpPut(key, val, opts...))
-	r, err := kv.KV.Do(ctx, op)
-	if err != nil {
-		return nil, err
-	}
-	put := r.Put()
-	kv.unprefixPutResponse(put)
-	return put, nil
-}
-
-func (kv *kvPrefix) Get(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.GetResponse, error) {
-	if len(key) == 0 {
-		return nil, rpctypes.ErrEmptyKey
-	}
-	r, err := kv.KV.Do(ctx, kv.prefixOp(clientv3.OpGet(key, opts...)))
-	if err != nil {
-		return nil, err
-	}
-	get := r.Get()
-	kv.unprefixGetResponse(get)
-	return get, nil
-}
-
-func (kv *kvPrefix) Delete(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.DeleteResponse, error) {
-	if len(key) == 0 {
-		return nil, rpctypes.ErrEmptyKey
-	}
-	r, err := kv.KV.Do(ctx, kv.prefixOp(clientv3.OpDelete(key, opts...)))
-	if err != nil {
-		return nil, err
-	}
-	del := r.Del()
-	kv.unprefixDeleteResponse(del)
-	return del, nil
-}
-
-func (kv *kvPrefix) Do(ctx context.Context, op clientv3.Op) (clientv3.OpResponse, error) {
-	if len(op.KeyBytes()) == 0 && !op.IsTxn() {
-		return clientv3.OpResponse{}, rpctypes.ErrEmptyKey
-	}
-	r, err := kv.KV.Do(ctx, kv.prefixOp(op))
-	if err != nil {
-		return r, err
-	}
-	switch {
-	case r.Get() != nil:
-		kv.unprefixGetResponse(r.Get())
-	case r.Put() != nil:
-		kv.unprefixPutResponse(r.Put())
-	case r.Del() != nil:
-		kv.unprefixDeleteResponse(r.Del())
-	case r.Txn() != nil:
-		kv.unprefixTxnResponse(r.Txn())
-	}
-	return r, nil
-}
-
-type txnPrefix struct {
-	clientv3.Txn
-	kv *kvPrefix
-}
-
-func (kv *kvPrefix) Txn(ctx context.Context) clientv3.Txn {
-	return &txnPrefix{kv.KV.Txn(ctx), kv}
-}
-
-func (txn *txnPrefix) If(cs ...clientv3.Cmp) clientv3.Txn {
-	txn.Txn = txn.Txn.If(txn.kv.prefixCmps(cs)...)
-	return txn
-}
-
-func (txn *txnPrefix) Then(ops ...clientv3.Op) clientv3.Txn {
-	txn.Txn = txn.Txn.Then(txn.kv.prefixOps(ops)...)
-	return txn
-}
-
-func (txn *txnPrefix) Else(ops ...clientv3.Op) clientv3.Txn {
-	txn.Txn = txn.Txn.Else(txn.kv.prefixOps(ops)...)
-	return txn
-}
-
-func (txn *txnPrefix) Commit() (*clientv3.TxnResponse, error) {
-	resp, err := txn.Txn.Commit()
-	if err != nil {
-		return nil, err
-	}
-	txn.kv.unprefixTxnResponse(resp)
-	return resp, nil
-}
-
-func (kv *kvPrefix) prefixOp(op clientv3.Op) clientv3.Op {
-	if !op.IsTxn() {
-		begin, end := kv.prefixInterval(op.KeyBytes(), op.RangeBytes())
-		op.WithKeyBytes(begin)
-		op.WithRangeBytes(end)
-		return op
-	}
-	cmps, thenOps, elseOps := op.Txn()
-	return clientv3.OpTxn(kv.prefixCmps(cmps), kv.prefixOps(thenOps), kv.prefixOps(elseOps))
-}
-
-func (kv *kvPrefix) unprefixGetResponse(resp *clientv3.GetResponse) {
-	for i := range resp.Kvs {
-		resp.Kvs[i].Key = resp.Kvs[i].Key[len(kv.pfx):]
-	}
-}
-
-func (kv *kvPrefix) unprefixPutResponse(resp *clientv3.PutResponse) {
-	if resp.PrevKv != nil {
-		resp.PrevKv.Key = resp.PrevKv.Key[len(kv.pfx):]
-	}
-}
-
-func (kv *kvPrefix) unprefixDeleteResponse(resp *clientv3.DeleteResponse) {
-	for i := range resp.PrevKvs {
-		resp.PrevKvs[i].Key = resp.PrevKvs[i].Key[len(kv.pfx):]
-	}
-}
-
-func (kv *kvPrefix) unprefixTxnResponse(resp *clientv3.TxnResponse) {
-	for _, r := range resp.Responses {
-		switch tv := r.Response.(type) {
-		case *pb.ResponseOp_ResponseRange:
-			if tv.ResponseRange != nil {
-				kv.unprefixGetResponse((*clientv3.GetResponse)(tv.ResponseRange))
-			}
-		case *pb.ResponseOp_ResponsePut:
-			if tv.ResponsePut != nil {
-				kv.unprefixPutResponse((*clientv3.PutResponse)(tv.ResponsePut))
-			}
-		case *pb.ResponseOp_ResponseDeleteRange:
-			if tv.ResponseDeleteRange != nil {
-				kv.unprefixDeleteResponse((*clientv3.DeleteResponse)(tv.ResponseDeleteRange))
-			}
-		case *pb.ResponseOp_ResponseTxn:
-			if tv.ResponseTxn != nil {
-				kv.unprefixTxnResponse((*clientv3.TxnResponse)(tv.ResponseTxn))
-			}
-		default:
-		}
-	}
-}
-
-func (kv *kvPrefix) prefixInterval(key, end []byte) (pfxKey []byte, pfxEnd []byte) {
-	return prefixInterval(kv.pfx, key, end)
-}
-
-func (kv *kvPrefix) prefixCmps(cs []clientv3.Cmp) []clientv3.Cmp {
-	newCmps := make([]clientv3.Cmp, len(cs))
-	for i := range cs {
-		newCmps[i] = cs[i]
-		pfxKey, endKey := kv.prefixInterval(cs[i].KeyBytes(), cs[i].RangeEnd)
-		newCmps[i].WithKeyBytes(pfxKey)
-		if len(cs[i].RangeEnd) != 0 {
-			newCmps[i].RangeEnd = endKey
-		}
-	}
-	return newCmps
-}
-
-func (kv *kvPrefix) prefixOps(ops []clientv3.Op) []clientv3.Op {
-	newOps := make([]clientv3.Op, len(ops))
-	for i := range ops {
-		newOps[i] = kv.prefixOp(ops[i])
-	}
-	return newOps
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/namespace/lease.go b/vendor/github.com/coreos/etcd/clientv3/namespace/lease.go
deleted file mode 100644
index f092106..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/namespace/lease.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package namespace
-
-import (
-	"bytes"
-	"context"
-
-	"github.com/coreos/etcd/clientv3"
-)
-
-type leasePrefix struct {
-	clientv3.Lease
-	pfx []byte
-}
-
-// NewLease wraps a Lease interface to filter for only keys with a prefix
-// and remove that prefix when fetching attached keys through TimeToLive.
-func NewLease(l clientv3.Lease, prefix string) clientv3.Lease {
-	return &leasePrefix{l, []byte(prefix)}
-}
-
-func (l *leasePrefix) TimeToLive(ctx context.Context, id clientv3.LeaseID, opts ...clientv3.LeaseOption) (*clientv3.LeaseTimeToLiveResponse, error) {
-	resp, err := l.Lease.TimeToLive(ctx, id, opts...)
-	if err != nil {
-		return nil, err
-	}
-	if len(resp.Keys) > 0 {
-		var outKeys [][]byte
-		for i := range resp.Keys {
-			if len(resp.Keys[i]) < len(l.pfx) {
-				// too short
-				continue
-			}
-			if !bytes.Equal(resp.Keys[i][:len(l.pfx)], l.pfx) {
-				// doesn't match prefix
-				continue
-			}
-			// strip prefix
-			outKeys = append(outKeys, resp.Keys[i][len(l.pfx):])
-		}
-		resp.Keys = outKeys
-	}
-	return resp, nil
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/namespace/util.go b/vendor/github.com/coreos/etcd/clientv3/namespace/util.go
deleted file mode 100644
index ecf0404..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/namespace/util.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package namespace
-
-func prefixInterval(pfx string, key, end []byte) (pfxKey []byte, pfxEnd []byte) {
-	pfxKey = make([]byte, len(pfx)+len(key))
-	copy(pfxKey[copy(pfxKey, pfx):], key)
-
-	if len(end) == 1 && end[0] == 0 {
-		// the edge of the keyspace
-		pfxEnd = make([]byte, len(pfx))
-		copy(pfxEnd, pfx)
-		ok := false
-		for i := len(pfxEnd) - 1; i >= 0; i-- {
-			if pfxEnd[i]++; pfxEnd[i] != 0 {
-				ok = true
-				break
-			}
-		}
-		if !ok {
-			// 0xff..ff => 0x00
-			pfxEnd = []byte{0}
-		}
-	} else if len(end) >= 1 {
-		pfxEnd = make([]byte, len(pfx)+len(end))
-		copy(pfxEnd[copy(pfxEnd, pfx):], end)
-	}
-
-	return pfxKey, pfxEnd
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/namespace/watch.go b/vendor/github.com/coreos/etcd/clientv3/namespace/watch.go
deleted file mode 100644
index 5a9596d..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/namespace/watch.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package namespace
-
-import (
-	"context"
-	"sync"
-
-	"github.com/coreos/etcd/clientv3"
-)
-
-type watcherPrefix struct {
-	clientv3.Watcher
-	pfx string
-
-	wg       sync.WaitGroup
-	stopc    chan struct{}
-	stopOnce sync.Once
-}
-
-// NewWatcher wraps a Watcher instance so that all Watch requests
-// are prefixed with a given string and all Watch responses have
-// the prefix removed.
-func NewWatcher(w clientv3.Watcher, prefix string) clientv3.Watcher {
-	return &watcherPrefix{Watcher: w, pfx: prefix, stopc: make(chan struct{})}
-}
-
-func (w *watcherPrefix) Watch(ctx context.Context, key string, opts ...clientv3.OpOption) clientv3.WatchChan {
-	// since OpOption is opaque, determine range for prefixing through an OpGet
-	op := clientv3.OpGet(key, opts...)
-	end := op.RangeBytes()
-	pfxBegin, pfxEnd := prefixInterval(w.pfx, []byte(key), end)
-	if pfxEnd != nil {
-		opts = append(opts, clientv3.WithRange(string(pfxEnd)))
-	}
-
-	wch := w.Watcher.Watch(ctx, string(pfxBegin), opts...)
-
-	// translate watch events from prefixed to unprefixed
-	pfxWch := make(chan clientv3.WatchResponse)
-	w.wg.Add(1)
-	go func() {
-		defer func() {
-			close(pfxWch)
-			w.wg.Done()
-		}()
-		for wr := range wch {
-			for i := range wr.Events {
-				wr.Events[i].Kv.Key = wr.Events[i].Kv.Key[len(w.pfx):]
-				if wr.Events[i].PrevKv != nil {
-					wr.Events[i].PrevKv.Key = wr.Events[i].Kv.Key
-				}
-			}
-			select {
-			case pfxWch <- wr:
-			case <-ctx.Done():
-				return
-			case <-w.stopc:
-				return
-			}
-		}
-	}()
-	return pfxWch
-}
-
-func (w *watcherPrefix) Close() error {
-	err := w.Watcher.Close()
-	w.stopOnce.Do(func() { close(w.stopc) })
-	w.wg.Wait()
-	return err
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/naming/doc.go b/vendor/github.com/coreos/etcd/clientv3/naming/doc.go
deleted file mode 100644
index 71608cc..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/naming/doc.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package naming provides an etcd-backed gRPC resolver for discovering gRPC services.
-//
-// To use, first import the packages:
-//
-//	import (
-//		"github.com/coreos/etcd/clientv3"
-//		etcdnaming "github.com/coreos/etcd/clientv3/naming"
-//
-//		"google.golang.org/grpc"
-//		"google.golang.org/grpc/naming"
-//	)
-//
-// First, register new endpoint addresses for a service:
-//
-//	func etcdAdd(c *clientv3.Client, service, addr string) error {
-//		r := &etcdnaming.GRPCResolver{Client: c}
-//		return r.Update(c.Ctx(), service, naming.Update{Op: naming.Add, Addr: addr})
-//	}
-//
-// Dial an RPC service using the etcd gRPC resolver and a gRPC Balancer:
-//
-//	func etcdDial(c *clientv3.Client, service string) (*grpc.ClientConn, error) {
-//		r := &etcdnaming.GRPCResolver{Client: c}
-//		b := grpc.RoundRobin(r)
-//		return grpc.Dial(service, grpc.WithBalancer(b))
-//	}
-//
-// Optionally, force delete an endpoint:
-//
-//	func etcdDelete(c *clientv3, service, addr string) error {
-//		r := &etcdnaming.GRPCResolver{Client: c}
-//		return r.Update(c.Ctx(), "my-service", naming.Update{Op: naming.Delete, Addr: "1.2.3.4"})
-//	}
-//
-// Or register an expiring endpoint with a lease:
-//
-//	func etcdLeaseAdd(c *clientv3.Client, lid clientv3.LeaseID, service, addr string) error {
-//		r := &etcdnaming.GRPCResolver{Client: c}
-//		return r.Update(c.Ctx(), service, naming.Update{Op: naming.Add, Addr: addr}, clientv3.WithLease(lid))
-//	}
-//
-package naming
diff --git a/vendor/github.com/coreos/etcd/clientv3/naming/grpc.go b/vendor/github.com/coreos/etcd/clientv3/naming/grpc.go
deleted file mode 100644
index 3c0e8e6..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/naming/grpc.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package naming
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-
-	etcd "github.com/coreos/etcd/clientv3"
-
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/naming"
-	"google.golang.org/grpc/status"
-)
-
-var ErrWatcherClosed = fmt.Errorf("naming: watch closed")
-
-// GRPCResolver creates a grpc.Watcher for a target to track its resolution changes.
-type GRPCResolver struct {
-	// Client is an initialized etcd client.
-	Client *etcd.Client
-}
-
-func (gr *GRPCResolver) Update(ctx context.Context, target string, nm naming.Update, opts ...etcd.OpOption) (err error) {
-	switch nm.Op {
-	case naming.Add:
-		var v []byte
-		if v, err = json.Marshal(nm); err != nil {
-			return status.Error(codes.InvalidArgument, err.Error())
-		}
-		_, err = gr.Client.KV.Put(ctx, target+"/"+nm.Addr, string(v), opts...)
-	case naming.Delete:
-		_, err = gr.Client.Delete(ctx, target+"/"+nm.Addr, opts...)
-	default:
-		return status.Error(codes.InvalidArgument, "naming: bad naming op")
-	}
-	return err
-}
-
-func (gr *GRPCResolver) Resolve(target string) (naming.Watcher, error) {
-	ctx, cancel := context.WithCancel(context.Background())
-	w := &gRPCWatcher{c: gr.Client, target: target + "/", ctx: ctx, cancel: cancel}
-	return w, nil
-}
-
-type gRPCWatcher struct {
-	c      *etcd.Client
-	target string
-	ctx    context.Context
-	cancel context.CancelFunc
-	wch    etcd.WatchChan
-	err    error
-}
-
-// Next gets the next set of updates from the etcd resolver.
-// Calls to Next should be serialized; concurrent calls are not safe since
-// there is no way to reconcile the update ordering.
-func (gw *gRPCWatcher) Next() ([]*naming.Update, error) {
-	if gw.wch == nil {
-		// first Next() returns all addresses
-		return gw.firstNext()
-	}
-	if gw.err != nil {
-		return nil, gw.err
-	}
-
-	// process new events on target/*
-	wr, ok := <-gw.wch
-	if !ok {
-		gw.err = status.Error(codes.Unavailable, ErrWatcherClosed.Error())
-		return nil, gw.err
-	}
-	if gw.err = wr.Err(); gw.err != nil {
-		return nil, gw.err
-	}
-
-	updates := make([]*naming.Update, 0, len(wr.Events))
-	for _, e := range wr.Events {
-		var jupdate naming.Update
-		var err error
-		switch e.Type {
-		case etcd.EventTypePut:
-			err = json.Unmarshal(e.Kv.Value, &jupdate)
-			jupdate.Op = naming.Add
-		case etcd.EventTypeDelete:
-			err = json.Unmarshal(e.PrevKv.Value, &jupdate)
-			jupdate.Op = naming.Delete
-		}
-		if err == nil {
-			updates = append(updates, &jupdate)
-		}
-	}
-	return updates, nil
-}
-
-func (gw *gRPCWatcher) firstNext() ([]*naming.Update, error) {
-	// Use serialized request so resolution still works if the target etcd
-	// server is partitioned away from the quorum.
-	resp, err := gw.c.Get(gw.ctx, gw.target, etcd.WithPrefix(), etcd.WithSerializable())
-	if gw.err = err; err != nil {
-		return nil, err
-	}
-
-	updates := make([]*naming.Update, 0, len(resp.Kvs))
-	for _, kv := range resp.Kvs {
-		var jupdate naming.Update
-		if err := json.Unmarshal(kv.Value, &jupdate); err != nil {
-			continue
-		}
-		updates = append(updates, &jupdate)
-	}
-
-	opts := []etcd.OpOption{etcd.WithRev(resp.Header.Revision + 1), etcd.WithPrefix(), etcd.WithPrevKV()}
-	gw.wch = gw.c.Watch(gw.ctx, gw.target, opts...)
-	return updates, nil
-}
-
-func (gw *gRPCWatcher) Close() { gw.cancel() }
diff --git a/vendor/github.com/coreos/etcd/clientv3/op.go b/vendor/github.com/coreos/etcd/clientv3/op.go
deleted file mode 100644
index c6ec5bf..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/op.go
+++ /dev/null
@@ -1,513 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-type opType int
-
-const (
-	// A default Op has opType 0, which is invalid.
-	tRange opType = iota + 1
-	tPut
-	tDeleteRange
-	tTxn
-)
-
-var (
-	noPrefixEnd = []byte{0}
-)
-
-// Op represents an Operation that kv can execute.
-type Op struct {
-	t   opType
-	key []byte
-	end []byte
-
-	// for range
-	limit        int64
-	sort         *SortOption
-	serializable bool
-	keysOnly     bool
-	countOnly    bool
-	minModRev    int64
-	maxModRev    int64
-	minCreateRev int64
-	maxCreateRev int64
-
-	// for range, watch
-	rev int64
-
-	// for watch, put, delete
-	prevKV bool
-
-	// for put
-	ignoreValue bool
-	ignoreLease bool
-
-	// progressNotify is for progress updates.
-	progressNotify bool
-	// createdNotify is for created event
-	createdNotify bool
-	// filters for watchers
-	filterPut    bool
-	filterDelete bool
-
-	// for put
-	val     []byte
-	leaseID LeaseID
-
-	// txn
-	cmps    []Cmp
-	thenOps []Op
-	elseOps []Op
-}
-
-// accessors / mutators
-
-func (op Op) IsTxn() bool              { return op.t == tTxn }
-func (op Op) Txn() ([]Cmp, []Op, []Op) { return op.cmps, op.thenOps, op.elseOps }
-
-// KeyBytes returns the byte slice holding the Op's key.
-func (op Op) KeyBytes() []byte { return op.key }
-
-// WithKeyBytes sets the byte slice for the Op's key.
-func (op *Op) WithKeyBytes(key []byte) { op.key = key }
-
-// RangeBytes returns the byte slice holding with the Op's range end, if any.
-func (op Op) RangeBytes() []byte { return op.end }
-
-// Rev returns the requested revision, if any.
-func (op Op) Rev() int64 { return op.rev }
-
-// IsPut returns true iff the operation is a Put.
-func (op Op) IsPut() bool { return op.t == tPut }
-
-// IsGet returns true iff the operation is a Get.
-func (op Op) IsGet() bool { return op.t == tRange }
-
-// IsDelete returns true iff the operation is a Delete.
-func (op Op) IsDelete() bool { return op.t == tDeleteRange }
-
-// IsSerializable returns true if the serializable field is true.
-func (op Op) IsSerializable() bool { return op.serializable == true }
-
-// IsKeysOnly returns whether keysOnly is set.
-func (op Op) IsKeysOnly() bool { return op.keysOnly == true }
-
-// IsCountOnly returns whether countOnly is set.
-func (op Op) IsCountOnly() bool { return op.countOnly == true }
-
-// MinModRev returns the operation's minimum modify revision.
-func (op Op) MinModRev() int64 { return op.minModRev }
-
-// MaxModRev returns the operation's maximum modify revision.
-func (op Op) MaxModRev() int64 { return op.maxModRev }
-
-// MinCreateRev returns the operation's minimum create revision.
-func (op Op) MinCreateRev() int64 { return op.minCreateRev }
-
-// MaxCreateRev returns the operation's maximum create revision.
-func (op Op) MaxCreateRev() int64 { return op.maxCreateRev }
-
-// WithRangeBytes sets the byte slice for the Op's range end.
-func (op *Op) WithRangeBytes(end []byte) { op.end = end }
-
-// ValueBytes returns the byte slice holding the Op's value, if any.
-func (op Op) ValueBytes() []byte { return op.val }
-
-// WithValueBytes sets the byte slice for the Op's value.
-func (op *Op) WithValueBytes(v []byte) { op.val = v }
-
-func (op Op) toRangeRequest() *pb.RangeRequest {
-	if op.t != tRange {
-		panic("op.t != tRange")
-	}
-	r := &pb.RangeRequest{
-		Key:               op.key,
-		RangeEnd:          op.end,
-		Limit:             op.limit,
-		Revision:          op.rev,
-		Serializable:      op.serializable,
-		KeysOnly:          op.keysOnly,
-		CountOnly:         op.countOnly,
-		MinModRevision:    op.minModRev,
-		MaxModRevision:    op.maxModRev,
-		MinCreateRevision: op.minCreateRev,
-		MaxCreateRevision: op.maxCreateRev,
-	}
-	if op.sort != nil {
-		r.SortOrder = pb.RangeRequest_SortOrder(op.sort.Order)
-		r.SortTarget = pb.RangeRequest_SortTarget(op.sort.Target)
-	}
-	return r
-}
-
-func (op Op) toTxnRequest() *pb.TxnRequest {
-	thenOps := make([]*pb.RequestOp, len(op.thenOps))
-	for i, tOp := range op.thenOps {
-		thenOps[i] = tOp.toRequestOp()
-	}
-	elseOps := make([]*pb.RequestOp, len(op.elseOps))
-	for i, eOp := range op.elseOps {
-		elseOps[i] = eOp.toRequestOp()
-	}
-	cmps := make([]*pb.Compare, len(op.cmps))
-	for i := range op.cmps {
-		cmps[i] = (*pb.Compare)(&op.cmps[i])
-	}
-	return &pb.TxnRequest{Compare: cmps, Success: thenOps, Failure: elseOps}
-}
-
-func (op Op) toRequestOp() *pb.RequestOp {
-	switch op.t {
-	case tRange:
-		return &pb.RequestOp{Request: &pb.RequestOp_RequestRange{RequestRange: op.toRangeRequest()}}
-	case tPut:
-		r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV, IgnoreValue: op.ignoreValue, IgnoreLease: op.ignoreLease}
-		return &pb.RequestOp{Request: &pb.RequestOp_RequestPut{RequestPut: r}}
-	case tDeleteRange:
-		r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV}
-		return &pb.RequestOp{Request: &pb.RequestOp_RequestDeleteRange{RequestDeleteRange: r}}
-	case tTxn:
-		return &pb.RequestOp{Request: &pb.RequestOp_RequestTxn{RequestTxn: op.toTxnRequest()}}
-	default:
-		panic("Unknown Op")
-	}
-}
-
-func (op Op) isWrite() bool {
-	if op.t == tTxn {
-		for _, tOp := range op.thenOps {
-			if tOp.isWrite() {
-				return true
-			}
-		}
-		for _, tOp := range op.elseOps {
-			if tOp.isWrite() {
-				return true
-			}
-		}
-		return false
-	}
-	return op.t != tRange
-}
-
-func OpGet(key string, opts ...OpOption) Op {
-	ret := Op{t: tRange, key: []byte(key)}
-	ret.applyOpts(opts)
-	return ret
-}
-
-func OpDelete(key string, opts ...OpOption) Op {
-	ret := Op{t: tDeleteRange, key: []byte(key)}
-	ret.applyOpts(opts)
-	switch {
-	case ret.leaseID != 0:
-		panic("unexpected lease in delete")
-	case ret.limit != 0:
-		panic("unexpected limit in delete")
-	case ret.rev != 0:
-		panic("unexpected revision in delete")
-	case ret.sort != nil:
-		panic("unexpected sort in delete")
-	case ret.serializable:
-		panic("unexpected serializable in delete")
-	case ret.countOnly:
-		panic("unexpected countOnly in delete")
-	case ret.minModRev != 0, ret.maxModRev != 0:
-		panic("unexpected mod revision filter in delete")
-	case ret.minCreateRev != 0, ret.maxCreateRev != 0:
-		panic("unexpected create revision filter in delete")
-	case ret.filterDelete, ret.filterPut:
-		panic("unexpected filter in delete")
-	case ret.createdNotify:
-		panic("unexpected createdNotify in delete")
-	}
-	return ret
-}
-
-func OpPut(key, val string, opts ...OpOption) Op {
-	ret := Op{t: tPut, key: []byte(key), val: []byte(val)}
-	ret.applyOpts(opts)
-	switch {
-	case ret.end != nil:
-		panic("unexpected range in put")
-	case ret.limit != 0:
-		panic("unexpected limit in put")
-	case ret.rev != 0:
-		panic("unexpected revision in put")
-	case ret.sort != nil:
-		panic("unexpected sort in put")
-	case ret.serializable:
-		panic("unexpected serializable in put")
-	case ret.countOnly:
-		panic("unexpected countOnly in put")
-	case ret.minModRev != 0, ret.maxModRev != 0:
-		panic("unexpected mod revision filter in put")
-	case ret.minCreateRev != 0, ret.maxCreateRev != 0:
-		panic("unexpected create revision filter in put")
-	case ret.filterDelete, ret.filterPut:
-		panic("unexpected filter in put")
-	case ret.createdNotify:
-		panic("unexpected createdNotify in put")
-	}
-	return ret
-}
-
-func OpTxn(cmps []Cmp, thenOps []Op, elseOps []Op) Op {
-	return Op{t: tTxn, cmps: cmps, thenOps: thenOps, elseOps: elseOps}
-}
-
-func opWatch(key string, opts ...OpOption) Op {
-	ret := Op{t: tRange, key: []byte(key)}
-	ret.applyOpts(opts)
-	switch {
-	case ret.leaseID != 0:
-		panic("unexpected lease in watch")
-	case ret.limit != 0:
-		panic("unexpected limit in watch")
-	case ret.sort != nil:
-		panic("unexpected sort in watch")
-	case ret.serializable:
-		panic("unexpected serializable in watch")
-	case ret.countOnly:
-		panic("unexpected countOnly in watch")
-	case ret.minModRev != 0, ret.maxModRev != 0:
-		panic("unexpected mod revision filter in watch")
-	case ret.minCreateRev != 0, ret.maxCreateRev != 0:
-		panic("unexpected create revision filter in watch")
-	}
-	return ret
-}
-
-func (op *Op) applyOpts(opts []OpOption) {
-	for _, opt := range opts {
-		opt(op)
-	}
-}
-
-// OpOption configures Operations like Get, Put, Delete.
-type OpOption func(*Op)
-
-// WithLease attaches a lease ID to a key in 'Put' request.
-func WithLease(leaseID LeaseID) OpOption {
-	return func(op *Op) { op.leaseID = leaseID }
-}
-
-// WithLimit limits the number of results to return from 'Get' request.
-// If WithLimit is given a 0 limit, it is treated as no limit.
-func WithLimit(n int64) OpOption { return func(op *Op) { op.limit = n } }
-
-// WithRev specifies the store revision for 'Get' request.
-// Or the start revision of 'Watch' request.
-func WithRev(rev int64) OpOption { return func(op *Op) { op.rev = rev } }
-
-// WithSort specifies the ordering in 'Get' request. It requires
-// 'WithRange' and/or 'WithPrefix' to be specified too.
-// 'target' specifies the target to sort by: key, version, revisions, value.
-// 'order' can be either 'SortNone', 'SortAscend', 'SortDescend'.
-func WithSort(target SortTarget, order SortOrder) OpOption {
-	return func(op *Op) {
-		if target == SortByKey && order == SortAscend {
-			// If order != SortNone, server fetches the entire key-space,
-			// and then applies the sort and limit, if provided.
-			// Since by default the server returns results sorted by keys
-			// in lexicographically ascending order, the client should ignore
-			// SortOrder if the target is SortByKey.
-			order = SortNone
-		}
-		op.sort = &SortOption{target, order}
-	}
-}
-
-// GetPrefixRangeEnd gets the range end of the prefix.
-// 'Get(foo, WithPrefix())' is equal to 'Get(foo, WithRange(GetPrefixRangeEnd(foo))'.
-func GetPrefixRangeEnd(prefix string) string {
-	return string(getPrefix([]byte(prefix)))
-}
-
-func getPrefix(key []byte) []byte {
-	end := make([]byte, len(key))
-	copy(end, key)
-	for i := len(end) - 1; i >= 0; i-- {
-		if end[i] < 0xff {
-			end[i] = end[i] + 1
-			end = end[:i+1]
-			return end
-		}
-	}
-	// next prefix does not exist (e.g., 0xffff);
-	// default to WithFromKey policy
-	return noPrefixEnd
-}
-
-// WithPrefix enables 'Get', 'Delete', or 'Watch' requests to operate
-// on the keys with matching prefix. For example, 'Get(foo, WithPrefix())'
-// can return 'foo1', 'foo2', and so on.
-func WithPrefix() OpOption {
-	return func(op *Op) {
-		if len(op.key) == 0 {
-			op.key, op.end = []byte{0}, []byte{0}
-			return
-		}
-		op.end = getPrefix(op.key)
-	}
-}
-
-// WithRange specifies the range of 'Get', 'Delete', 'Watch' requests.
-// For example, 'Get' requests with 'WithRange(end)' returns
-// the keys in the range [key, end).
-// endKey must be lexicographically greater than start key.
-func WithRange(endKey string) OpOption {
-	return func(op *Op) { op.end = []byte(endKey) }
-}
-
-// WithFromKey specifies the range of 'Get', 'Delete', 'Watch' requests
-// to be equal or greater than the key in the argument.
-func WithFromKey() OpOption { return WithRange("\x00") }
-
-// WithSerializable makes 'Get' request serializable. By default,
-// it's linearizable. Serializable requests are better for lower latency
-// requirement.
-func WithSerializable() OpOption {
-	return func(op *Op) { op.serializable = true }
-}
-
-// WithKeysOnly makes the 'Get' request return only the keys and the corresponding
-// values will be omitted.
-func WithKeysOnly() OpOption {
-	return func(op *Op) { op.keysOnly = true }
-}
-
-// WithCountOnly makes the 'Get' request return only the count of keys.
-func WithCountOnly() OpOption {
-	return func(op *Op) { op.countOnly = true }
-}
-
-// WithMinModRev filters out keys for Get with modification revisions less than the given revision.
-func WithMinModRev(rev int64) OpOption { return func(op *Op) { op.minModRev = rev } }
-
-// WithMaxModRev filters out keys for Get with modification revisions greater than the given revision.
-func WithMaxModRev(rev int64) OpOption { return func(op *Op) { op.maxModRev = rev } }
-
-// WithMinCreateRev filters out keys for Get with creation revisions less than the given revision.
-func WithMinCreateRev(rev int64) OpOption { return func(op *Op) { op.minCreateRev = rev } }
-
-// WithMaxCreateRev filters out keys for Get with creation revisions greater than the given revision.
-func WithMaxCreateRev(rev int64) OpOption { return func(op *Op) { op.maxCreateRev = rev } }
-
-// WithFirstCreate gets the key with the oldest creation revision in the request range.
-func WithFirstCreate() []OpOption { return withTop(SortByCreateRevision, SortAscend) }
-
-// WithLastCreate gets the key with the latest creation revision in the request range.
-func WithLastCreate() []OpOption { return withTop(SortByCreateRevision, SortDescend) }
-
-// WithFirstKey gets the lexically first key in the request range.
-func WithFirstKey() []OpOption { return withTop(SortByKey, SortAscend) }
-
-// WithLastKey gets the lexically last key in the request range.
-func WithLastKey() []OpOption { return withTop(SortByKey, SortDescend) }
-
-// WithFirstRev gets the key with the oldest modification revision in the request range.
-func WithFirstRev() []OpOption { return withTop(SortByModRevision, SortAscend) }
-
-// WithLastRev gets the key with the latest modification revision in the request range.
-func WithLastRev() []OpOption { return withTop(SortByModRevision, SortDescend) }
-
-// withTop gets the first key over the get's prefix given a sort order
-func withTop(target SortTarget, order SortOrder) []OpOption {
-	return []OpOption{WithPrefix(), WithSort(target, order), WithLimit(1)}
-}
-
-// WithProgressNotify makes watch server send periodic progress updates
-// every 10 minutes when there is no incoming events.
-// Progress updates have zero events in WatchResponse.
-func WithProgressNotify() OpOption {
-	return func(op *Op) {
-		op.progressNotify = true
-	}
-}
-
-// WithCreatedNotify makes watch server sends the created event.
-func WithCreatedNotify() OpOption {
-	return func(op *Op) {
-		op.createdNotify = true
-	}
-}
-
-// WithFilterPut discards PUT events from the watcher.
-func WithFilterPut() OpOption {
-	return func(op *Op) { op.filterPut = true }
-}
-
-// WithFilterDelete discards DELETE events from the watcher.
-func WithFilterDelete() OpOption {
-	return func(op *Op) { op.filterDelete = true }
-}
-
-// WithPrevKV gets the previous key-value pair before the event happens. If the previous KV is already compacted,
-// nothing will be returned.
-func WithPrevKV() OpOption {
-	return func(op *Op) {
-		op.prevKV = true
-	}
-}
-
-// WithIgnoreValue updates the key using its current value.
-// This option can not be combined with non-empty values.
-// Returns an error if the key does not exist.
-func WithIgnoreValue() OpOption {
-	return func(op *Op) {
-		op.ignoreValue = true
-	}
-}
-
-// WithIgnoreLease updates the key using its current lease.
-// This option can not be combined with WithLease.
-// Returns an error if the key does not exist.
-func WithIgnoreLease() OpOption {
-	return func(op *Op) {
-		op.ignoreLease = true
-	}
-}
-
-// LeaseOp represents an Operation that lease can execute.
-type LeaseOp struct {
-	id LeaseID
-
-	// for TimeToLive
-	attachedKeys bool
-}
-
-// LeaseOption configures lease operations.
-type LeaseOption func(*LeaseOp)
-
-func (op *LeaseOp) applyOpts(opts []LeaseOption) {
-	for _, opt := range opts {
-		opt(op)
-	}
-}
-
-// WithAttachedKeys makes TimeToLive list the keys attached to the given lease ID.
-func WithAttachedKeys() LeaseOption {
-	return func(op *LeaseOp) { op.attachedKeys = true }
-}
-
-func toLeaseTimeToLiveRequest(id LeaseID, opts ...LeaseOption) *pb.LeaseTimeToLiveRequest {
-	ret := &LeaseOp{id: id}
-	ret.applyOpts(opts)
-	return &pb.LeaseTimeToLiveRequest{ID: int64(id), Keys: ret.attachedKeys}
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/options.go b/vendor/github.com/coreos/etcd/clientv3/options.go
deleted file mode 100644
index fa25811..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/options.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"math"
-
-	"google.golang.org/grpc"
-)
-
-var (
-	// Disable gRPC internal retrial logic
-	// TODO: enable when gRPC retry is stable (FailFast=false)
-	// Reference:
-	//  - https://github.com/grpc/grpc-go/issues/1532
-	//  - https://github.com/grpc/proposal/blob/master/A6-client-retries.md
-	defaultFailFast = grpc.FailFast(true)
-
-	// client-side request send limit, gRPC default is math.MaxInt32
-	// Make sure that "client-side send limit < server-side default send/recv limit"
-	// Same value as "embed.DefaultMaxRequestBytes" plus gRPC overhead bytes
-	defaultMaxCallSendMsgSize = grpc.MaxCallSendMsgSize(2 * 1024 * 1024)
-
-	// client-side response receive limit, gRPC default is 4MB
-	// Make sure that "client-side receive limit >= server-side default send/recv limit"
-	// because range response can easily exceed request send limits
-	// Default to math.MaxInt32; writes exceeding server-side send limit fails anyway
-	defaultMaxCallRecvMsgSize = grpc.MaxCallRecvMsgSize(math.MaxInt32)
-)
-
-// defaultCallOpts defines a list of default "gRPC.CallOption".
-// Some options are exposed to "clientv3.Config".
-// Defaults will be overridden by the settings in "clientv3.Config".
-var defaultCallOpts = []grpc.CallOption{defaultFailFast, defaultMaxCallSendMsgSize, defaultMaxCallRecvMsgSize}
-
-// MaxLeaseTTL is the maximum lease TTL value
-const MaxLeaseTTL = 9000000000
diff --git a/vendor/github.com/coreos/etcd/clientv3/ordering/doc.go b/vendor/github.com/coreos/etcd/clientv3/ordering/doc.go
deleted file mode 100644
index 856f330..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/ordering/doc.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package ordering is a clientv3 wrapper that caches response header revisions
-// to detect ordering violations from stale responses. Users may define a
-// policy on how to handle the ordering violation, but typically the client
-// should connect to another endpoint and reissue the request.
-//
-// The most common situation where an ordering violation happens is a client
-// reconnects to a partitioned member and issues a serializable read. Since the
-// partitioned member is likely behind the last member, it may return a Get
-// response based on a store revision older than the store revision used to
-// service a prior Get on the former endpoint.
-//
-// First, create a client:
-//
-//	cli, err := clientv3.New(clientv3.Config{Endpoints: []string{"localhost:2379"}})
-//	if err != nil {
-//		// handle error!
-//	}
-//
-// Next, override the client interface with the ordering wrapper:
-//
-//	vf := func(op clientv3.Op, resp clientv3.OpResponse, prevRev int64) error {
-//		return fmt.Errorf("ordering: issued %+v, got %+v, expected rev=%v", op, resp, prevRev)
-//	}
-//	cli.KV = ordering.NewKV(cli.KV, vf)
-//
-// Now calls using 'cli' will reject order violations with an error.
-//
-package ordering
diff --git a/vendor/github.com/coreos/etcd/clientv3/ordering/kv.go b/vendor/github.com/coreos/etcd/clientv3/ordering/kv.go
deleted file mode 100644
index dc9926e..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/ordering/kv.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package ordering
-
-import (
-	"context"
-	"sync"
-
-	"github.com/coreos/etcd/clientv3"
-)
-
-// kvOrdering ensures that serialized requests do not return
-// get with revisions less than the previous
-// returned revision.
-type kvOrdering struct {
-	clientv3.KV
-	orderViolationFunc OrderViolationFunc
-	prevRev            int64
-	revMu              sync.RWMutex
-}
-
-func NewKV(kv clientv3.KV, orderViolationFunc OrderViolationFunc) *kvOrdering {
-	return &kvOrdering{kv, orderViolationFunc, 0, sync.RWMutex{}}
-}
-
-func (kv *kvOrdering) getPrevRev() int64 {
-	kv.revMu.RLock()
-	defer kv.revMu.RUnlock()
-	return kv.prevRev
-}
-
-func (kv *kvOrdering) setPrevRev(currRev int64) {
-	kv.revMu.Lock()
-	defer kv.revMu.Unlock()
-	if currRev > kv.prevRev {
-		kv.prevRev = currRev
-	}
-}
-
-func (kv *kvOrdering) Get(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.GetResponse, error) {
-	// prevRev is stored in a local variable in order to record the prevRev
-	// at the beginning of the Get operation, because concurrent
-	// access to kvOrdering could change the prevRev field in the
-	// middle of the Get operation.
-	prevRev := kv.getPrevRev()
-	op := clientv3.OpGet(key, opts...)
-	for {
-		r, err := kv.KV.Do(ctx, op)
-		if err != nil {
-			return nil, err
-		}
-		resp := r.Get()
-		if resp.Header.Revision == prevRev {
-			return resp, nil
-		} else if resp.Header.Revision > prevRev {
-			kv.setPrevRev(resp.Header.Revision)
-			return resp, nil
-		}
-		err = kv.orderViolationFunc(op, r, prevRev)
-		if err != nil {
-			return nil, err
-		}
-	}
-}
-
-func (kv *kvOrdering) Txn(ctx context.Context) clientv3.Txn {
-	return &txnOrdering{
-		kv.KV.Txn(ctx),
-		kv,
-		ctx,
-		sync.Mutex{},
-		[]clientv3.Cmp{},
-		[]clientv3.Op{},
-		[]clientv3.Op{},
-	}
-}
-
-// txnOrdering ensures that serialized requests do not return
-// txn responses with revisions less than the previous
-// returned revision.
-type txnOrdering struct {
-	clientv3.Txn
-	*kvOrdering
-	ctx     context.Context
-	mu      sync.Mutex
-	cmps    []clientv3.Cmp
-	thenOps []clientv3.Op
-	elseOps []clientv3.Op
-}
-
-func (txn *txnOrdering) If(cs ...clientv3.Cmp) clientv3.Txn {
-	txn.mu.Lock()
-	defer txn.mu.Unlock()
-	txn.cmps = cs
-	txn.Txn.If(cs...)
-	return txn
-}
-
-func (txn *txnOrdering) Then(ops ...clientv3.Op) clientv3.Txn {
-	txn.mu.Lock()
-	defer txn.mu.Unlock()
-	txn.thenOps = ops
-	txn.Txn.Then(ops...)
-	return txn
-}
-
-func (txn *txnOrdering) Else(ops ...clientv3.Op) clientv3.Txn {
-	txn.mu.Lock()
-	defer txn.mu.Unlock()
-	txn.elseOps = ops
-	txn.Txn.Else(ops...)
-	return txn
-}
-
-func (txn *txnOrdering) Commit() (*clientv3.TxnResponse, error) {
-	// prevRev is stored in a local variable in order to record the prevRev
-	// at the beginning of the Commit operation, because concurrent
-	// access to txnOrdering could change the prevRev field in the
-	// middle of the Commit operation.
-	prevRev := txn.getPrevRev()
-	opTxn := clientv3.OpTxn(txn.cmps, txn.thenOps, txn.elseOps)
-	for {
-		opResp, err := txn.KV.Do(txn.ctx, opTxn)
-		if err != nil {
-			return nil, err
-		}
-		txnResp := opResp.Txn()
-		if txnResp.Header.Revision >= prevRev {
-			txn.setPrevRev(txnResp.Header.Revision)
-			return txnResp, nil
-		}
-		err = txn.orderViolationFunc(opTxn, opResp, prevRev)
-		if err != nil {
-			return nil, err
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/ordering/util.go b/vendor/github.com/coreos/etcd/clientv3/ordering/util.go
deleted file mode 100644
index 190a591..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/ordering/util.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package ordering
-
-import (
-	"errors"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/clientv3"
-)
-
-type OrderViolationFunc func(op clientv3.Op, resp clientv3.OpResponse, prevRev int64) error
-
-var ErrNoGreaterRev = errors.New("etcdclient: no cluster members have a revision higher than the previously received revision")
-
-func NewOrderViolationSwitchEndpointClosure(c clientv3.Client) OrderViolationFunc {
-	var mu sync.Mutex
-	violationCount := 0
-	return func(op clientv3.Op, resp clientv3.OpResponse, prevRev int64) error {
-		if violationCount > len(c.Endpoints()) {
-			return ErrNoGreaterRev
-		}
-		mu.Lock()
-		defer mu.Unlock()
-		eps := c.Endpoints()
-		// force client to connect to given endpoint by limiting to a single endpoint
-		c.SetEndpoints(eps[violationCount%len(eps)])
-		// give enough time for operation
-		time.Sleep(1 * time.Second)
-		// set available endpoints back to all endpoints in to ensure
-		// the client has access to all the endpoints.
-		c.SetEndpoints(eps...)
-		violationCount++
-		return nil
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/ready_wait.go b/vendor/github.com/coreos/etcd/clientv3/ready_wait.go
deleted file mode 100644
index c6ef585..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/ready_wait.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import "context"
-
-// TODO: remove this when "FailFast=false" is fixed.
-// See https://github.com/grpc/grpc-go/issues/1532.
-func readyWait(rpcCtx, clientCtx context.Context, ready <-chan struct{}) error {
-	select {
-	case <-ready:
-		return nil
-	case <-rpcCtx.Done():
-		return rpcCtx.Err()
-	case <-clientCtx.Done():
-		return clientCtx.Err()
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/retry.go b/vendor/github.com/coreos/etcd/clientv3/retry.go
deleted file mode 100644
index 7f89ba6..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/retry.go
+++ /dev/null
@@ -1,496 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/status"
-)
-
-type retryPolicy uint8
-
-const (
-	repeatable retryPolicy = iota
-	nonRepeatable
-)
-
-type rpcFunc func(ctx context.Context) error
-type retryRPCFunc func(context.Context, rpcFunc, retryPolicy) error
-type retryStopErrFunc func(error) bool
-
-// immutable requests (e.g. Get) should be retried unless it's
-// an obvious server-side error (e.g. rpctypes.ErrRequestTooLarge).
-//
-// "isRepeatableStopError" returns "true" when an immutable request
-// is interrupted by server-side or gRPC-side error and its status
-// code is not transient (!= codes.Unavailable).
-//
-// Returning "true" means retry should stop, since client cannot
-// handle itself even with retries.
-func isRepeatableStopError(err error) bool {
-	eErr := rpctypes.Error(err)
-	// always stop retry on etcd errors
-	if serverErr, ok := eErr.(rpctypes.EtcdError); ok && serverErr.Code() != codes.Unavailable {
-		return true
-	}
-	// only retry if unavailable
-	ev, _ := status.FromError(err)
-	return ev.Code() != codes.Unavailable
-}
-
-// mutable requests (e.g. Put, Delete, Txn) should only be retried
-// when the status code is codes.Unavailable when initial connection
-// has not been established (no pinned endpoint).
-//
-// "isNonRepeatableStopError" returns "true" when a mutable request
-// is interrupted by non-transient error that client cannot handle itself,
-// or transient error while the connection has already been established
-// (pinned endpoint exists).
-//
-// Returning "true" means retry should stop, otherwise it violates
-// write-at-most-once semantics.
-func isNonRepeatableStopError(err error) bool {
-	ev, _ := status.FromError(err)
-	if ev.Code() != codes.Unavailable {
-		return true
-	}
-	desc := rpctypes.ErrorDesc(err)
-	return desc != "there is no address available" && desc != "there is no connection available"
-}
-
-func (c *Client) newRetryWrapper() retryRPCFunc {
-	return func(rpcCtx context.Context, f rpcFunc, rp retryPolicy) error {
-		var isStop retryStopErrFunc
-		switch rp {
-		case repeatable:
-			isStop = isRepeatableStopError
-		case nonRepeatable:
-			isStop = isNonRepeatableStopError
-		}
-		for {
-			if err := readyWait(rpcCtx, c.ctx, c.balancer.ConnectNotify()); err != nil {
-				return err
-			}
-			pinned := c.balancer.pinned()
-			err := f(rpcCtx)
-			if err == nil {
-				return nil
-			}
-			logger.Lvl(4).Infof("clientv3/retry: error %q on pinned endpoint %q", err.Error(), pinned)
-
-			if s, ok := status.FromError(err); ok && (s.Code() == codes.Unavailable || s.Code() == codes.DeadlineExceeded || s.Code() == codes.Internal) {
-				// mark this before endpoint switch is triggered
-				c.balancer.hostPortError(pinned, err)
-				c.balancer.next()
-				logger.Lvl(4).Infof("clientv3/retry: switching from %q due to error %q", pinned, err.Error())
-			}
-
-			if isStop(err) {
-				return err
-			}
-		}
-	}
-}
-
-func (c *Client) newAuthRetryWrapper(retryf retryRPCFunc) retryRPCFunc {
-	return func(rpcCtx context.Context, f rpcFunc, rp retryPolicy) error {
-		for {
-			pinned := c.balancer.pinned()
-			err := retryf(rpcCtx, f, rp)
-			if err == nil {
-				return nil
-			}
-			logger.Lvl(4).Infof("clientv3/auth-retry: error %q on pinned endpoint %q", err.Error(), pinned)
-			// always stop retry on etcd errors other than invalid auth token
-			if rpctypes.Error(err) == rpctypes.ErrInvalidAuthToken {
-				gterr := c.getToken(rpcCtx)
-				if gterr != nil {
-					logger.Lvl(4).Infof("clientv3/auth-retry: cannot retry due to error %q(%q) on pinned endpoint %q", err.Error(), gterr.Error(), pinned)
-					return err // return the original error for simplicity
-				}
-				continue
-			}
-			return err
-		}
-	}
-}
-
-type retryKVClient struct {
-	kc     pb.KVClient
-	retryf retryRPCFunc
-}
-
-// RetryKVClient implements a KVClient.
-func RetryKVClient(c *Client) pb.KVClient {
-	return &retryKVClient{
-		kc:     pb.NewKVClient(c.conn),
-		retryf: c.newAuthRetryWrapper(c.newRetryWrapper()),
-	}
-}
-func (rkv *retryKVClient) Range(ctx context.Context, in *pb.RangeRequest, opts ...grpc.CallOption) (resp *pb.RangeResponse, err error) {
-	err = rkv.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rkv.kc.Range(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rkv *retryKVClient) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (resp *pb.PutResponse, err error) {
-	err = rkv.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rkv.kc.Put(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rkv *retryKVClient) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (resp *pb.DeleteRangeResponse, err error) {
-	err = rkv.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rkv.kc.DeleteRange(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rkv *retryKVClient) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (resp *pb.TxnResponse, err error) {
-	// TODO: "repeatable" for read-only txn
-	err = rkv.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rkv.kc.Txn(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rkv *retryKVClient) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (resp *pb.CompactionResponse, err error) {
-	err = rkv.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rkv.kc.Compact(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-type retryLeaseClient struct {
-	lc     pb.LeaseClient
-	retryf retryRPCFunc
-}
-
-// RetryLeaseClient implements a LeaseClient.
-func RetryLeaseClient(c *Client) pb.LeaseClient {
-	return &retryLeaseClient{
-		lc:     pb.NewLeaseClient(c.conn),
-		retryf: c.newAuthRetryWrapper(c.newRetryWrapper()),
-	}
-}
-
-func (rlc *retryLeaseClient) LeaseTimeToLive(ctx context.Context, in *pb.LeaseTimeToLiveRequest, opts ...grpc.CallOption) (resp *pb.LeaseTimeToLiveResponse, err error) {
-	err = rlc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rlc.lc.LeaseTimeToLive(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rlc *retryLeaseClient) LeaseLeases(ctx context.Context, in *pb.LeaseLeasesRequest, opts ...grpc.CallOption) (resp *pb.LeaseLeasesResponse, err error) {
-	err = rlc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rlc.lc.LeaseLeases(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rlc *retryLeaseClient) LeaseGrant(ctx context.Context, in *pb.LeaseGrantRequest, opts ...grpc.CallOption) (resp *pb.LeaseGrantResponse, err error) {
-	err = rlc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rlc.lc.LeaseGrant(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-
-}
-
-func (rlc *retryLeaseClient) LeaseRevoke(ctx context.Context, in *pb.LeaseRevokeRequest, opts ...grpc.CallOption) (resp *pb.LeaseRevokeResponse, err error) {
-	err = rlc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rlc.lc.LeaseRevoke(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rlc *retryLeaseClient) LeaseKeepAlive(ctx context.Context, opts ...grpc.CallOption) (stream pb.Lease_LeaseKeepAliveClient, err error) {
-	err = rlc.retryf(ctx, func(rctx context.Context) error {
-		stream, err = rlc.lc.LeaseKeepAlive(rctx, opts...)
-		return err
-	}, repeatable)
-	return stream, err
-}
-
-type retryClusterClient struct {
-	cc     pb.ClusterClient
-	retryf retryRPCFunc
-}
-
-// RetryClusterClient implements a ClusterClient.
-func RetryClusterClient(c *Client) pb.ClusterClient {
-	return &retryClusterClient{
-		cc:     pb.NewClusterClient(c.conn),
-		retryf: c.newRetryWrapper(),
-	}
-}
-
-func (rcc *retryClusterClient) MemberList(ctx context.Context, in *pb.MemberListRequest, opts ...grpc.CallOption) (resp *pb.MemberListResponse, err error) {
-	err = rcc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rcc.cc.MemberList(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rcc *retryClusterClient) MemberAdd(ctx context.Context, in *pb.MemberAddRequest, opts ...grpc.CallOption) (resp *pb.MemberAddResponse, err error) {
-	err = rcc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rcc.cc.MemberAdd(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rcc *retryClusterClient) MemberRemove(ctx context.Context, in *pb.MemberRemoveRequest, opts ...grpc.CallOption) (resp *pb.MemberRemoveResponse, err error) {
-	err = rcc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rcc.cc.MemberRemove(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rcc *retryClusterClient) MemberUpdate(ctx context.Context, in *pb.MemberUpdateRequest, opts ...grpc.CallOption) (resp *pb.MemberUpdateResponse, err error) {
-	err = rcc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rcc.cc.MemberUpdate(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-type retryMaintenanceClient struct {
-	mc     pb.MaintenanceClient
-	retryf retryRPCFunc
-}
-
-// RetryMaintenanceClient implements a Maintenance.
-func RetryMaintenanceClient(c *Client, conn *grpc.ClientConn) pb.MaintenanceClient {
-	return &retryMaintenanceClient{
-		mc:     pb.NewMaintenanceClient(conn),
-		retryf: c.newRetryWrapper(),
-	}
-}
-
-func (rmc *retryMaintenanceClient) Alarm(ctx context.Context, in *pb.AlarmRequest, opts ...grpc.CallOption) (resp *pb.AlarmResponse, err error) {
-	err = rmc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rmc.mc.Alarm(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rmc *retryMaintenanceClient) Status(ctx context.Context, in *pb.StatusRequest, opts ...grpc.CallOption) (resp *pb.StatusResponse, err error) {
-	err = rmc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rmc.mc.Status(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rmc *retryMaintenanceClient) Hash(ctx context.Context, in *pb.HashRequest, opts ...grpc.CallOption) (resp *pb.HashResponse, err error) {
-	err = rmc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rmc.mc.Hash(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rmc *retryMaintenanceClient) HashKV(ctx context.Context, in *pb.HashKVRequest, opts ...grpc.CallOption) (resp *pb.HashKVResponse, err error) {
-	err = rmc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rmc.mc.HashKV(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rmc *retryMaintenanceClient) Snapshot(ctx context.Context, in *pb.SnapshotRequest, opts ...grpc.CallOption) (stream pb.Maintenance_SnapshotClient, err error) {
-	err = rmc.retryf(ctx, func(rctx context.Context) error {
-		stream, err = rmc.mc.Snapshot(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return stream, err
-}
-
-func (rmc *retryMaintenanceClient) MoveLeader(ctx context.Context, in *pb.MoveLeaderRequest, opts ...grpc.CallOption) (resp *pb.MoveLeaderResponse, err error) {
-	err = rmc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rmc.mc.MoveLeader(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rmc *retryMaintenanceClient) Defragment(ctx context.Context, in *pb.DefragmentRequest, opts ...grpc.CallOption) (resp *pb.DefragmentResponse, err error) {
-	err = rmc.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rmc.mc.Defragment(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-type retryAuthClient struct {
-	ac     pb.AuthClient
-	retryf retryRPCFunc
-}
-
-// RetryAuthClient implements a AuthClient.
-func RetryAuthClient(c *Client) pb.AuthClient {
-	return &retryAuthClient{
-		ac:     pb.NewAuthClient(c.conn),
-		retryf: c.newRetryWrapper(),
-	}
-}
-
-func (rac *retryAuthClient) UserList(ctx context.Context, in *pb.AuthUserListRequest, opts ...grpc.CallOption) (resp *pb.AuthUserListResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.UserList(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) UserGet(ctx context.Context, in *pb.AuthUserGetRequest, opts ...grpc.CallOption) (resp *pb.AuthUserGetResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.UserGet(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) RoleGet(ctx context.Context, in *pb.AuthRoleGetRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleGetResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.RoleGet(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) RoleList(ctx context.Context, in *pb.AuthRoleListRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleListResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.RoleList(rctx, in, opts...)
-		return err
-	}, repeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) AuthEnable(ctx context.Context, in *pb.AuthEnableRequest, opts ...grpc.CallOption) (resp *pb.AuthEnableResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.AuthEnable(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) AuthDisable(ctx context.Context, in *pb.AuthDisableRequest, opts ...grpc.CallOption) (resp *pb.AuthDisableResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.AuthDisable(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) UserAdd(ctx context.Context, in *pb.AuthUserAddRequest, opts ...grpc.CallOption) (resp *pb.AuthUserAddResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.UserAdd(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) UserDelete(ctx context.Context, in *pb.AuthUserDeleteRequest, opts ...grpc.CallOption) (resp *pb.AuthUserDeleteResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.UserDelete(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) UserChangePassword(ctx context.Context, in *pb.AuthUserChangePasswordRequest, opts ...grpc.CallOption) (resp *pb.AuthUserChangePasswordResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.UserChangePassword(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) UserGrantRole(ctx context.Context, in *pb.AuthUserGrantRoleRequest, opts ...grpc.CallOption) (resp *pb.AuthUserGrantRoleResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.UserGrantRole(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) UserRevokeRole(ctx context.Context, in *pb.AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (resp *pb.AuthUserRevokeRoleResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.UserRevokeRole(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) RoleAdd(ctx context.Context, in *pb.AuthRoleAddRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleAddResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.RoleAdd(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) RoleDelete(ctx context.Context, in *pb.AuthRoleDeleteRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleDeleteResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.RoleDelete(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) RoleGrantPermission(ctx context.Context, in *pb.AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleGrantPermissionResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.RoleGrantPermission(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) RoleRevokePermission(ctx context.Context, in *pb.AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (resp *pb.AuthRoleRevokePermissionResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.RoleRevokePermission(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
-
-func (rac *retryAuthClient) Authenticate(ctx context.Context, in *pb.AuthenticateRequest, opts ...grpc.CallOption) (resp *pb.AuthenticateResponse, err error) {
-	err = rac.retryf(ctx, func(rctx context.Context) error {
-		resp, err = rac.ac.Authenticate(rctx, in, opts...)
-		return err
-	}, nonRepeatable)
-	return resp, err
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/sort.go b/vendor/github.com/coreos/etcd/clientv3/sort.go
deleted file mode 100644
index 2bb9d9a..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/sort.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-type SortTarget int
-type SortOrder int
-
-const (
-	SortNone SortOrder = iota
-	SortAscend
-	SortDescend
-)
-
-const (
-	SortByKey SortTarget = iota
-	SortByVersion
-	SortByCreateRevision
-	SortByModRevision
-	SortByValue
-)
-
-type SortOption struct {
-	Target SortTarget
-	Order  SortOrder
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/txn.go b/vendor/github.com/coreos/etcd/clientv3/txn.go
deleted file mode 100644
index c3c2d24..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/txn.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-	"sync"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-)
-
-// Txn is the interface that wraps mini-transactions.
-//
-//	 Txn(context.TODO()).If(
-//	  Compare(Value(k1), ">", v1),
-//	  Compare(Version(k1), "=", 2)
-//	 ).Then(
-//	  OpPut(k2,v2), OpPut(k3,v3)
-//	 ).Else(
-//	  OpPut(k4,v4), OpPut(k5,v5)
-//	 ).Commit()
-//
-type Txn interface {
-	// If takes a list of comparison. If all comparisons passed in succeed,
-	// the operations passed into Then() will be executed. Or the operations
-	// passed into Else() will be executed.
-	If(cs ...Cmp) Txn
-
-	// Then takes a list of operations. The Ops list will be executed, if the
-	// comparisons passed in If() succeed.
-	Then(ops ...Op) Txn
-
-	// Else takes a list of operations. The Ops list will be executed, if the
-	// comparisons passed in If() fail.
-	Else(ops ...Op) Txn
-
-	// Commit tries to commit the transaction.
-	Commit() (*TxnResponse, error)
-}
-
-type txn struct {
-	kv  *kv
-	ctx context.Context
-
-	mu    sync.Mutex
-	cif   bool
-	cthen bool
-	celse bool
-
-	isWrite bool
-
-	cmps []*pb.Compare
-
-	sus []*pb.RequestOp
-	fas []*pb.RequestOp
-
-	callOpts []grpc.CallOption
-}
-
-func (txn *txn) If(cs ...Cmp) Txn {
-	txn.mu.Lock()
-	defer txn.mu.Unlock()
-
-	if txn.cif {
-		panic("cannot call If twice!")
-	}
-
-	if txn.cthen {
-		panic("cannot call If after Then!")
-	}
-
-	if txn.celse {
-		panic("cannot call If after Else!")
-	}
-
-	txn.cif = true
-
-	for i := range cs {
-		txn.cmps = append(txn.cmps, (*pb.Compare)(&cs[i]))
-	}
-
-	return txn
-}
-
-func (txn *txn) Then(ops ...Op) Txn {
-	txn.mu.Lock()
-	defer txn.mu.Unlock()
-
-	if txn.cthen {
-		panic("cannot call Then twice!")
-	}
-	if txn.celse {
-		panic("cannot call Then after Else!")
-	}
-
-	txn.cthen = true
-
-	for _, op := range ops {
-		txn.isWrite = txn.isWrite || op.isWrite()
-		txn.sus = append(txn.sus, op.toRequestOp())
-	}
-
-	return txn
-}
-
-func (txn *txn) Else(ops ...Op) Txn {
-	txn.mu.Lock()
-	defer txn.mu.Unlock()
-
-	if txn.celse {
-		panic("cannot call Else twice!")
-	}
-
-	txn.celse = true
-
-	for _, op := range ops {
-		txn.isWrite = txn.isWrite || op.isWrite()
-		txn.fas = append(txn.fas, op.toRequestOp())
-	}
-
-	return txn
-}
-
-func (txn *txn) Commit() (*TxnResponse, error) {
-	txn.mu.Lock()
-	defer txn.mu.Unlock()
-
-	r := &pb.TxnRequest{Compare: txn.cmps, Success: txn.sus, Failure: txn.fas}
-
-	var resp *pb.TxnResponse
-	var err error
-	resp, err = txn.kv.remote.Txn(txn.ctx, r, txn.callOpts...)
-	if err != nil {
-		return nil, toErr(txn.ctx, err)
-	}
-	return (*TxnResponse)(resp), nil
-}
diff --git a/vendor/github.com/coreos/etcd/clientv3/watch.go b/vendor/github.com/coreos/etcd/clientv3/watch.go
deleted file mode 100644
index d763385..0000000
--- a/vendor/github.com/coreos/etcd/clientv3/watch.go
+++ /dev/null
@@ -1,828 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package clientv3
-
-import (
-	"context"
-	"fmt"
-	"sync"
-	"time"
-
-	v3rpc "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	mvccpb "github.com/coreos/etcd/mvcc/mvccpb"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/status"
-)
-
-const (
-	EventTypeDelete = mvccpb.DELETE
-	EventTypePut    = mvccpb.PUT
-
-	closeSendErrTimeout = 250 * time.Millisecond
-)
-
-type Event mvccpb.Event
-
-type WatchChan <-chan WatchResponse
-
-type Watcher interface {
-	// Watch watches on a key or prefix. The watched events will be returned
-	// through the returned channel. If revisions waiting to be sent over the
-	// watch are compacted, then the watch will be canceled by the server, the
-	// client will post a compacted error watch response, and the channel will close.
-	Watch(ctx context.Context, key string, opts ...OpOption) WatchChan
-
-	// Close closes the watcher and cancels all watch requests.
-	Close() error
-}
-
-type WatchResponse struct {
-	Header pb.ResponseHeader
-	Events []*Event
-
-	// CompactRevision is the minimum revision the watcher may receive.
-	CompactRevision int64
-
-	// Canceled is used to indicate watch failure.
-	// If the watch failed and the stream was about to close, before the channel is closed,
-	// the channel sends a final response that has Canceled set to true with a non-nil Err().
-	Canceled bool
-
-	// Created is used to indicate the creation of the watcher.
-	Created bool
-
-	closeErr error
-
-	// cancelReason is a reason of canceling watch
-	cancelReason string
-}
-
-// IsCreate returns true if the event tells that the key is newly created.
-func (e *Event) IsCreate() bool {
-	return e.Type == EventTypePut && e.Kv.CreateRevision == e.Kv.ModRevision
-}
-
-// IsModify returns true if the event tells that a new value is put on existing key.
-func (e *Event) IsModify() bool {
-	return e.Type == EventTypePut && e.Kv.CreateRevision != e.Kv.ModRevision
-}
-
-// Err is the error value if this WatchResponse holds an error.
-func (wr *WatchResponse) Err() error {
-	switch {
-	case wr.closeErr != nil:
-		return v3rpc.Error(wr.closeErr)
-	case wr.CompactRevision != 0:
-		return v3rpc.ErrCompacted
-	case wr.Canceled:
-		if len(wr.cancelReason) != 0 {
-			return v3rpc.Error(status.Error(codes.FailedPrecondition, wr.cancelReason))
-		}
-		return v3rpc.ErrFutureRev
-	}
-	return nil
-}
-
-// IsProgressNotify returns true if the WatchResponse is progress notification.
-func (wr *WatchResponse) IsProgressNotify() bool {
-	return len(wr.Events) == 0 && !wr.Canceled && !wr.Created && wr.CompactRevision == 0 && wr.Header.Revision != 0
-}
-
-// watcher implements the Watcher interface
-type watcher struct {
-	remote   pb.WatchClient
-	callOpts []grpc.CallOption
-
-	// mu protects the grpc streams map
-	mu sync.RWMutex
-
-	// streams holds all the active grpc streams keyed by ctx value.
-	streams map[string]*watchGrpcStream
-}
-
-// watchGrpcStream tracks all watch resources attached to a single grpc stream.
-type watchGrpcStream struct {
-	owner    *watcher
-	remote   pb.WatchClient
-	callOpts []grpc.CallOption
-
-	// ctx controls internal remote.Watch requests
-	ctx context.Context
-	// ctxKey is the key used when looking up this stream's context
-	ctxKey string
-	cancel context.CancelFunc
-
-	// substreams holds all active watchers on this grpc stream
-	substreams map[int64]*watcherStream
-	// resuming holds all resuming watchers on this grpc stream
-	resuming []*watcherStream
-
-	// reqc sends a watch request from Watch() to the main goroutine
-	reqc chan *watchRequest
-	// respc receives data from the watch client
-	respc chan *pb.WatchResponse
-	// donec closes to broadcast shutdown
-	donec chan struct{}
-	// errc transmits errors from grpc Recv to the watch stream reconnect logic
-	errc chan error
-	// closingc gets the watcherStream of closing watchers
-	closingc chan *watcherStream
-	// wg is Done when all substream goroutines have exited
-	wg sync.WaitGroup
-
-	// resumec closes to signal that all substreams should begin resuming
-	resumec chan struct{}
-	// closeErr is the error that closed the watch stream
-	closeErr error
-}
-
-// watchRequest is issued by the subscriber to start a new watcher
-type watchRequest struct {
-	ctx context.Context
-	key string
-	end string
-	rev int64
-	// send created notification event if this field is true
-	createdNotify bool
-	// progressNotify is for progress updates
-	progressNotify bool
-	// filters is the list of events to filter out
-	filters []pb.WatchCreateRequest_FilterType
-	// get the previous key-value pair before the event happens
-	prevKV bool
-	// retc receives a chan WatchResponse once the watcher is established
-	retc chan chan WatchResponse
-}
-
-// watcherStream represents a registered watcher
-type watcherStream struct {
-	// initReq is the request that initiated this request
-	initReq watchRequest
-
-	// outc publishes watch responses to subscriber
-	outc chan WatchResponse
-	// recvc buffers watch responses before publishing
-	recvc chan *WatchResponse
-	// donec closes when the watcherStream goroutine stops.
-	donec chan struct{}
-	// closing is set to true when stream should be scheduled to shutdown.
-	closing bool
-	// id is the registered watch id on the grpc stream
-	id int64
-
-	// buf holds all events received from etcd but not yet consumed by the client
-	buf []*WatchResponse
-}
-
-func NewWatcher(c *Client) Watcher {
-	return NewWatchFromWatchClient(pb.NewWatchClient(c.conn), c)
-}
-
-func NewWatchFromWatchClient(wc pb.WatchClient, c *Client) Watcher {
-	w := &watcher{
-		remote:  wc,
-		streams: make(map[string]*watchGrpcStream),
-	}
-	if c != nil {
-		w.callOpts = c.callOpts
-	}
-	return w
-}
-
-// never closes
-var valCtxCh = make(chan struct{})
-var zeroTime = time.Unix(0, 0)
-
-// ctx with only the values; never Done
-type valCtx struct{ context.Context }
-
-func (vc *valCtx) Deadline() (time.Time, bool) { return zeroTime, false }
-func (vc *valCtx) Done() <-chan struct{}       { return valCtxCh }
-func (vc *valCtx) Err() error                  { return nil }
-
-func (w *watcher) newWatcherGrpcStream(inctx context.Context) *watchGrpcStream {
-	ctx, cancel := context.WithCancel(&valCtx{inctx})
-	wgs := &watchGrpcStream{
-		owner:      w,
-		remote:     w.remote,
-		callOpts:   w.callOpts,
-		ctx:        ctx,
-		ctxKey:     streamKeyFromCtx(inctx),
-		cancel:     cancel,
-		substreams: make(map[int64]*watcherStream),
-		respc:      make(chan *pb.WatchResponse),
-		reqc:       make(chan *watchRequest),
-		donec:      make(chan struct{}),
-		errc:       make(chan error, 1),
-		closingc:   make(chan *watcherStream),
-		resumec:    make(chan struct{}),
-	}
-	go wgs.run()
-	return wgs
-}
-
-// Watch posts a watch request to run() and waits for a new watcher channel
-func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOption) WatchChan {
-	ow := opWatch(key, opts...)
-
-	var filters []pb.WatchCreateRequest_FilterType
-	if ow.filterPut {
-		filters = append(filters, pb.WatchCreateRequest_NOPUT)
-	}
-	if ow.filterDelete {
-		filters = append(filters, pb.WatchCreateRequest_NODELETE)
-	}
-
-	wr := &watchRequest{
-		ctx:            ctx,
-		createdNotify:  ow.createdNotify,
-		key:            string(ow.key),
-		end:            string(ow.end),
-		rev:            ow.rev,
-		progressNotify: ow.progressNotify,
-		filters:        filters,
-		prevKV:         ow.prevKV,
-		retc:           make(chan chan WatchResponse, 1),
-	}
-
-	ok := false
-	ctxKey := streamKeyFromCtx(ctx)
-
-	// find or allocate appropriate grpc watch stream
-	w.mu.Lock()
-	if w.streams == nil {
-		// closed
-		w.mu.Unlock()
-		ch := make(chan WatchResponse)
-		close(ch)
-		return ch
-	}
-	wgs := w.streams[ctxKey]
-	if wgs == nil {
-		wgs = w.newWatcherGrpcStream(ctx)
-		w.streams[ctxKey] = wgs
-	}
-	donec := wgs.donec
-	reqc := wgs.reqc
-	w.mu.Unlock()
-
-	// couldn't create channel; return closed channel
-	closeCh := make(chan WatchResponse, 1)
-
-	// submit request
-	select {
-	case reqc <- wr:
-		ok = true
-	case <-wr.ctx.Done():
-	case <-donec:
-		if wgs.closeErr != nil {
-			closeCh <- WatchResponse{closeErr: wgs.closeErr}
-			break
-		}
-		// retry; may have dropped stream from no ctxs
-		return w.Watch(ctx, key, opts...)
-	}
-
-	// receive channel
-	if ok {
-		select {
-		case ret := <-wr.retc:
-			return ret
-		case <-ctx.Done():
-		case <-donec:
-			if wgs.closeErr != nil {
-				closeCh <- WatchResponse{closeErr: wgs.closeErr}
-				break
-			}
-			// retry; may have dropped stream from no ctxs
-			return w.Watch(ctx, key, opts...)
-		}
-	}
-
-	close(closeCh)
-	return closeCh
-}
-
-func (w *watcher) Close() (err error) {
-	w.mu.Lock()
-	streams := w.streams
-	w.streams = nil
-	w.mu.Unlock()
-	for _, wgs := range streams {
-		if werr := wgs.close(); werr != nil {
-			err = werr
-		}
-	}
-	return err
-}
-
-func (w *watchGrpcStream) close() (err error) {
-	w.cancel()
-	<-w.donec
-	select {
-	case err = <-w.errc:
-	default:
-	}
-	return toErr(w.ctx, err)
-}
-
-func (w *watcher) closeStream(wgs *watchGrpcStream) {
-	w.mu.Lock()
-	close(wgs.donec)
-	wgs.cancel()
-	if w.streams != nil {
-		delete(w.streams, wgs.ctxKey)
-	}
-	w.mu.Unlock()
-}
-
-func (w *watchGrpcStream) addSubstream(resp *pb.WatchResponse, ws *watcherStream) {
-	if resp.WatchId == -1 {
-		// failed; no channel
-		close(ws.recvc)
-		return
-	}
-	ws.id = resp.WatchId
-	w.substreams[ws.id] = ws
-}
-
-func (w *watchGrpcStream) sendCloseSubstream(ws *watcherStream, resp *WatchResponse) {
-	select {
-	case ws.outc <- *resp:
-	case <-ws.initReq.ctx.Done():
-	case <-time.After(closeSendErrTimeout):
-	}
-	close(ws.outc)
-}
-
-func (w *watchGrpcStream) closeSubstream(ws *watcherStream) {
-	// send channel response in case stream was never established
-	select {
-	case ws.initReq.retc <- ws.outc:
-	default:
-	}
-	// close subscriber's channel
-	if closeErr := w.closeErr; closeErr != nil && ws.initReq.ctx.Err() == nil {
-		go w.sendCloseSubstream(ws, &WatchResponse{closeErr: w.closeErr})
-	} else if ws.outc != nil {
-		close(ws.outc)
-	}
-	if ws.id != -1 {
-		delete(w.substreams, ws.id)
-		return
-	}
-	for i := range w.resuming {
-		if w.resuming[i] == ws {
-			w.resuming[i] = nil
-			return
-		}
-	}
-}
-
-// run is the root of the goroutines for managing a watcher client
-func (w *watchGrpcStream) run() {
-	var wc pb.Watch_WatchClient
-	var closeErr error
-
-	// substreams marked to close but goroutine still running; needed for
-	// avoiding double-closing recvc on grpc stream teardown
-	closing := make(map[*watcherStream]struct{})
-
-	defer func() {
-		w.closeErr = closeErr
-		// shutdown substreams and resuming substreams
-		for _, ws := range w.substreams {
-			if _, ok := closing[ws]; !ok {
-				close(ws.recvc)
-				closing[ws] = struct{}{}
-			}
-		}
-		for _, ws := range w.resuming {
-			if _, ok := closing[ws]; ws != nil && !ok {
-				close(ws.recvc)
-				closing[ws] = struct{}{}
-			}
-		}
-		w.joinSubstreams()
-		for range closing {
-			w.closeSubstream(<-w.closingc)
-		}
-		w.wg.Wait()
-		w.owner.closeStream(w)
-	}()
-
-	// start a stream with the etcd grpc server
-	if wc, closeErr = w.newWatchClient(); closeErr != nil {
-		return
-	}
-
-	cancelSet := make(map[int64]struct{})
-
-	for {
-		select {
-		// Watch() requested
-		case wreq := <-w.reqc:
-			outc := make(chan WatchResponse, 1)
-			ws := &watcherStream{
-				initReq: *wreq,
-				id:      -1,
-				outc:    outc,
-				// unbuffered so resumes won't cause repeat events
-				recvc: make(chan *WatchResponse),
-			}
-
-			ws.donec = make(chan struct{})
-			w.wg.Add(1)
-			go w.serveSubstream(ws, w.resumec)
-
-			// queue up for watcher creation/resume
-			w.resuming = append(w.resuming, ws)
-			if len(w.resuming) == 1 {
-				// head of resume queue, can register a new watcher
-				wc.Send(ws.initReq.toPB())
-			}
-		// New events from the watch client
-		case pbresp := <-w.respc:
-			switch {
-			case pbresp.Created:
-				// response to head of queue creation
-				if ws := w.resuming[0]; ws != nil {
-					w.addSubstream(pbresp, ws)
-					w.dispatchEvent(pbresp)
-					w.resuming[0] = nil
-				}
-				if ws := w.nextResume(); ws != nil {
-					wc.Send(ws.initReq.toPB())
-				}
-			case pbresp.Canceled && pbresp.CompactRevision == 0:
-				delete(cancelSet, pbresp.WatchId)
-				if ws, ok := w.substreams[pbresp.WatchId]; ok {
-					// signal to stream goroutine to update closingc
-					close(ws.recvc)
-					closing[ws] = struct{}{}
-				}
-			default:
-				// dispatch to appropriate watch stream
-				if ok := w.dispatchEvent(pbresp); ok {
-					break
-				}
-				// watch response on unexpected watch id; cancel id
-				if _, ok := cancelSet[pbresp.WatchId]; ok {
-					break
-				}
-				cancelSet[pbresp.WatchId] = struct{}{}
-				cr := &pb.WatchRequest_CancelRequest{
-					CancelRequest: &pb.WatchCancelRequest{
-						WatchId: pbresp.WatchId,
-					},
-				}
-				req := &pb.WatchRequest{RequestUnion: cr}
-				wc.Send(req)
-			}
-		// watch client failed on Recv; spawn another if possible
-		case err := <-w.errc:
-			if isHaltErr(w.ctx, err) || toErr(w.ctx, err) == v3rpc.ErrNoLeader {
-				closeErr = err
-				return
-			}
-			if wc, closeErr = w.newWatchClient(); closeErr != nil {
-				return
-			}
-			if ws := w.nextResume(); ws != nil {
-				wc.Send(ws.initReq.toPB())
-			}
-			cancelSet = make(map[int64]struct{})
-		case <-w.ctx.Done():
-			return
-		case ws := <-w.closingc:
-			w.closeSubstream(ws)
-			delete(closing, ws)
-			if len(w.substreams)+len(w.resuming) == 0 {
-				// no more watchers on this stream, shutdown
-				return
-			}
-		}
-	}
-}
-
-// nextResume chooses the next resuming to register with the grpc stream. Abandoned
-// streams are marked as nil in the queue since the head must wait for its inflight registration.
-func (w *watchGrpcStream) nextResume() *watcherStream {
-	for len(w.resuming) != 0 {
-		if w.resuming[0] != nil {
-			return w.resuming[0]
-		}
-		w.resuming = w.resuming[1:len(w.resuming)]
-	}
-	return nil
-}
-
-// dispatchEvent sends a WatchResponse to the appropriate watcher stream
-func (w *watchGrpcStream) dispatchEvent(pbresp *pb.WatchResponse) bool {
-	events := make([]*Event, len(pbresp.Events))
-	for i, ev := range pbresp.Events {
-		events[i] = (*Event)(ev)
-	}
-	wr := &WatchResponse{
-		Header:          *pbresp.Header,
-		Events:          events,
-		CompactRevision: pbresp.CompactRevision,
-		Created:         pbresp.Created,
-		Canceled:        pbresp.Canceled,
-		cancelReason:    pbresp.CancelReason,
-	}
-	ws, ok := w.substreams[pbresp.WatchId]
-	if !ok {
-		return false
-	}
-	select {
-	case ws.recvc <- wr:
-	case <-ws.donec:
-		return false
-	}
-	return true
-}
-
-// serveWatchClient forwards messages from the grpc stream to run()
-func (w *watchGrpcStream) serveWatchClient(wc pb.Watch_WatchClient) {
-	for {
-		resp, err := wc.Recv()
-		if err != nil {
-			select {
-			case w.errc <- err:
-			case <-w.donec:
-			}
-			return
-		}
-		select {
-		case w.respc <- resp:
-		case <-w.donec:
-			return
-		}
-	}
-}
-
-// serveSubstream forwards watch responses from run() to the subscriber
-func (w *watchGrpcStream) serveSubstream(ws *watcherStream, resumec chan struct{}) {
-	if ws.closing {
-		panic("created substream goroutine but substream is closing")
-	}
-
-	// nextRev is the minimum expected next revision
-	nextRev := ws.initReq.rev
-	resuming := false
-	defer func() {
-		if !resuming {
-			ws.closing = true
-		}
-		close(ws.donec)
-		if !resuming {
-			w.closingc <- ws
-		}
-		w.wg.Done()
-	}()
-
-	emptyWr := &WatchResponse{}
-	for {
-		curWr := emptyWr
-		outc := ws.outc
-
-		if len(ws.buf) > 0 {
-			curWr = ws.buf[0]
-		} else {
-			outc = nil
-		}
-		select {
-		case outc <- *curWr:
-			if ws.buf[0].Err() != nil {
-				return
-			}
-			ws.buf[0] = nil
-			ws.buf = ws.buf[1:]
-		case wr, ok := <-ws.recvc:
-			if !ok {
-				// shutdown from closeSubstream
-				return
-			}
-
-			if wr.Created {
-				if ws.initReq.retc != nil {
-					ws.initReq.retc <- ws.outc
-					// to prevent next write from taking the slot in buffered channel
-					// and posting duplicate create events
-					ws.initReq.retc = nil
-
-					// send first creation event only if requested
-					if ws.initReq.createdNotify {
-						ws.outc <- *wr
-					}
-					// once the watch channel is returned, a current revision
-					// watch must resume at the store revision. This is necessary
-					// for the following case to work as expected:
-					//	wch := m1.Watch("a")
-					//	m2.Put("a", "b")
-					//	<-wch
-					// If the revision is only bound on the first observed event,
-					// if wch is disconnected before the Put is issued, then reconnects
-					// after it is committed, it'll miss the Put.
-					if ws.initReq.rev == 0 {
-						nextRev = wr.Header.Revision
-					}
-				}
-			} else {
-				// current progress of watch; <= store revision
-				nextRev = wr.Header.Revision
-			}
-
-			if len(wr.Events) > 0 {
-				nextRev = wr.Events[len(wr.Events)-1].Kv.ModRevision + 1
-			}
-			ws.initReq.rev = nextRev
-
-			// created event is already sent above,
-			// watcher should not post duplicate events
-			if wr.Created {
-				continue
-			}
-
-			// TODO pause channel if buffer gets too large
-			ws.buf = append(ws.buf, wr)
-		case <-w.ctx.Done():
-			return
-		case <-ws.initReq.ctx.Done():
-			return
-		case <-resumec:
-			resuming = true
-			return
-		}
-	}
-	// lazily send cancel message if events on missing id
-}
-
-func (w *watchGrpcStream) newWatchClient() (pb.Watch_WatchClient, error) {
-	// mark all substreams as resuming
-	close(w.resumec)
-	w.resumec = make(chan struct{})
-	w.joinSubstreams()
-	for _, ws := range w.substreams {
-		ws.id = -1
-		w.resuming = append(w.resuming, ws)
-	}
-	// strip out nils, if any
-	var resuming []*watcherStream
-	for _, ws := range w.resuming {
-		if ws != nil {
-			resuming = append(resuming, ws)
-		}
-	}
-	w.resuming = resuming
-	w.substreams = make(map[int64]*watcherStream)
-
-	// connect to grpc stream while accepting watcher cancelation
-	stopc := make(chan struct{})
-	donec := w.waitCancelSubstreams(stopc)
-	wc, err := w.openWatchClient()
-	close(stopc)
-	<-donec
-
-	// serve all non-closing streams, even if there's a client error
-	// so that the teardown path can shutdown the streams as expected.
-	for _, ws := range w.resuming {
-		if ws.closing {
-			continue
-		}
-		ws.donec = make(chan struct{})
-		w.wg.Add(1)
-		go w.serveSubstream(ws, w.resumec)
-	}
-
-	if err != nil {
-		return nil, v3rpc.Error(err)
-	}
-
-	// receive data from new grpc stream
-	go w.serveWatchClient(wc)
-	return wc, nil
-}
-
-func (w *watchGrpcStream) waitCancelSubstreams(stopc <-chan struct{}) <-chan struct{} {
-	var wg sync.WaitGroup
-	wg.Add(len(w.resuming))
-	donec := make(chan struct{})
-	for i := range w.resuming {
-		go func(ws *watcherStream) {
-			defer wg.Done()
-			if ws.closing {
-				if ws.initReq.ctx.Err() != nil && ws.outc != nil {
-					close(ws.outc)
-					ws.outc = nil
-				}
-				return
-			}
-			select {
-			case <-ws.initReq.ctx.Done():
-				// closed ws will be removed from resuming
-				ws.closing = true
-				close(ws.outc)
-				ws.outc = nil
-				w.wg.Add(1)
-				go func() {
-					defer w.wg.Done()
-					w.closingc <- ws
-				}()
-			case <-stopc:
-			}
-		}(w.resuming[i])
-	}
-	go func() {
-		defer close(donec)
-		wg.Wait()
-	}()
-	return donec
-}
-
-// joinSubstreams waits for all substream goroutines to complete.
-func (w *watchGrpcStream) joinSubstreams() {
-	for _, ws := range w.substreams {
-		<-ws.donec
-	}
-	for _, ws := range w.resuming {
-		if ws != nil {
-			<-ws.donec
-		}
-	}
-}
-
-var maxBackoff = 100 * time.Millisecond
-
-// openWatchClient retries opening a watch client until success or halt.
-// manually retry in case "ws==nil && err==nil"
-// TODO: remove FailFast=false
-func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, err error) {
-	backoff := time.Millisecond
-	for {
-		select {
-		case <-w.ctx.Done():
-			if err == nil {
-				return nil, w.ctx.Err()
-			}
-			return nil, err
-		default:
-		}
-		if ws, err = w.remote.Watch(w.ctx, w.callOpts...); ws != nil && err == nil {
-			break
-		}
-		if isHaltErr(w.ctx, err) {
-			return nil, v3rpc.Error(err)
-		}
-		if isUnavailableErr(w.ctx, err) {
-			// retry, but backoff
-			if backoff < maxBackoff {
-				// 25% backoff factor
-				backoff = backoff + backoff/4
-				if backoff > maxBackoff {
-					backoff = maxBackoff
-				}
-			}
-			time.Sleep(backoff)
-		}
-	}
-	return ws, nil
-}
-
-// toPB converts an internal watch request structure to its protobuf WatchRequest structure.
-func (wr *watchRequest) toPB() *pb.WatchRequest {
-	req := &pb.WatchCreateRequest{
-		StartRevision:  wr.rev,
-		Key:            []byte(wr.key),
-		RangeEnd:       []byte(wr.end),
-		ProgressNotify: wr.progressNotify,
-		Filters:        wr.filters,
-		PrevKv:         wr.prevKV,
-	}
-	cr := &pb.WatchRequest_CreateRequest{CreateRequest: req}
-	return &pb.WatchRequest{RequestUnion: cr}
-}
-
-func streamKeyFromCtx(ctx context.Context) string {
-	if md, ok := metadata.FromOutgoingContext(ctx); ok {
-		return fmt.Sprintf("%+v", md)
-	}
-	return ""
-}
diff --git a/vendor/github.com/coreos/etcd/compactor/compactor.go b/vendor/github.com/coreos/etcd/compactor/compactor.go
deleted file mode 100644
index 8100b69..0000000
--- a/vendor/github.com/coreos/etcd/compactor/compactor.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package compactor
-
-import (
-	"context"
-	"fmt"
-	"time"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "compactor")
-)
-
-const (
-	ModePeriodic = "periodic"
-	ModeRevision = "revision"
-)
-
-// Compactor purges old log from the storage periodically.
-type Compactor interface {
-	// Run starts the main loop of the compactor in background.
-	// Use Stop() to halt the loop and release the resource.
-	Run()
-	// Stop halts the main loop of the compactor.
-	Stop()
-	// Pause temporally suspend the compactor not to run compaction. Resume() to unpose.
-	Pause()
-	// Resume restarts the compactor suspended by Pause().
-	Resume()
-}
-
-type Compactable interface {
-	Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error)
-}
-
-type RevGetter interface {
-	Rev() int64
-}
-
-func New(mode string, retention time.Duration, rg RevGetter, c Compactable) (Compactor, error) {
-	switch mode {
-	case ModePeriodic:
-		return NewPeriodic(retention, rg, c), nil
-	case ModeRevision:
-		return NewRevision(int64(retention), rg, c), nil
-	default:
-		return nil, fmt.Errorf("unsupported compaction mode %s", mode)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/compactor/doc.go b/vendor/github.com/coreos/etcd/compactor/doc.go
deleted file mode 100644
index cb15834..0000000
--- a/vendor/github.com/coreos/etcd/compactor/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package compactor implements automated policies for compacting etcd's mvcc storage.
-package compactor
diff --git a/vendor/github.com/coreos/etcd/compactor/periodic.go b/vendor/github.com/coreos/etcd/compactor/periodic.go
deleted file mode 100644
index 9d9164e..0000000
--- a/vendor/github.com/coreos/etcd/compactor/periodic.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package compactor
-
-import (
-	"context"
-	"sync"
-	"time"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc"
-
-	"github.com/jonboulle/clockwork"
-)
-
-// Periodic compacts the log by purging revisions older than
-// the configured retention time.
-type Periodic struct {
-	clock  clockwork.Clock
-	period time.Duration
-
-	rg RevGetter
-	c  Compactable
-
-	revs   []int64
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	// mu protects paused
-	mu     sync.RWMutex
-	paused bool
-}
-
-// NewPeriodic creates a new instance of Periodic compactor that purges
-// the log older than h Duration.
-func NewPeriodic(h time.Duration, rg RevGetter, c Compactable) *Periodic {
-	return newPeriodic(clockwork.NewRealClock(), h, rg, c)
-}
-
-func newPeriodic(clock clockwork.Clock, h time.Duration, rg RevGetter, c Compactable) *Periodic {
-	t := &Periodic{
-		clock:  clock,
-		period: h,
-		rg:     rg,
-		c:      c,
-		revs:   make([]int64, 0),
-	}
-	t.ctx, t.cancel = context.WithCancel(context.Background())
-	return t
-}
-
-/*
-Compaction period 1-hour:
-  1. compute compaction period, which is 1-hour
-  2. record revisions for every 1/10 of 1-hour (6-minute)
-  3. keep recording revisions with no compaction for first 1-hour
-  4. do compact with revs[0]
-	- success? contiue on for-loop and move sliding window; revs = revs[1:]
-	- failure? update revs, and retry after 1/10 of 1-hour (6-minute)
-
-Compaction period 24-hour:
-  1. compute compaction period, which is 1-hour
-  2. record revisions for every 1/10 of 1-hour (6-minute)
-  3. keep recording revisions with no compaction for first 24-hour
-  4. do compact with revs[0]
-	- success? contiue on for-loop and move sliding window; revs = revs[1:]
-	- failure? update revs, and retry after 1/10 of 1-hour (6-minute)
-
-Compaction period 59-min:
-  1. compute compaction period, which is 59-min
-  2. record revisions for every 1/10 of 59-min (5.9-min)
-  3. keep recording revisions with no compaction for first 59-min
-  4. do compact with revs[0]
-	- success? contiue on for-loop and move sliding window; revs = revs[1:]
-	- failure? update revs, and retry after 1/10 of 59-min (5.9-min)
-
-Compaction period 5-sec:
-  1. compute compaction period, which is 5-sec
-  2. record revisions for every 1/10 of 5-sec (0.5-sec)
-  3. keep recording revisions with no compaction for first 5-sec
-  4. do compact with revs[0]
-	- success? contiue on for-loop and move sliding window; revs = revs[1:]
-	- failure? update revs, and retry after 1/10 of 5-sec (0.5-sec)
-*/
-
-// Run runs periodic compactor.
-func (t *Periodic) Run() {
-	compactInterval := t.getCompactInterval()
-	retryInterval := t.getRetryInterval()
-	retentions := t.getRetentions()
-
-	go func() {
-		lastSuccess := t.clock.Now()
-		baseInterval := t.period
-		for {
-			t.revs = append(t.revs, t.rg.Rev())
-			if len(t.revs) > retentions {
-				t.revs = t.revs[1:] // t.revs[0] is always the rev at t.period ago
-			}
-
-			select {
-			case <-t.ctx.Done():
-				return
-			case <-t.clock.After(retryInterval):
-				t.mu.Lock()
-				p := t.paused
-				t.mu.Unlock()
-				if p {
-					continue
-				}
-			}
-
-			if t.clock.Now().Sub(lastSuccess) < baseInterval {
-				continue
-			}
-
-			// wait up to initial given period
-			if baseInterval == t.period {
-				baseInterval = compactInterval
-			}
-			rev := t.revs[0]
-
-			plog.Noticef("Starting auto-compaction at revision %d (retention: %v)", rev, t.period)
-			_, err := t.c.Compact(t.ctx, &pb.CompactionRequest{Revision: rev})
-			if err == nil || err == mvcc.ErrCompacted {
-				lastSuccess = t.clock.Now()
-				plog.Noticef("Finished auto-compaction at revision %d", rev)
-			} else {
-				plog.Noticef("Failed auto-compaction at revision %d (%v)", rev, err)
-				plog.Noticef("Retry after %v", retryInterval)
-			}
-		}
-	}()
-}
-
-// if given compaction period x is <1-hour, compact every x duration.
-// (e.g. --auto-compaction-mode 'periodic' --auto-compaction-retention='10m', then compact every 10-minute)
-// if given compaction period x is >1-hour, compact every hour.
-// (e.g. --auto-compaction-mode 'periodic' --auto-compaction-retention='2h', then compact every 1-hour)
-func (t *Periodic) getCompactInterval() time.Duration {
-	itv := t.period
-	if itv > time.Hour {
-		itv = time.Hour
-	}
-	return itv
-}
-
-func (t *Periodic) getRetentions() int {
-	return int(t.period/t.getRetryInterval()) + 1
-}
-
-const retryDivisor = 10
-
-func (t *Periodic) getRetryInterval() time.Duration {
-	itv := t.period
-	if itv > time.Hour {
-		itv = time.Hour
-	}
-	return itv / retryDivisor
-}
-
-// Stop stops periodic compactor.
-func (t *Periodic) Stop() {
-	t.cancel()
-}
-
-// Pause pauses periodic compactor.
-func (t *Periodic) Pause() {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	t.paused = true
-}
-
-// Resume resumes periodic compactor.
-func (t *Periodic) Resume() {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	t.paused = false
-}
diff --git a/vendor/github.com/coreos/etcd/compactor/revision.go b/vendor/github.com/coreos/etcd/compactor/revision.go
deleted file mode 100644
index 927e41c..0000000
--- a/vendor/github.com/coreos/etcd/compactor/revision.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package compactor
-
-import (
-	"context"
-	"sync"
-	"time"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc"
-
-	"github.com/jonboulle/clockwork"
-)
-
-// Revision compacts the log by purging revisions older than
-// the configured reivison number. Compaction happens every 5 minutes.
-type Revision struct {
-	clock     clockwork.Clock
-	retention int64
-
-	rg RevGetter
-	c  Compactable
-
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	mu     sync.Mutex
-	paused bool
-}
-
-// NewRevision creates a new instance of Revisonal compactor that purges
-// the log older than retention revisions from the current revision.
-func NewRevision(retention int64, rg RevGetter, c Compactable) *Revision {
-	return newRevision(clockwork.NewRealClock(), retention, rg, c)
-}
-
-func newRevision(clock clockwork.Clock, retention int64, rg RevGetter, c Compactable) *Revision {
-	t := &Revision{
-		clock:     clock,
-		retention: retention,
-		rg:        rg,
-		c:         c,
-	}
-	t.ctx, t.cancel = context.WithCancel(context.Background())
-	return t
-}
-
-const revInterval = 5 * time.Minute
-
-// Run runs revision-based compactor.
-func (t *Revision) Run() {
-	prev := int64(0)
-	go func() {
-		for {
-			select {
-			case <-t.ctx.Done():
-				return
-			case <-t.clock.After(revInterval):
-				t.mu.Lock()
-				p := t.paused
-				t.mu.Unlock()
-				if p {
-					continue
-				}
-			}
-
-			rev := t.rg.Rev() - t.retention
-			if rev <= 0 || rev == prev {
-				continue
-			}
-
-			plog.Noticef("Starting auto-compaction at revision %d (retention: %d revisions)", rev, t.retention)
-			_, err := t.c.Compact(t.ctx, &pb.CompactionRequest{Revision: rev})
-			if err == nil || err == mvcc.ErrCompacted {
-				prev = rev
-				plog.Noticef("Finished auto-compaction at revision %d", rev)
-			} else {
-				plog.Noticef("Failed auto-compaction at revision %d (%v)", rev, err)
-				plog.Noticef("Retry after %v", revInterval)
-			}
-		}
-	}()
-}
-
-// Stop stops revision-based compactor.
-func (t *Revision) Stop() {
-	t.cancel()
-}
-
-// Pause pauses revision-based compactor.
-func (t *Revision) Pause() {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	t.paused = true
-}
-
-// Resume resumes revision-based compactor.
-func (t *Revision) Resume() {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	t.paused = false
-}
diff --git a/vendor/github.com/coreos/etcd/cover b/vendor/github.com/coreos/etcd/cover
deleted file mode 100755
index b7ad391..0000000
--- a/vendor/github.com/coreos/etcd/cover
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env bash
-#
-# Generate coverage HTML for a package
-# e.g. PKG=./unit ./cover
-#
-set -e
-
-if [ -z "$PKG" ]; then
-	echo "cover only works with a single package, sorry"
-	exit 255
-fi
-
-COVEROUT="coverage"
-
-if ! [ -d "$COVEROUT" ]; then
-	mkdir "$COVEROUT"
-fi
-
-# strip leading dot/slash and trailing slash and sanitize other slashes
-# e.g. ./etcdserver/etcdhttp/ ==> etcdserver_etcdhttp
-COVERPKG=${PKG/#./}
-COVERPKG=${COVERPKG/#\//}
-COVERPKG=${COVERPKG/%\//}
-COVERPKG=${COVERPKG//\//_}
-
-# generate arg for "go test"
-export COVER="-coverprofile ${COVEROUT}/${COVERPKG}.out"
-
-source ./test
-
-go tool cover -html=${COVEROUT}/${COVERPKG}.out
diff --git a/vendor/github.com/coreos/etcd/discovery/discovery.go b/vendor/github.com/coreos/etcd/discovery/discovery.go
deleted file mode 100644
index 7d1fa0d..0000000
--- a/vendor/github.com/coreos/etcd/discovery/discovery.go
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package discovery provides an implementation of the cluster discovery that
-// is used by etcd.
-package discovery
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"math"
-	"net/http"
-	"net/url"
-	"path"
-	"sort"
-	"strconv"
-	"strings"
-	"time"
-
-	"github.com/coreos/etcd/client"
-	"github.com/coreos/etcd/pkg/transport"
-	"github.com/coreos/etcd/pkg/types"
-
-	"github.com/coreos/pkg/capnslog"
-	"github.com/jonboulle/clockwork"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "discovery")
-
-	ErrInvalidURL           = errors.New("discovery: invalid URL")
-	ErrBadSizeKey           = errors.New("discovery: size key is bad")
-	ErrSizeNotFound         = errors.New("discovery: size key not found")
-	ErrTokenNotFound        = errors.New("discovery: token not found")
-	ErrDuplicateID          = errors.New("discovery: found duplicate id")
-	ErrDuplicateName        = errors.New("discovery: found duplicate name")
-	ErrFullCluster          = errors.New("discovery: cluster is full")
-	ErrTooManyRetries       = errors.New("discovery: too many retries")
-	ErrBadDiscoveryEndpoint = errors.New("discovery: bad discovery endpoint")
-)
-
-var (
-	// Number of retries discovery will attempt before giving up and erroring out.
-	nRetries             = uint(math.MaxUint32)
-	maxExpoentialRetries = uint(8)
-)
-
-// JoinCluster will connect to the discovery service at the given url, and
-// register the server represented by the given id and config to the cluster
-func JoinCluster(durl, dproxyurl string, id types.ID, config string) (string, error) {
-	d, err := newDiscovery(durl, dproxyurl, id)
-	if err != nil {
-		return "", err
-	}
-	return d.joinCluster(config)
-}
-
-// GetCluster will connect to the discovery service at the given url and
-// retrieve a string describing the cluster
-func GetCluster(durl, dproxyurl string) (string, error) {
-	d, err := newDiscovery(durl, dproxyurl, 0)
-	if err != nil {
-		return "", err
-	}
-	return d.getCluster()
-}
-
-type discovery struct {
-	cluster string
-	id      types.ID
-	c       client.KeysAPI
-	retries uint
-	url     *url.URL
-
-	clock clockwork.Clock
-}
-
-// newProxyFunc builds a proxy function from the given string, which should
-// represent a URL that can be used as a proxy. It performs basic
-// sanitization of the URL and returns any error encountered.
-func newProxyFunc(proxy string) (func(*http.Request) (*url.URL, error), error) {
-	if proxy == "" {
-		return nil, nil
-	}
-	// Do a small amount of URL sanitization to help the user
-	// Derived from net/http.ProxyFromEnvironment
-	proxyURL, err := url.Parse(proxy)
-	if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") {
-		// proxy was bogus. Try prepending "http://" to it and
-		// see if that parses correctly. If not, we ignore the
-		// error and complain about the original one
-		var err2 error
-		proxyURL, err2 = url.Parse("http://" + proxy)
-		if err2 == nil {
-			err = nil
-		}
-	}
-	if err != nil {
-		return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
-	}
-
-	plog.Infof("using proxy %q", proxyURL.String())
-	return http.ProxyURL(proxyURL), nil
-}
-
-func newDiscovery(durl, dproxyurl string, id types.ID) (*discovery, error) {
-	u, err := url.Parse(durl)
-	if err != nil {
-		return nil, err
-	}
-	token := u.Path
-	u.Path = ""
-	pf, err := newProxyFunc(dproxyurl)
-	if err != nil {
-		return nil, err
-	}
-
-	// TODO: add ResponseHeaderTimeout back when watch on discovery service writes header early
-	tr, err := transport.NewTransport(transport.TLSInfo{}, 30*time.Second)
-	if err != nil {
-		return nil, err
-	}
-	tr.Proxy = pf
-	cfg := client.Config{
-		Transport: tr,
-		Endpoints: []string{u.String()},
-	}
-	c, err := client.New(cfg)
-	if err != nil {
-		return nil, err
-	}
-	dc := client.NewKeysAPIWithPrefix(c, "")
-	return &discovery{
-		cluster: token,
-		c:       dc,
-		id:      id,
-		url:     u,
-		clock:   clockwork.NewRealClock(),
-	}, nil
-}
-
-func (d *discovery) joinCluster(config string) (string, error) {
-	// fast path: if the cluster is full, return the error
-	// do not need to register to the cluster in this case.
-	if _, _, _, err := d.checkCluster(); err != nil {
-		return "", err
-	}
-
-	if err := d.createSelf(config); err != nil {
-		// Fails, even on a timeout, if createSelf times out.
-		// TODO(barakmich): Retrying the same node might want to succeed here
-		// (ie, createSelf should be idempotent for discovery).
-		return "", err
-	}
-
-	nodes, size, index, err := d.checkCluster()
-	if err != nil {
-		return "", err
-	}
-
-	all, err := d.waitNodes(nodes, size, index)
-	if err != nil {
-		return "", err
-	}
-
-	return nodesToCluster(all, size)
-}
-
-func (d *discovery) getCluster() (string, error) {
-	nodes, size, index, err := d.checkCluster()
-	if err != nil {
-		if err == ErrFullCluster {
-			return nodesToCluster(nodes, size)
-		}
-		return "", err
-	}
-
-	all, err := d.waitNodes(nodes, size, index)
-	if err != nil {
-		return "", err
-	}
-	return nodesToCluster(all, size)
-}
-
-func (d *discovery) createSelf(contents string) error {
-	ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
-	resp, err := d.c.Create(ctx, d.selfKey(), contents)
-	cancel()
-	if err != nil {
-		if eerr, ok := err.(client.Error); ok && eerr.Code == client.ErrorCodeNodeExist {
-			return ErrDuplicateID
-		}
-		return err
-	}
-
-	// ensure self appears on the server we connected to
-	w := d.c.Watcher(d.selfKey(), &client.WatcherOptions{AfterIndex: resp.Node.CreatedIndex - 1})
-	_, err = w.Next(context.Background())
-	return err
-}
-
-func (d *discovery) checkCluster() ([]*client.Node, int, uint64, error) {
-	configKey := path.Join("/", d.cluster, "_config")
-	ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
-	// find cluster size
-	resp, err := d.c.Get(ctx, path.Join(configKey, "size"), nil)
-	cancel()
-	if err != nil {
-		if eerr, ok := err.(*client.Error); ok && eerr.Code == client.ErrorCodeKeyNotFound {
-			return nil, 0, 0, ErrSizeNotFound
-		}
-		if err == client.ErrInvalidJSON {
-			return nil, 0, 0, ErrBadDiscoveryEndpoint
-		}
-		if ce, ok := err.(*client.ClusterError); ok {
-			plog.Error(ce.Detail())
-			return d.checkClusterRetry()
-		}
-		return nil, 0, 0, err
-	}
-	size, err := strconv.Atoi(resp.Node.Value)
-	if err != nil {
-		return nil, 0, 0, ErrBadSizeKey
-	}
-
-	ctx, cancel = context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
-	resp, err = d.c.Get(ctx, d.cluster, nil)
-	cancel()
-	if err != nil {
-		if ce, ok := err.(*client.ClusterError); ok {
-			plog.Error(ce.Detail())
-			return d.checkClusterRetry()
-		}
-		return nil, 0, 0, err
-	}
-	var nodes []*client.Node
-	// append non-config keys to nodes
-	for _, n := range resp.Node.Nodes {
-		if !(path.Base(n.Key) == path.Base(configKey)) {
-			nodes = append(nodes, n)
-		}
-	}
-
-	snodes := sortableNodes{nodes}
-	sort.Sort(snodes)
-
-	// find self position
-	for i := range nodes {
-		if path.Base(nodes[i].Key) == path.Base(d.selfKey()) {
-			break
-		}
-		if i >= size-1 {
-			return nodes[:size], size, resp.Index, ErrFullCluster
-		}
-	}
-	return nodes, size, resp.Index, nil
-}
-
-func (d *discovery) logAndBackoffForRetry(step string) {
-	d.retries++
-	// logAndBackoffForRetry stops exponential backoff when the retries are more than maxExpoentialRetries and is set to a constant backoff afterward.
-	retries := d.retries
-	if retries > maxExpoentialRetries {
-		retries = maxExpoentialRetries
-	}
-	retryTimeInSecond := time.Duration(0x1<<retries) * time.Second
-	plog.Infof("%s: error connecting to %s, retrying in %s", step, d.url, retryTimeInSecond)
-	d.clock.Sleep(retryTimeInSecond)
-}
-
-func (d *discovery) checkClusterRetry() ([]*client.Node, int, uint64, error) {
-	if d.retries < nRetries {
-		d.logAndBackoffForRetry("cluster status check")
-		return d.checkCluster()
-	}
-	return nil, 0, 0, ErrTooManyRetries
-}
-
-func (d *discovery) waitNodesRetry() ([]*client.Node, error) {
-	if d.retries < nRetries {
-		d.logAndBackoffForRetry("waiting for other nodes")
-		nodes, n, index, err := d.checkCluster()
-		if err != nil {
-			return nil, err
-		}
-		return d.waitNodes(nodes, n, index)
-	}
-	return nil, ErrTooManyRetries
-}
-
-func (d *discovery) waitNodes(nodes []*client.Node, size int, index uint64) ([]*client.Node, error) {
-	if len(nodes) > size {
-		nodes = nodes[:size]
-	}
-	// watch from the next index
-	w := d.c.Watcher(d.cluster, &client.WatcherOptions{AfterIndex: index, Recursive: true})
-	all := make([]*client.Node, len(nodes))
-	copy(all, nodes)
-	for _, n := range all {
-		if path.Base(n.Key) == path.Base(d.selfKey()) {
-			plog.Noticef("found self %s in the cluster", path.Base(d.selfKey()))
-		} else {
-			plog.Noticef("found peer %s in the cluster", path.Base(n.Key))
-		}
-	}
-
-	// wait for others
-	for len(all) < size {
-		plog.Noticef("found %d peer(s), waiting for %d more", len(all), size-len(all))
-		resp, err := w.Next(context.Background())
-		if err != nil {
-			if ce, ok := err.(*client.ClusterError); ok {
-				plog.Error(ce.Detail())
-				return d.waitNodesRetry()
-			}
-			return nil, err
-		}
-		plog.Noticef("found peer %s in the cluster", path.Base(resp.Node.Key))
-		all = append(all, resp.Node)
-	}
-	plog.Noticef("found %d needed peer(s)", len(all))
-	return all, nil
-}
-
-func (d *discovery) selfKey() string {
-	return path.Join("/", d.cluster, d.id.String())
-}
-
-func nodesToCluster(ns []*client.Node, size int) (string, error) {
-	s := make([]string, len(ns))
-	for i, n := range ns {
-		s[i] = n.Value
-	}
-	us := strings.Join(s, ",")
-	m, err := types.NewURLsMap(us)
-	if err != nil {
-		return us, ErrInvalidURL
-	}
-	if m.Len() != size {
-		return us, ErrDuplicateName
-	}
-	return us, nil
-}
-
-type sortableNodes struct{ Nodes []*client.Node }
-
-func (ns sortableNodes) Len() int { return len(ns.Nodes) }
-func (ns sortableNodes) Less(i, j int) bool {
-	return ns.Nodes[i].CreatedIndex < ns.Nodes[j].CreatedIndex
-}
-func (ns sortableNodes) Swap(i, j int) { ns.Nodes[i], ns.Nodes[j] = ns.Nodes[j], ns.Nodes[i] }
diff --git a/vendor/github.com/coreos/etcd/embed/config.go b/vendor/github.com/coreos/etcd/embed/config.go
deleted file mode 100644
index 835e051..0000000
--- a/vendor/github.com/coreos/etcd/embed/config.go
+++ /dev/null
@@ -1,699 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package embed
-
-import (
-	"crypto/tls"
-	"fmt"
-	"io/ioutil"
-	"net"
-	"net/http"
-	"net/url"
-	"os"
-	"path/filepath"
-	"strings"
-	"time"
-
-	"github.com/coreos/etcd/compactor"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/pkg/cors"
-	"github.com/coreos/etcd/pkg/netutil"
-	"github.com/coreos/etcd/pkg/srv"
-	"github.com/coreos/etcd/pkg/tlsutil"
-	"github.com/coreos/etcd/pkg/transport"
-	"github.com/coreos/etcd/pkg/types"
-
-	"github.com/coreos/pkg/capnslog"
-	"github.com/ghodss/yaml"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/grpclog"
-)
-
-const (
-	ClusterStateFlagNew      = "new"
-	ClusterStateFlagExisting = "existing"
-
-	DefaultName                  = "default"
-	DefaultMaxSnapshots          = 5
-	DefaultMaxWALs               = 5
-	DefaultMaxTxnOps             = uint(128)
-	DefaultMaxRequestBytes       = 1.5 * 1024 * 1024
-	DefaultGRPCKeepAliveMinTime  = 5 * time.Second
-	DefaultGRPCKeepAliveInterval = 2 * time.Hour
-	DefaultGRPCKeepAliveTimeout  = 20 * time.Second
-
-	DefaultListenPeerURLs   = "http://localhost:2380"
-	DefaultListenClientURLs = "http://localhost:2379"
-
-	DefaultLogOutput = "default"
-
-	// DefaultStrictReconfigCheck is the default value for "--strict-reconfig-check" flag.
-	// It's enabled by default.
-	DefaultStrictReconfigCheck = true
-	// DefaultEnableV2 is the default value for "--enable-v2" flag.
-	// v2 is enabled by default.
-	// TODO: disable v2 when deprecated.
-	DefaultEnableV2 = true
-
-	// maxElectionMs specifies the maximum value of election timeout.
-	// More details are listed in ../Documentation/tuning.md#time-parameters.
-	maxElectionMs = 50000
-)
-
-var (
-	ErrConflictBootstrapFlags = fmt.Errorf("multiple discovery or bootstrap flags are set. " +
-		"Choose one of \"initial-cluster\", \"discovery\" or \"discovery-srv\"")
-	ErrUnsetAdvertiseClientURLsFlag = fmt.Errorf("--advertise-client-urls is required when --listen-client-urls is set explicitly")
-
-	DefaultInitialAdvertisePeerURLs = "http://localhost:2380"
-	DefaultAdvertiseClientURLs      = "http://localhost:2379"
-
-	defaultHostname   string
-	defaultHostStatus error
-)
-
-func init() {
-	defaultHostname, defaultHostStatus = netutil.GetDefaultHost()
-}
-
-// Config holds the arguments for configuring an etcd server.
-type Config struct {
-	// member
-
-	CorsInfo       *cors.CORSInfo
-	LPUrls, LCUrls []url.URL
-	Dir            string `json:"data-dir"`
-	WalDir         string `json:"wal-dir"`
-	MaxSnapFiles   uint   `json:"max-snapshots"`
-	MaxWalFiles    uint   `json:"max-wals"`
-	Name           string `json:"name"`
-	SnapCount      uint64 `json:"snapshot-count"`
-
-	// AutoCompactionMode is either 'periodic' or 'revision'.
-	AutoCompactionMode string `json:"auto-compaction-mode"`
-	// AutoCompactionRetention is either duration string with time unit
-	// (e.g. '5m' for 5-minute), or revision unit (e.g. '5000').
-	// If no time unit is provided and compaction mode is 'periodic',
-	// the unit defaults to hour. For example, '5' translates into 5-hour.
-	AutoCompactionRetention string `json:"auto-compaction-retention"`
-
-	// TickMs is the number of milliseconds between heartbeat ticks.
-	// TODO: decouple tickMs and heartbeat tick (current heartbeat tick = 1).
-	// make ticks a cluster wide configuration.
-	TickMs     uint `json:"heartbeat-interval"`
-	ElectionMs uint `json:"election-timeout"`
-
-	// InitialElectionTickAdvance is true, then local member fast-forwards
-	// election ticks to speed up "initial" leader election trigger. This
-	// benefits the case of larger election ticks. For instance, cross
-	// datacenter deployment may require longer election timeout of 10-second.
-	// If true, local node does not need wait up to 10-second. Instead,
-	// forwards its election ticks to 8-second, and have only 2-second left
-	// before leader election.
-	//
-	// Major assumptions are that:
-	//  - cluster has no active leader thus advancing ticks enables faster
-	//    leader election, or
-	//  - cluster already has an established leader, and rejoining follower
-	//    is likely to receive heartbeats from the leader after tick advance
-	//    and before election timeout.
-	//
-	// However, when network from leader to rejoining follower is congested,
-	// and the follower does not receive leader heartbeat within left election
-	// ticks, disruptive election has to happen thus affecting cluster
-	// availabilities.
-	//
-	// Disabling this would slow down initial bootstrap process for cross
-	// datacenter deployments. Make your own tradeoffs by configuring
-	// --initial-election-tick-advance at the cost of slow initial bootstrap.
-	//
-	// If single-node, it advances ticks regardless.
-	//
-	// See https://github.com/coreos/etcd/issues/9333 for more detail.
-	InitialElectionTickAdvance bool `json:"initial-election-tick-advance"`
-
-	QuotaBackendBytes int64 `json:"quota-backend-bytes"`
-	MaxTxnOps         uint  `json:"max-txn-ops"`
-	MaxRequestBytes   uint  `json:"max-request-bytes"`
-
-	// gRPC server options
-
-	// GRPCKeepAliveMinTime is the minimum interval that a client should
-	// wait before pinging server. When client pings "too fast", server
-	// sends goaway and closes the connection (errors: too_many_pings,
-	// http2.ErrCodeEnhanceYourCalm). When too slow, nothing happens.
-	// Server expects client pings only when there is any active streams
-	// (PermitWithoutStream is set false).
-	GRPCKeepAliveMinTime time.Duration `json:"grpc-keepalive-min-time"`
-	// GRPCKeepAliveInterval is the frequency of server-to-client ping
-	// to check if a connection is alive. Close a non-responsive connection
-	// after an additional duration of Timeout. 0 to disable.
-	GRPCKeepAliveInterval time.Duration `json:"grpc-keepalive-interval"`
-	// GRPCKeepAliveTimeout is the additional duration of wait
-	// before closing a non-responsive connection. 0 to disable.
-	GRPCKeepAliveTimeout time.Duration `json:"grpc-keepalive-timeout"`
-
-	// clustering
-
-	APUrls, ACUrls      []url.URL
-	ClusterState        string `json:"initial-cluster-state"`
-	DNSCluster          string `json:"discovery-srv"`
-	Dproxy              string `json:"discovery-proxy"`
-	Durl                string `json:"discovery"`
-	InitialCluster      string `json:"initial-cluster"`
-	InitialClusterToken string `json:"initial-cluster-token"`
-	StrictReconfigCheck bool   `json:"strict-reconfig-check"`
-	EnableV2            bool   `json:"enable-v2"`
-
-	// security
-
-	ClientTLSInfo transport.TLSInfo
-	ClientAutoTLS bool
-	PeerTLSInfo   transport.TLSInfo
-	PeerAutoTLS   bool
-
-	// CipherSuites is a list of supported TLS cipher suites between
-	// client/server and peers. If empty, Go auto-populates the list.
-	// Note that cipher suites are prioritized in the given order.
-	CipherSuites []string `json:"cipher-suites"`
-
-	// debug
-
-	Debug                 bool   `json:"debug"`
-	LogPkgLevels          string `json:"log-package-levels"`
-	LogOutput             string `json:"log-output"`
-	EnablePprof           bool   `json:"enable-pprof"`
-	Metrics               string `json:"metrics"`
-	ListenMetricsUrls     []url.URL
-	ListenMetricsUrlsJSON string `json:"listen-metrics-urls"`
-
-	// ForceNewCluster starts a new cluster even if previously started; unsafe.
-	ForceNewCluster bool `json:"force-new-cluster"`
-
-	// UserHandlers is for registering users handlers and only used for
-	// embedding etcd into other applications.
-	// The map key is the route path for the handler, and
-	// you must ensure it can't be conflicted with etcd's.
-	UserHandlers map[string]http.Handler `json:"-"`
-	// ServiceRegister is for registering users' gRPC services. A simple usage example:
-	//	cfg := embed.NewConfig()
-	//	cfg.ServerRegister = func(s *grpc.Server) {
-	//		pb.RegisterFooServer(s, &fooServer{})
-	//		pb.RegisterBarServer(s, &barServer{})
-	//	}
-	//	embed.StartEtcd(cfg)
-	ServiceRegister func(*grpc.Server) `json:"-"`
-
-	// auth
-
-	AuthToken string `json:"auth-token"`
-
-	// Experimental flags
-
-	ExperimentalInitialCorruptCheck bool          `json:"experimental-initial-corrupt-check"`
-	ExperimentalCorruptCheckTime    time.Duration `json:"experimental-corrupt-check-time"`
-	ExperimentalEnableV2V3          string        `json:"experimental-enable-v2v3"`
-}
-
-// configYAML holds the config suitable for yaml parsing
-type configYAML struct {
-	Config
-	configJSON
-}
-
-// configJSON has file options that are translated into Config options
-type configJSON struct {
-	LPUrlsJSON         string         `json:"listen-peer-urls"`
-	LCUrlsJSON         string         `json:"listen-client-urls"`
-	CorsJSON           string         `json:"cors"`
-	APUrlsJSON         string         `json:"initial-advertise-peer-urls"`
-	ACUrlsJSON         string         `json:"advertise-client-urls"`
-	ClientSecurityJSON securityConfig `json:"client-transport-security"`
-	PeerSecurityJSON   securityConfig `json:"peer-transport-security"`
-}
-
-type securityConfig struct {
-	CAFile        string `json:"ca-file"`
-	CertFile      string `json:"cert-file"`
-	KeyFile       string `json:"key-file"`
-	CertAuth      bool   `json:"client-cert-auth"`
-	TrustedCAFile string `json:"trusted-ca-file"`
-	AutoTLS       bool   `json:"auto-tls"`
-}
-
-// NewConfig creates a new Config populated with default values.
-func NewConfig() *Config {
-	lpurl, _ := url.Parse(DefaultListenPeerURLs)
-	apurl, _ := url.Parse(DefaultInitialAdvertisePeerURLs)
-	lcurl, _ := url.Parse(DefaultListenClientURLs)
-	acurl, _ := url.Parse(DefaultAdvertiseClientURLs)
-	cfg := &Config{
-		CorsInfo:                   &cors.CORSInfo{},
-		MaxSnapFiles:               DefaultMaxSnapshots,
-		MaxWalFiles:                DefaultMaxWALs,
-		Name:                       DefaultName,
-		SnapCount:                  etcdserver.DefaultSnapCount,
-		MaxTxnOps:                  DefaultMaxTxnOps,
-		MaxRequestBytes:            DefaultMaxRequestBytes,
-		GRPCKeepAliveMinTime:       DefaultGRPCKeepAliveMinTime,
-		GRPCKeepAliveInterval:      DefaultGRPCKeepAliveInterval,
-		GRPCKeepAliveTimeout:       DefaultGRPCKeepAliveTimeout,
-		TickMs:                     100,
-		ElectionMs:                 1000,
-		InitialElectionTickAdvance: true,
-		LPUrls:              []url.URL{*lpurl},
-		LCUrls:              []url.URL{*lcurl},
-		APUrls:              []url.URL{*apurl},
-		ACUrls:              []url.URL{*acurl},
-		ClusterState:        ClusterStateFlagNew,
-		InitialClusterToken: "etcd-cluster",
-		StrictReconfigCheck: DefaultStrictReconfigCheck,
-		LogOutput:           DefaultLogOutput,
-		Metrics:             "basic",
-		EnableV2:            DefaultEnableV2,
-		AuthToken:           "simple",
-	}
-	cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name)
-	return cfg
-}
-
-func logTLSHandshakeFailure(conn *tls.Conn, err error) {
-	state := conn.ConnectionState()
-	remoteAddr := conn.RemoteAddr().String()
-	serverName := state.ServerName
-	if len(state.PeerCertificates) > 0 {
-		cert := state.PeerCertificates[0]
-		ips, dns := cert.IPAddresses, cert.DNSNames
-		plog.Infof("rejected connection from %q (error %q, ServerName %q, IPAddresses %q, DNSNames %q)", remoteAddr, err.Error(), serverName, ips, dns)
-	} else {
-		plog.Infof("rejected connection from %q (error %q, ServerName %q)", remoteAddr, err.Error(), serverName)
-	}
-}
-
-// SetupLogging initializes etcd logging.
-// Must be called after flag parsing.
-func (cfg *Config) SetupLogging() {
-	cfg.ClientTLSInfo.HandshakeFailure = logTLSHandshakeFailure
-	cfg.PeerTLSInfo.HandshakeFailure = logTLSHandshakeFailure
-
-	capnslog.SetGlobalLogLevel(capnslog.INFO)
-	if cfg.Debug {
-		capnslog.SetGlobalLogLevel(capnslog.DEBUG)
-		grpc.EnableTracing = true
-		// enable info, warning, error
-		grpclog.SetLoggerV2(grpclog.NewLoggerV2(os.Stderr, os.Stderr, os.Stderr))
-	} else {
-		// only discard info
-		grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, os.Stderr, os.Stderr))
-	}
-	if cfg.LogPkgLevels != "" {
-		repoLog := capnslog.MustRepoLogger("github.com/coreos/etcd")
-		settings, err := repoLog.ParseLogLevelConfig(cfg.LogPkgLevels)
-		if err != nil {
-			plog.Warningf("couldn't parse log level string: %s, continuing with default levels", err.Error())
-			return
-		}
-		repoLog.SetLogLevel(settings)
-	}
-
-	// capnslog initially SetFormatter(NewDefaultFormatter(os.Stderr))
-	// where NewDefaultFormatter returns NewJournaldFormatter when syscall.Getppid() == 1
-	// specify 'stdout' or 'stderr' to skip journald logging even when running under systemd
-	switch cfg.LogOutput {
-	case "stdout":
-		capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stdout, cfg.Debug))
-	case "stderr":
-		capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stderr, cfg.Debug))
-	case DefaultLogOutput:
-	default:
-		plog.Panicf(`unknown log-output %q (only supports %q, "stdout", "stderr")`, cfg.LogOutput, DefaultLogOutput)
-	}
-}
-
-func ConfigFromFile(path string) (*Config, error) {
-	cfg := &configYAML{Config: *NewConfig()}
-	if err := cfg.configFromFile(path); err != nil {
-		return nil, err
-	}
-	return &cfg.Config, nil
-}
-
-func (cfg *configYAML) configFromFile(path string) error {
-	b, err := ioutil.ReadFile(path)
-	if err != nil {
-		return err
-	}
-
-	defaultInitialCluster := cfg.InitialCluster
-
-	err = yaml.Unmarshal(b, cfg)
-	if err != nil {
-		return err
-	}
-
-	if cfg.LPUrlsJSON != "" {
-		u, err := types.NewURLs(strings.Split(cfg.LPUrlsJSON, ","))
-		if err != nil {
-			plog.Fatalf("unexpected error setting up listen-peer-urls: %v", err)
-		}
-		cfg.LPUrls = []url.URL(u)
-	}
-
-	if cfg.LCUrlsJSON != "" {
-		u, err := types.NewURLs(strings.Split(cfg.LCUrlsJSON, ","))
-		if err != nil {
-			plog.Fatalf("unexpected error setting up listen-client-urls: %v", err)
-		}
-		cfg.LCUrls = []url.URL(u)
-	}
-
-	if cfg.CorsJSON != "" {
-		if err := cfg.CorsInfo.Set(cfg.CorsJSON); err != nil {
-			plog.Panicf("unexpected error setting up cors: %v", err)
-		}
-	}
-
-	if cfg.APUrlsJSON != "" {
-		u, err := types.NewURLs(strings.Split(cfg.APUrlsJSON, ","))
-		if err != nil {
-			plog.Fatalf("unexpected error setting up initial-advertise-peer-urls: %v", err)
-		}
-		cfg.APUrls = []url.URL(u)
-	}
-
-	if cfg.ACUrlsJSON != "" {
-		u, err := types.NewURLs(strings.Split(cfg.ACUrlsJSON, ","))
-		if err != nil {
-			plog.Fatalf("unexpected error setting up advertise-peer-urls: %v", err)
-		}
-		cfg.ACUrls = []url.URL(u)
-	}
-
-	if cfg.ListenMetricsUrlsJSON != "" {
-		u, err := types.NewURLs(strings.Split(cfg.ListenMetricsUrlsJSON, ","))
-		if err != nil {
-			plog.Fatalf("unexpected error setting up listen-metrics-urls: %v", err)
-		}
-		cfg.ListenMetricsUrls = []url.URL(u)
-	}
-
-	// If a discovery flag is set, clear default initial cluster set by InitialClusterFromName
-	if (cfg.Durl != "" || cfg.DNSCluster != "") && cfg.InitialCluster == defaultInitialCluster {
-		cfg.InitialCluster = ""
-	}
-	if cfg.ClusterState == "" {
-		cfg.ClusterState = ClusterStateFlagNew
-	}
-
-	copySecurityDetails := func(tls *transport.TLSInfo, ysc *securityConfig) {
-		tls.CAFile = ysc.CAFile
-		tls.CertFile = ysc.CertFile
-		tls.KeyFile = ysc.KeyFile
-		tls.ClientCertAuth = ysc.CertAuth
-		tls.TrustedCAFile = ysc.TrustedCAFile
-	}
-	copySecurityDetails(&cfg.ClientTLSInfo, &cfg.ClientSecurityJSON)
-	copySecurityDetails(&cfg.PeerTLSInfo, &cfg.PeerSecurityJSON)
-	cfg.ClientAutoTLS = cfg.ClientSecurityJSON.AutoTLS
-	cfg.PeerAutoTLS = cfg.PeerSecurityJSON.AutoTLS
-
-	return cfg.Validate()
-}
-
-func updateCipherSuites(tls *transport.TLSInfo, ss []string) error {
-	if len(tls.CipherSuites) > 0 && len(ss) > 0 {
-		return fmt.Errorf("TLSInfo.CipherSuites is already specified (given %v)", ss)
-	}
-	if len(ss) > 0 {
-		cs := make([]uint16, len(ss))
-		for i, s := range ss {
-			var ok bool
-			cs[i], ok = tlsutil.GetCipherSuite(s)
-			if !ok {
-				return fmt.Errorf("unexpected TLS cipher suite %q", s)
-			}
-		}
-		tls.CipherSuites = cs
-	}
-	return nil
-}
-
-// Validate ensures that '*embed.Config' fields are properly configured.
-func (cfg *Config) Validate() error {
-	if err := checkBindURLs(cfg.LPUrls); err != nil {
-		return err
-	}
-	if err := checkBindURLs(cfg.LCUrls); err != nil {
-		return err
-	}
-	if err := checkBindURLs(cfg.ListenMetricsUrls); err != nil {
-		return err
-	}
-	if err := checkHostURLs(cfg.APUrls); err != nil {
-		// TODO: return err in v3.4
-		addrs := make([]string, len(cfg.APUrls))
-		for i := range cfg.APUrls {
-			addrs[i] = cfg.APUrls[i].String()
-		}
-		plog.Warningf("advertise-peer-urls %q is deprecated (%v)", strings.Join(addrs, ","), err)
-	}
-	if err := checkHostURLs(cfg.ACUrls); err != nil {
-		// TODO: return err in v3.4
-		addrs := make([]string, len(cfg.ACUrls))
-		for i := range cfg.ACUrls {
-			addrs[i] = cfg.ACUrls[i].String()
-		}
-		plog.Warningf("advertise-client-urls %q is deprecated (%v)", strings.Join(addrs, ","), err)
-	}
-
-	// Check if conflicting flags are passed.
-	nSet := 0
-	for _, v := range []bool{cfg.Durl != "", cfg.InitialCluster != "", cfg.DNSCluster != ""} {
-		if v {
-			nSet++
-		}
-	}
-
-	if cfg.ClusterState != ClusterStateFlagNew && cfg.ClusterState != ClusterStateFlagExisting {
-		return fmt.Errorf("unexpected clusterState %q", cfg.ClusterState)
-	}
-
-	if nSet > 1 {
-		return ErrConflictBootstrapFlags
-	}
-
-	if cfg.TickMs <= 0 {
-		return fmt.Errorf("--heartbeat-interval must be >0 (set to %dms)", cfg.TickMs)
-	}
-	if cfg.ElectionMs <= 0 {
-		return fmt.Errorf("--election-timeout must be >0 (set to %dms)", cfg.ElectionMs)
-	}
-	if 5*cfg.TickMs > cfg.ElectionMs {
-		return fmt.Errorf("--election-timeout[%vms] should be at least as 5 times as --heartbeat-interval[%vms]", cfg.ElectionMs, cfg.TickMs)
-	}
-	if cfg.ElectionMs > maxElectionMs {
-		return fmt.Errorf("--election-timeout[%vms] is too long, and should be set less than %vms", cfg.ElectionMs, maxElectionMs)
-	}
-
-	// check this last since proxying in etcdmain may make this OK
-	if cfg.LCUrls != nil && cfg.ACUrls == nil {
-		return ErrUnsetAdvertiseClientURLsFlag
-	}
-
-	switch cfg.AutoCompactionMode {
-	case "":
-	case compactor.ModeRevision, compactor.ModePeriodic:
-	default:
-		return fmt.Errorf("unknown auto-compaction-mode %q", cfg.AutoCompactionMode)
-	}
-
-	return nil
-}
-
-// PeerURLsMapAndToken sets up an initial peer URLsMap and cluster token for bootstrap or discovery.
-func (cfg *Config) PeerURLsMapAndToken(which string) (urlsmap types.URLsMap, token string, err error) {
-	token = cfg.InitialClusterToken
-	switch {
-	case cfg.Durl != "":
-		urlsmap = types.URLsMap{}
-		// If using discovery, generate a temporary cluster based on
-		// self's advertised peer URLs
-		urlsmap[cfg.Name] = cfg.APUrls
-		token = cfg.Durl
-	case cfg.DNSCluster != "":
-		clusterStrs, cerr := srv.GetCluster("etcd-server", cfg.Name, cfg.DNSCluster, cfg.APUrls)
-		if cerr != nil {
-			plog.Errorf("couldn't resolve during SRV discovery (%v)", cerr)
-			return nil, "", cerr
-		}
-		for _, s := range clusterStrs {
-			plog.Noticef("got bootstrap from DNS for etcd-server at %s", s)
-		}
-		clusterStr := strings.Join(clusterStrs, ",")
-		if strings.Contains(clusterStr, "https://") && cfg.PeerTLSInfo.CAFile == "" {
-			cfg.PeerTLSInfo.ServerName = cfg.DNSCluster
-		}
-		urlsmap, err = types.NewURLsMap(clusterStr)
-		// only etcd member must belong to the discovered cluster.
-		// proxy does not need to belong to the discovered cluster.
-		if which == "etcd" {
-			if _, ok := urlsmap[cfg.Name]; !ok {
-				return nil, "", fmt.Errorf("cannot find local etcd member %q in SRV records", cfg.Name)
-			}
-		}
-	default:
-		// We're statically configured, and cluster has appropriately been set.
-		urlsmap, err = types.NewURLsMap(cfg.InitialCluster)
-	}
-	return urlsmap, token, err
-}
-
-func (cfg Config) InitialClusterFromName(name string) (ret string) {
-	if len(cfg.APUrls) == 0 {
-		return ""
-	}
-	n := name
-	if name == "" {
-		n = DefaultName
-	}
-	for i := range cfg.APUrls {
-		ret = ret + "," + n + "=" + cfg.APUrls[i].String()
-	}
-	return ret[1:]
-}
-
-func (cfg Config) IsNewCluster() bool { return cfg.ClusterState == ClusterStateFlagNew }
-func (cfg Config) ElectionTicks() int { return int(cfg.ElectionMs / cfg.TickMs) }
-
-func (cfg Config) defaultPeerHost() bool {
-	return len(cfg.APUrls) == 1 && cfg.APUrls[0].String() == DefaultInitialAdvertisePeerURLs
-}
-
-func (cfg Config) defaultClientHost() bool {
-	return len(cfg.ACUrls) == 1 && cfg.ACUrls[0].String() == DefaultAdvertiseClientURLs
-}
-
-func (cfg *Config) ClientSelfCert() (err error) {
-	if !cfg.ClientAutoTLS {
-		return nil
-	}
-	if !cfg.ClientTLSInfo.Empty() {
-		plog.Warningf("ignoring client auto TLS since certs given")
-		return nil
-	}
-	chosts := make([]string, len(cfg.LCUrls))
-	for i, u := range cfg.LCUrls {
-		chosts[i] = u.Host
-	}
-	cfg.ClientTLSInfo, err = transport.SelfCert(filepath.Join(cfg.Dir, "fixtures", "client"), chosts)
-	if err != nil {
-		return err
-	}
-	return updateCipherSuites(&cfg.ClientTLSInfo, cfg.CipherSuites)
-}
-
-func (cfg *Config) PeerSelfCert() (err error) {
-	if !cfg.PeerAutoTLS {
-		return nil
-	}
-	if !cfg.PeerTLSInfo.Empty() {
-		plog.Warningf("ignoring peer auto TLS since certs given")
-		return nil
-	}
-	phosts := make([]string, len(cfg.LPUrls))
-	for i, u := range cfg.LPUrls {
-		phosts[i] = u.Host
-	}
-	cfg.PeerTLSInfo, err = transport.SelfCert(filepath.Join(cfg.Dir, "fixtures", "peer"), phosts)
-	if err != nil {
-		return err
-	}
-	return updateCipherSuites(&cfg.PeerTLSInfo, cfg.CipherSuites)
-}
-
-// UpdateDefaultClusterFromName updates cluster advertise URLs with, if available, default host,
-// if advertise URLs are default values(localhost:2379,2380) AND if listen URL is 0.0.0.0.
-// e.g. advertise peer URL localhost:2380 or listen peer URL 0.0.0.0:2380
-// then the advertise peer host would be updated with machine's default host,
-// while keeping the listen URL's port.
-// User can work around this by explicitly setting URL with 127.0.0.1.
-// It returns the default hostname, if used, and the error, if any, from getting the machine's default host.
-// TODO: check whether fields are set instead of whether fields have default value
-func (cfg *Config) UpdateDefaultClusterFromName(defaultInitialCluster string) (string, error) {
-	if defaultHostname == "" || defaultHostStatus != nil {
-		// update 'initial-cluster' when only the name is specified (e.g. 'etcd --name=abc')
-		if cfg.Name != DefaultName && cfg.InitialCluster == defaultInitialCluster {
-			cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name)
-		}
-		return "", defaultHostStatus
-	}
-
-	used := false
-	pip, pport := cfg.LPUrls[0].Hostname(), cfg.LPUrls[0].Port()
-	if cfg.defaultPeerHost() && pip == "0.0.0.0" {
-		cfg.APUrls[0] = url.URL{Scheme: cfg.APUrls[0].Scheme, Host: fmt.Sprintf("%s:%s", defaultHostname, pport)}
-		used = true
-	}
-	// update 'initial-cluster' when only the name is specified (e.g. 'etcd --name=abc')
-	if cfg.Name != DefaultName && cfg.InitialCluster == defaultInitialCluster {
-		cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name)
-	}
-
-	cip, cport := cfg.LCUrls[0].Hostname(), cfg.LCUrls[0].Port()
-	if cfg.defaultClientHost() && cip == "0.0.0.0" {
-		cfg.ACUrls[0] = url.URL{Scheme: cfg.ACUrls[0].Scheme, Host: fmt.Sprintf("%s:%s", defaultHostname, cport)}
-		used = true
-	}
-	dhost := defaultHostname
-	if !used {
-		dhost = ""
-	}
-	return dhost, defaultHostStatus
-}
-
-// checkBindURLs returns an error if any URL uses a domain name.
-func checkBindURLs(urls []url.URL) error {
-	for _, url := range urls {
-		if url.Scheme == "unix" || url.Scheme == "unixs" {
-			continue
-		}
-		host, _, err := net.SplitHostPort(url.Host)
-		if err != nil {
-			return err
-		}
-		if host == "localhost" {
-			// special case for local address
-			// TODO: support /etc/hosts ?
-			continue
-		}
-		if net.ParseIP(host) == nil {
-			return fmt.Errorf("expected IP in URL for binding (%s)", url.String())
-		}
-	}
-	return nil
-}
-
-func checkHostURLs(urls []url.URL) error {
-	for _, url := range urls {
-		host, _, err := net.SplitHostPort(url.Host)
-		if err != nil {
-			return err
-		}
-		if host == "" {
-			return fmt.Errorf("unexpected empty host (%s)", url.String())
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/coreos/etcd/embed/doc.go b/vendor/github.com/coreos/etcd/embed/doc.go
deleted file mode 100644
index c555aa5..0000000
--- a/vendor/github.com/coreos/etcd/embed/doc.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/*
-Package embed provides bindings for embedding an etcd server in a program.
-
-Launch an embedded etcd server using the configuration defaults:
-
-	import (
-		"log"
-		"time"
-
-		"github.com/coreos/etcd/embed"
-	)
-
-	func main() {
-		cfg := embed.NewConfig()
-		cfg.Dir = "default.etcd"
-		e, err := embed.StartEtcd(cfg)
-		if err != nil {
-			log.Fatal(err)
-		}
-		defer e.Close()
-		select {
-		case <-e.Server.ReadyNotify():
-			log.Printf("Server is ready!")
-		case <-time.After(60 * time.Second):
-			e.Server.Stop() // trigger a shutdown
-			log.Printf("Server took too long to start!")
-		}
-		log.Fatal(<-e.Err())
-	}
-*/
-package embed
diff --git a/vendor/github.com/coreos/etcd/embed/etcd.go b/vendor/github.com/coreos/etcd/embed/etcd.go
deleted file mode 100644
index bd848a7..0000000
--- a/vendor/github.com/coreos/etcd/embed/etcd.go
+++ /dev/null
@@ -1,582 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package embed
-
-import (
-	"context"
-	"crypto/tls"
-	"fmt"
-	"io/ioutil"
-	defaultLog "log"
-	"net"
-	"net/http"
-	"net/url"
-	"strconv"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/compactor"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/etcdhttp"
-	"github.com/coreos/etcd/etcdserver/api/v2http"
-	"github.com/coreos/etcd/etcdserver/api/v2v3"
-	"github.com/coreos/etcd/etcdserver/api/v3client"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc"
-	"github.com/coreos/etcd/pkg/cors"
-	"github.com/coreos/etcd/pkg/debugutil"
-	runtimeutil "github.com/coreos/etcd/pkg/runtime"
-	"github.com/coreos/etcd/pkg/transport"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/rafthttp"
-
-	"github.com/coreos/pkg/capnslog"
-	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
-	"github.com/soheilhy/cmux"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/keepalive"
-)
-
-var plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "embed")
-
-const (
-	// internal fd usage includes disk usage and transport usage.
-	// To read/write snapshot, snap pkg needs 1. In normal case, wal pkg needs
-	// at most 2 to read/lock/write WALs. One case that it needs to 2 is to
-	// read all logs after some snapshot index, which locates at the end of
-	// the second last and the head of the last. For purging, it needs to read
-	// directory, so it needs 1. For fd monitor, it needs 1.
-	// For transport, rafthttp builds two long-polling connections and at most
-	// four temporary connections with each member. There are at most 9 members
-	// in a cluster, so it should reserve 96.
-	// For the safety, we set the total reserved number to 150.
-	reservedInternalFDNum = 150
-)
-
-// Etcd contains a running etcd server and its listeners.
-type Etcd struct {
-	Peers   []*peerListener
-	Clients []net.Listener
-	// a map of contexts for the servers that serves client requests.
-	sctxs            map[string]*serveCtx
-	metricsListeners []net.Listener
-
-	Server *etcdserver.EtcdServer
-
-	cfg   Config
-	stopc chan struct{}
-	errc  chan error
-
-	closeOnce sync.Once
-}
-
-type peerListener struct {
-	net.Listener
-	serve func() error
-	close func(context.Context) error
-}
-
-// StartEtcd launches the etcd server and HTTP handlers for client/server communication.
-// The returned Etcd.Server is not guaranteed to have joined the cluster. Wait
-// on the Etcd.Server.ReadyNotify() channel to know when it completes and is ready for use.
-func StartEtcd(inCfg *Config) (e *Etcd, err error) {
-	if err = inCfg.Validate(); err != nil {
-		return nil, err
-	}
-	serving := false
-	e = &Etcd{cfg: *inCfg, stopc: make(chan struct{})}
-	cfg := &e.cfg
-	defer func() {
-		if e == nil || err == nil {
-			return
-		}
-		if !serving {
-			// errored before starting gRPC server for serveCtx.serversC
-			for _, sctx := range e.sctxs {
-				close(sctx.serversC)
-			}
-		}
-		e.Close()
-		e = nil
-	}()
-
-	if e.Peers, err = startPeerListeners(cfg); err != nil {
-		return e, err
-	}
-	if e.sctxs, err = startClientListeners(cfg); err != nil {
-		return e, err
-	}
-	for _, sctx := range e.sctxs {
-		e.Clients = append(e.Clients, sctx.l)
-	}
-
-	var (
-		urlsmap types.URLsMap
-		token   string
-	)
-
-	memberInitialized := true
-	if !isMemberInitialized(cfg) {
-		memberInitialized = false
-		urlsmap, token, err = cfg.PeerURLsMapAndToken("etcd")
-		if err != nil {
-			return e, fmt.Errorf("error setting up initial cluster: %v", err)
-		}
-	}
-
-	// AutoCompactionRetention defaults to "0" if not set.
-	if len(cfg.AutoCompactionRetention) == 0 {
-		cfg.AutoCompactionRetention = "0"
-	}
-	autoCompactionRetention, err := parseCompactionRetention(cfg.AutoCompactionMode, cfg.AutoCompactionRetention)
-	if err != nil {
-		return e, err
-	}
-
-	srvcfg := etcdserver.ServerConfig{
-		Name:                       cfg.Name,
-		ClientURLs:                 cfg.ACUrls,
-		PeerURLs:                   cfg.APUrls,
-		DataDir:                    cfg.Dir,
-		DedicatedWALDir:            cfg.WalDir,
-		SnapCount:                  cfg.SnapCount,
-		MaxSnapFiles:               cfg.MaxSnapFiles,
-		MaxWALFiles:                cfg.MaxWalFiles,
-		InitialPeerURLsMap:         urlsmap,
-		InitialClusterToken:        token,
-		DiscoveryURL:               cfg.Durl,
-		DiscoveryProxy:             cfg.Dproxy,
-		NewCluster:                 cfg.IsNewCluster(),
-		ForceNewCluster:            cfg.ForceNewCluster,
-		PeerTLSInfo:                cfg.PeerTLSInfo,
-		TickMs:                     cfg.TickMs,
-		ElectionTicks:              cfg.ElectionTicks(),
-		InitialElectionTickAdvance: cfg.InitialElectionTickAdvance,
-		AutoCompactionRetention:    autoCompactionRetention,
-		AutoCompactionMode:         cfg.AutoCompactionMode,
-		QuotaBackendBytes:          cfg.QuotaBackendBytes,
-		MaxTxnOps:                  cfg.MaxTxnOps,
-		MaxRequestBytes:            cfg.MaxRequestBytes,
-		StrictReconfigCheck:        cfg.StrictReconfigCheck,
-		ClientCertAuthEnabled:      cfg.ClientTLSInfo.ClientCertAuth,
-		AuthToken:                  cfg.AuthToken,
-		InitialCorruptCheck:        cfg.ExperimentalInitialCorruptCheck,
-		CorruptCheckTime:           cfg.ExperimentalCorruptCheckTime,
-		Debug:                      cfg.Debug,
-	}
-
-	if e.Server, err = etcdserver.NewServer(srvcfg); err != nil {
-		return e, err
-	}
-
-	// buffer channel so goroutines on closed connections won't wait forever
-	e.errc = make(chan error, len(e.Peers)+len(e.Clients)+2*len(e.sctxs))
-
-	// newly started member ("memberInitialized==false")
-	// does not need corruption check
-	if memberInitialized {
-		if err = e.Server.CheckInitialHashKV(); err != nil {
-			// set "EtcdServer" to nil, so that it does not block on "EtcdServer.Close()"
-			// (nothing to close since rafthttp transports have not been started)
-			e.Server = nil
-			return e, err
-		}
-	}
-	e.Server.Start()
-
-	if err = e.servePeers(); err != nil {
-		return e, err
-	}
-	if err = e.serveClients(); err != nil {
-		return e, err
-	}
-	if err = e.serveMetrics(); err != nil {
-		return e, err
-	}
-
-	serving = true
-	return e, nil
-}
-
-// Config returns the current configuration.
-func (e *Etcd) Config() Config {
-	return e.cfg
-}
-
-// Close gracefully shuts down all servers/listeners.
-// Client requests will be terminated with request timeout.
-// After timeout, enforce remaning requests be closed immediately.
-func (e *Etcd) Close() {
-	e.closeOnce.Do(func() { close(e.stopc) })
-
-	// close client requests with request timeout
-	timeout := 2 * time.Second
-	if e.Server != nil {
-		timeout = e.Server.Cfg.ReqTimeout()
-	}
-	for _, sctx := range e.sctxs {
-		for ss := range sctx.serversC {
-			ctx, cancel := context.WithTimeout(context.Background(), timeout)
-			stopServers(ctx, ss)
-			cancel()
-		}
-	}
-
-	for _, sctx := range e.sctxs {
-		sctx.cancel()
-	}
-
-	for i := range e.Clients {
-		if e.Clients[i] != nil {
-			e.Clients[i].Close()
-		}
-	}
-
-	for i := range e.metricsListeners {
-		e.metricsListeners[i].Close()
-	}
-
-	// close rafthttp transports
-	if e.Server != nil {
-		e.Server.Stop()
-	}
-
-	// close all idle connections in peer handler (wait up to 1-second)
-	for i := range e.Peers {
-		if e.Peers[i] != nil && e.Peers[i].close != nil {
-			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
-			e.Peers[i].close(ctx)
-			cancel()
-		}
-	}
-}
-
-func stopServers(ctx context.Context, ss *servers) {
-	shutdownNow := func() {
-		// first, close the http.Server
-		ss.http.Shutdown(ctx)
-		// then close grpc.Server; cancels all active RPCs
-		ss.grpc.Stop()
-	}
-
-	// do not grpc.Server.GracefulStop with TLS enabled etcd server
-	// See https://github.com/grpc/grpc-go/issues/1384#issuecomment-317124531
-	// and https://github.com/coreos/etcd/issues/8916
-	if ss.secure {
-		shutdownNow()
-		return
-	}
-
-	ch := make(chan struct{})
-	go func() {
-		defer close(ch)
-		// close listeners to stop accepting new connections,
-		// will block on any existing transports
-		ss.grpc.GracefulStop()
-	}()
-
-	// wait until all pending RPCs are finished
-	select {
-	case <-ch:
-	case <-ctx.Done():
-		// took too long, manually close open transports
-		// e.g. watch streams
-		shutdownNow()
-
-		// concurrent GracefulStop should be interrupted
-		<-ch
-	}
-}
-
-func (e *Etcd) Err() <-chan error { return e.errc }
-
-func startPeerListeners(cfg *Config) (peers []*peerListener, err error) {
-	if err = updateCipherSuites(&cfg.PeerTLSInfo, cfg.CipherSuites); err != nil {
-		return nil, err
-	}
-	if err = cfg.PeerSelfCert(); err != nil {
-		plog.Fatalf("could not get certs (%v)", err)
-	}
-	if !cfg.PeerTLSInfo.Empty() {
-		plog.Infof("peerTLS: %s", cfg.PeerTLSInfo)
-	}
-
-	peers = make([]*peerListener, len(cfg.LPUrls))
-	defer func() {
-		if err == nil {
-			return
-		}
-		for i := range peers {
-			if peers[i] != nil && peers[i].close != nil {
-				plog.Info("stopping listening for peers on ", cfg.LPUrls[i].String())
-				ctx, cancel := context.WithTimeout(context.Background(), time.Second)
-				peers[i].close(ctx)
-				cancel()
-			}
-		}
-	}()
-
-	for i, u := range cfg.LPUrls {
-		if u.Scheme == "http" {
-			if !cfg.PeerTLSInfo.Empty() {
-				plog.Warningf("The scheme of peer url %s is HTTP while peer key/cert files are presented. Ignored peer key/cert files.", u.String())
-			}
-			if cfg.PeerTLSInfo.ClientCertAuth {
-				plog.Warningf("The scheme of peer url %s is HTTP while client cert auth (--peer-client-cert-auth) is enabled. Ignored client cert auth for this url.", u.String())
-			}
-		}
-		peers[i] = &peerListener{close: func(context.Context) error { return nil }}
-		peers[i].Listener, err = rafthttp.NewListener(u, &cfg.PeerTLSInfo)
-		if err != nil {
-			return nil, err
-		}
-		// once serve, overwrite with 'http.Server.Shutdown'
-		peers[i].close = func(context.Context) error {
-			return peers[i].Listener.Close()
-		}
-		plog.Info("listening for peers on ", u.String())
-	}
-	return peers, nil
-}
-
-// configure peer handlers after rafthttp.Transport started
-func (e *Etcd) servePeers() (err error) {
-	ph := etcdhttp.NewPeerHandler(e.Server)
-	var peerTLScfg *tls.Config
-	if !e.cfg.PeerTLSInfo.Empty() {
-		if peerTLScfg, err = e.cfg.PeerTLSInfo.ServerConfig(); err != nil {
-			return err
-		}
-	}
-
-	for _, p := range e.Peers {
-		gs := v3rpc.Server(e.Server, peerTLScfg)
-		m := cmux.New(p.Listener)
-		go gs.Serve(m.Match(cmux.HTTP2()))
-		srv := &http.Server{
-			Handler:     grpcHandlerFunc(gs, ph),
-			ReadTimeout: 5 * time.Minute,
-			ErrorLog:    defaultLog.New(ioutil.Discard, "", 0), // do not log user error
-		}
-		go srv.Serve(m.Match(cmux.Any()))
-		p.serve = func() error { return m.Serve() }
-		p.close = func(ctx context.Context) error {
-			// gracefully shutdown http.Server
-			// close open listeners, idle connections
-			// until context cancel or time-out
-			stopServers(ctx, &servers{secure: peerTLScfg != nil, grpc: gs, http: srv})
-			return nil
-		}
-	}
-
-	// start peer servers in a goroutine
-	for _, pl := range e.Peers {
-		go func(l *peerListener) {
-			e.errHandler(l.serve())
-		}(pl)
-	}
-	return nil
-}
-
-func startClientListeners(cfg *Config) (sctxs map[string]*serveCtx, err error) {
-	if err = updateCipherSuites(&cfg.ClientTLSInfo, cfg.CipherSuites); err != nil {
-		return nil, err
-	}
-	if err = cfg.ClientSelfCert(); err != nil {
-		plog.Fatalf("could not get certs (%v)", err)
-	}
-	if cfg.EnablePprof {
-		plog.Infof("pprof is enabled under %s", debugutil.HTTPPrefixPProf)
-	}
-
-	sctxs = make(map[string]*serveCtx)
-	for _, u := range cfg.LCUrls {
-		sctx := newServeCtx()
-
-		if u.Scheme == "http" || u.Scheme == "unix" {
-			if !cfg.ClientTLSInfo.Empty() {
-				plog.Warningf("The scheme of client url %s is HTTP while peer key/cert files are presented. Ignored key/cert files.", u.String())
-			}
-			if cfg.ClientTLSInfo.ClientCertAuth {
-				plog.Warningf("The scheme of client url %s is HTTP while client cert auth (--client-cert-auth) is enabled. Ignored client cert auth for this url.", u.String())
-			}
-		}
-		if (u.Scheme == "https" || u.Scheme == "unixs") && cfg.ClientTLSInfo.Empty() {
-			return nil, fmt.Errorf("TLS key/cert (--cert-file, --key-file) must be provided for client url %s with HTTPs scheme", u.String())
-		}
-
-		proto := "tcp"
-		addr := u.Host
-		if u.Scheme == "unix" || u.Scheme == "unixs" {
-			proto = "unix"
-			addr = u.Host + u.Path
-		}
-
-		sctx.secure = u.Scheme == "https" || u.Scheme == "unixs"
-		sctx.insecure = !sctx.secure
-		if oldctx := sctxs[addr]; oldctx != nil {
-			oldctx.secure = oldctx.secure || sctx.secure
-			oldctx.insecure = oldctx.insecure || sctx.insecure
-			continue
-		}
-
-		if sctx.l, err = net.Listen(proto, addr); err != nil {
-			return nil, err
-		}
-		// net.Listener will rewrite ipv4 0.0.0.0 to ipv6 [::], breaking
-		// hosts that disable ipv6. So, use the address given by the user.
-		sctx.addr = addr
-
-		if fdLimit, fderr := runtimeutil.FDLimit(); fderr == nil {
-			if fdLimit <= reservedInternalFDNum {
-				plog.Fatalf("file descriptor limit[%d] of etcd process is too low, and should be set higher than %d to ensure internal usage", fdLimit, reservedInternalFDNum)
-			}
-			sctx.l = transport.LimitListener(sctx.l, int(fdLimit-reservedInternalFDNum))
-		}
-
-		if proto == "tcp" {
-			if sctx.l, err = transport.NewKeepAliveListener(sctx.l, "tcp", nil); err != nil {
-				return nil, err
-			}
-		}
-
-		plog.Info("listening for client requests on ", u.Host)
-		defer func() {
-			if err != nil {
-				sctx.l.Close()
-				plog.Info("stopping listening for client requests on ", u.Host)
-			}
-		}()
-		for k := range cfg.UserHandlers {
-			sctx.userHandlers[k] = cfg.UserHandlers[k]
-		}
-		sctx.serviceRegister = cfg.ServiceRegister
-		if cfg.EnablePprof || cfg.Debug {
-			sctx.registerPprof()
-		}
-		if cfg.Debug {
-			sctx.registerTrace()
-		}
-		sctxs[addr] = sctx
-	}
-	return sctxs, nil
-}
-
-func (e *Etcd) serveClients() (err error) {
-	if !e.cfg.ClientTLSInfo.Empty() {
-		plog.Infof("ClientTLS: %s", e.cfg.ClientTLSInfo)
-	}
-
-	if e.cfg.CorsInfo.String() != "" {
-		plog.Infof("cors = %s", e.cfg.CorsInfo)
-	}
-
-	// Start a client server goroutine for each listen address
-	var h http.Handler
-	if e.Config().EnableV2 {
-		if len(e.Config().ExperimentalEnableV2V3) > 0 {
-			srv := v2v3.NewServer(v3client.New(e.Server), e.cfg.ExperimentalEnableV2V3)
-			h = v2http.NewClientHandler(srv, e.Server.Cfg.ReqTimeout())
-		} else {
-			h = v2http.NewClientHandler(e.Server, e.Server.Cfg.ReqTimeout())
-		}
-	} else {
-		mux := http.NewServeMux()
-		etcdhttp.HandleBasic(mux, e.Server)
-		h = mux
-	}
-	h = http.Handler(&cors.CORSHandler{Handler: h, Info: e.cfg.CorsInfo})
-
-	gopts := []grpc.ServerOption{}
-	if e.cfg.GRPCKeepAliveMinTime > time.Duration(0) {
-		gopts = append(gopts, grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{
-			MinTime:             e.cfg.GRPCKeepAliveMinTime,
-			PermitWithoutStream: false,
-		}))
-	}
-	if e.cfg.GRPCKeepAliveInterval > time.Duration(0) &&
-		e.cfg.GRPCKeepAliveTimeout > time.Duration(0) {
-		gopts = append(gopts, grpc.KeepaliveParams(keepalive.ServerParameters{
-			Time:    e.cfg.GRPCKeepAliveInterval,
-			Timeout: e.cfg.GRPCKeepAliveTimeout,
-		}))
-	}
-
-	// start client servers in a goroutine
-	for _, sctx := range e.sctxs {
-		go func(s *serveCtx) {
-			e.errHandler(s.serve(e.Server, &e.cfg.ClientTLSInfo, h, e.errHandler, gopts...))
-		}(sctx)
-	}
-	return nil
-}
-
-func (e *Etcd) serveMetrics() (err error) {
-	if e.cfg.Metrics == "extensive" {
-		grpc_prometheus.EnableHandlingTimeHistogram()
-	}
-
-	if len(e.cfg.ListenMetricsUrls) > 0 {
-		metricsMux := http.NewServeMux()
-		etcdhttp.HandleMetricsHealth(metricsMux, e.Server)
-
-		for _, murl := range e.cfg.ListenMetricsUrls {
-			tlsInfo := &e.cfg.ClientTLSInfo
-			if murl.Scheme == "http" {
-				tlsInfo = nil
-			}
-			ml, err := transport.NewListener(murl.Host, murl.Scheme, tlsInfo)
-			if err != nil {
-				return err
-			}
-			e.metricsListeners = append(e.metricsListeners, ml)
-			go func(u url.URL, ln net.Listener) {
-				plog.Info("listening for metrics on ", u.String())
-				e.errHandler(http.Serve(ln, metricsMux))
-			}(murl, ml)
-		}
-	}
-	return nil
-}
-
-func (e *Etcd) errHandler(err error) {
-	select {
-	case <-e.stopc:
-		return
-	default:
-	}
-	select {
-	case <-e.stopc:
-	case e.errc <- err:
-	}
-}
-
-func parseCompactionRetention(mode, retention string) (ret time.Duration, err error) {
-	h, err := strconv.Atoi(retention)
-	if err == nil {
-		switch mode {
-		case compactor.ModeRevision:
-			ret = time.Duration(int64(h))
-		case compactor.ModePeriodic:
-			ret = time.Duration(int64(h)) * time.Hour
-		}
-	} else {
-		// periodic compaction
-		ret, err = time.ParseDuration(retention)
-		if err != nil {
-			return 0, fmt.Errorf("error parsing CompactionRetention: %v", err)
-		}
-	}
-	return ret, nil
-}
diff --git a/vendor/github.com/coreos/etcd/embed/serve.go b/vendor/github.com/coreos/etcd/embed/serve.go
deleted file mode 100644
index 62b8b57..0000000
--- a/vendor/github.com/coreos/etcd/embed/serve.go
+++ /dev/null
@@ -1,285 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package embed
-
-import (
-	"context"
-	"io/ioutil"
-	defaultLog "log"
-	"net"
-	"net/http"
-	"strings"
-
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/v3client"
-	"github.com/coreos/etcd/etcdserver/api/v3election"
-	"github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb"
-	v3electiongw "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/gw"
-	"github.com/coreos/etcd/etcdserver/api/v3lock"
-	"github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb"
-	v3lockgw "github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/gw"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc"
-	etcdservergw "github.com/coreos/etcd/etcdserver/etcdserverpb/gw"
-	"github.com/coreos/etcd/pkg/debugutil"
-	"github.com/coreos/etcd/pkg/transport"
-
-	gw "github.com/grpc-ecosystem/grpc-gateway/runtime"
-	"github.com/soheilhy/cmux"
-	"github.com/tmc/grpc-websocket-proxy/wsproxy"
-	"golang.org/x/net/trace"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/credentials"
-)
-
-type serveCtx struct {
-	l        net.Listener
-	addr     string
-	secure   bool
-	insecure bool
-
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	userHandlers    map[string]http.Handler
-	serviceRegister func(*grpc.Server)
-	serversC        chan *servers
-}
-
-type servers struct {
-	secure bool
-	grpc   *grpc.Server
-	http   *http.Server
-}
-
-func newServeCtx() *serveCtx {
-	ctx, cancel := context.WithCancel(context.Background())
-	return &serveCtx{ctx: ctx, cancel: cancel, userHandlers: make(map[string]http.Handler),
-		serversC: make(chan *servers, 2), // in case sctx.insecure,sctx.secure true
-	}
-}
-
-// serve accepts incoming connections on the listener l,
-// creating a new service goroutine for each. The service goroutines
-// read requests and then call handler to reply to them.
-func (sctx *serveCtx) serve(
-	s *etcdserver.EtcdServer,
-	tlsinfo *transport.TLSInfo,
-	handler http.Handler,
-	errHandler func(error),
-	gopts ...grpc.ServerOption) (err error) {
-	logger := defaultLog.New(ioutil.Discard, "etcdhttp", 0)
-	<-s.ReadyNotify()
-	plog.Info("ready to serve client requests")
-
-	m := cmux.New(sctx.l)
-	v3c := v3client.New(s)
-	servElection := v3election.NewElectionServer(v3c)
-	servLock := v3lock.NewLockServer(v3c)
-
-	var gs *grpc.Server
-	defer func() {
-		if err != nil && gs != nil {
-			gs.Stop()
-		}
-	}()
-
-	if sctx.insecure {
-		gs = v3rpc.Server(s, nil, gopts...)
-		v3electionpb.RegisterElectionServer(gs, servElection)
-		v3lockpb.RegisterLockServer(gs, servLock)
-		if sctx.serviceRegister != nil {
-			sctx.serviceRegister(gs)
-		}
-		grpcl := m.Match(cmux.HTTP2())
-		go func() { errHandler(gs.Serve(grpcl)) }()
-
-		var gwmux *gw.ServeMux
-		gwmux, err = sctx.registerGateway([]grpc.DialOption{grpc.WithInsecure()})
-		if err != nil {
-			return err
-		}
-
-		httpmux := sctx.createMux(gwmux, handler)
-
-		srvhttp := &http.Server{
-			Handler:  wrapMux(httpmux),
-			ErrorLog: logger, // do not log user error
-		}
-		httpl := m.Match(cmux.HTTP1())
-		go func() { errHandler(srvhttp.Serve(httpl)) }()
-
-		sctx.serversC <- &servers{grpc: gs, http: srvhttp}
-		plog.Noticef("serving insecure client requests on %s, this is strongly discouraged!", sctx.l.Addr().String())
-	}
-
-	if sctx.secure {
-		tlscfg, tlsErr := tlsinfo.ServerConfig()
-		if tlsErr != nil {
-			return tlsErr
-		}
-		gs = v3rpc.Server(s, tlscfg, gopts...)
-		v3electionpb.RegisterElectionServer(gs, servElection)
-		v3lockpb.RegisterLockServer(gs, servLock)
-		if sctx.serviceRegister != nil {
-			sctx.serviceRegister(gs)
-		}
-		handler = grpcHandlerFunc(gs, handler)
-
-		dtls := tlscfg.Clone()
-		// trust local server
-		dtls.InsecureSkipVerify = true
-		creds := credentials.NewTLS(dtls)
-		opts := []grpc.DialOption{grpc.WithTransportCredentials(creds)}
-		var gwmux *gw.ServeMux
-		gwmux, err = sctx.registerGateway(opts)
-		if err != nil {
-			return err
-		}
-
-		var tlsl net.Listener
-		tlsl, err = transport.NewTLSListener(m.Match(cmux.Any()), tlsinfo)
-		if err != nil {
-			return err
-		}
-		// TODO: add debug flag; enable logging when debug flag is set
-		httpmux := sctx.createMux(gwmux, handler)
-
-		srv := &http.Server{
-			Handler:   wrapMux(httpmux),
-			TLSConfig: tlscfg,
-			ErrorLog:  logger, // do not log user error
-		}
-		go func() { errHandler(srv.Serve(tlsl)) }()
-
-		sctx.serversC <- &servers{secure: true, grpc: gs, http: srv}
-		plog.Infof("serving client requests on %s", sctx.l.Addr().String())
-	}
-
-	close(sctx.serversC)
-	return m.Serve()
-}
-
-// grpcHandlerFunc returns an http.Handler that delegates to grpcServer on incoming gRPC
-// connections or otherHandler otherwise. Given in gRPC docs.
-func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
-	if otherHandler == nil {
-		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			grpcServer.ServeHTTP(w, r)
-		})
-	}
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
-			grpcServer.ServeHTTP(w, r)
-		} else {
-			otherHandler.ServeHTTP(w, r)
-		}
-	})
-}
-
-type registerHandlerFunc func(context.Context, *gw.ServeMux, *grpc.ClientConn) error
-
-func (sctx *serveCtx) registerGateway(opts []grpc.DialOption) (*gw.ServeMux, error) {
-	ctx := sctx.ctx
-	conn, err := grpc.DialContext(ctx, sctx.addr, opts...)
-	if err != nil {
-		return nil, err
-	}
-	gwmux := gw.NewServeMux()
-
-	handlers := []registerHandlerFunc{
-		etcdservergw.RegisterKVHandler,
-		etcdservergw.RegisterWatchHandler,
-		etcdservergw.RegisterLeaseHandler,
-		etcdservergw.RegisterClusterHandler,
-		etcdservergw.RegisterMaintenanceHandler,
-		etcdservergw.RegisterAuthHandler,
-		v3lockgw.RegisterLockHandler,
-		v3electiongw.RegisterElectionHandler,
-	}
-	for _, h := range handlers {
-		if err := h(ctx, gwmux, conn); err != nil {
-			return nil, err
-		}
-	}
-	go func() {
-		<-ctx.Done()
-		if cerr := conn.Close(); cerr != nil {
-			plog.Warningf("failed to close conn to %s: %v", sctx.l.Addr().String(), cerr)
-		}
-	}()
-
-	return gwmux, nil
-}
-
-func (sctx *serveCtx) createMux(gwmux *gw.ServeMux, handler http.Handler) *http.ServeMux {
-	httpmux := http.NewServeMux()
-	for path, h := range sctx.userHandlers {
-		httpmux.Handle(path, h)
-	}
-
-	httpmux.Handle(
-		"/v3beta/",
-		wsproxy.WebsocketProxy(
-			gwmux,
-			wsproxy.WithRequestMutator(
-				// Default to the POST method for streams
-				func(incoming *http.Request, outgoing *http.Request) *http.Request {
-					outgoing.Method = "POST"
-					return outgoing
-				},
-			),
-		),
-	)
-	if handler != nil {
-		httpmux.Handle("/", handler)
-	}
-	return httpmux
-}
-
-// wraps HTTP multiplexer to mute requests to /v3alpha
-// TODO: deprecate this in 3.4 release
-func wrapMux(mux *http.ServeMux) http.Handler { return &v3alphaMutator{mux: mux} }
-
-type v3alphaMutator struct {
-	mux *http.ServeMux
-}
-
-func (m *v3alphaMutator) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-	if req != nil && req.URL != nil && strings.HasPrefix(req.URL.Path, "/v3alpha/") {
-		req.URL.Path = strings.Replace(req.URL.Path, "/v3alpha/", "/v3beta/", 1)
-	}
-	m.mux.ServeHTTP(rw, req)
-}
-
-func (sctx *serveCtx) registerUserHandler(s string, h http.Handler) {
-	if sctx.userHandlers[s] != nil {
-		plog.Warningf("path %s already registered by user handler", s)
-		return
-	}
-	sctx.userHandlers[s] = h
-}
-
-func (sctx *serveCtx) registerPprof() {
-	for p, h := range debugutil.PProfHandlers() {
-		sctx.registerUserHandler(p, h)
-	}
-}
-
-func (sctx *serveCtx) registerTrace() {
-	reqf := func(w http.ResponseWriter, r *http.Request) { trace.Render(w, r, true) }
-	sctx.registerUserHandler("/debug/requests", http.HandlerFunc(reqf))
-	evf := func(w http.ResponseWriter, r *http.Request) { trace.RenderEvents(w, r, true) }
-	sctx.registerUserHandler("/debug/events", http.HandlerFunc(evf))
-}
diff --git a/vendor/github.com/coreos/etcd/embed/util.go b/vendor/github.com/coreos/etcd/embed/util.go
deleted file mode 100644
index 168e031..0000000
--- a/vendor/github.com/coreos/etcd/embed/util.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package embed
-
-import (
-	"path/filepath"
-
-	"github.com/coreos/etcd/wal"
-)
-
-func isMemberInitialized(cfg *Config) bool {
-	waldir := cfg.WalDir
-	if waldir == "" {
-		waldir = filepath.Join(cfg.Dir, "member", "wal")
-	}
-
-	return wal.Exist(waldir)
-}
diff --git a/vendor/github.com/coreos/etcd/error/error.go b/vendor/github.com/coreos/etcd/error/error.go
deleted file mode 100644
index b541a62..0000000
--- a/vendor/github.com/coreos/etcd/error/error.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package error describes errors in etcd project. When any change happens,
-// Documentation/v2/errorcode.md needs to be updated correspondingly.
-package error
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/http"
-)
-
-var errors = map[int]string{
-	// command related errors
-	EcodeKeyNotFound:      "Key not found",
-	EcodeTestFailed:       "Compare failed", //test and set
-	EcodeNotFile:          "Not a file",
-	ecodeNoMorePeer:       "Reached the max number of peers in the cluster",
-	EcodeNotDir:           "Not a directory",
-	EcodeNodeExist:        "Key already exists", // create
-	ecodeKeyIsPreserved:   "The prefix of given key is a keyword in etcd",
-	EcodeRootROnly:        "Root is read only",
-	EcodeDirNotEmpty:      "Directory not empty",
-	ecodeExistingPeerAddr: "Peer address has existed",
-	EcodeUnauthorized:     "The request requires user authentication",
-
-	// Post form related errors
-	ecodeValueRequired:        "Value is Required in POST form",
-	EcodePrevValueRequired:    "PrevValue is Required in POST form",
-	EcodeTTLNaN:               "The given TTL in POST form is not a number",
-	EcodeIndexNaN:             "The given index in POST form is not a number",
-	ecodeValueOrTTLRequired:   "Value or TTL is required in POST form",
-	ecodeTimeoutNaN:           "The given timeout in POST form is not a number",
-	ecodeNameRequired:         "Name is required in POST form",
-	ecodeIndexOrValueRequired: "Index or value is required",
-	ecodeIndexValueMutex:      "Index and value cannot both be specified",
-	EcodeInvalidField:         "Invalid field",
-	EcodeInvalidForm:          "Invalid POST form",
-	EcodeRefreshValue:         "Value provided on refresh",
-	EcodeRefreshTTLRequired:   "A TTL must be provided on refresh",
-
-	// raft related errors
-	EcodeRaftInternal: "Raft Internal Error",
-	EcodeLeaderElect:  "During Leader Election",
-
-	// etcd related errors
-	EcodeWatcherCleared:     "watcher is cleared due to etcd recovery",
-	EcodeEventIndexCleared:  "The event in requested index is outdated and cleared",
-	ecodeStandbyInternal:    "Standby Internal Error",
-	ecodeInvalidActiveSize:  "Invalid active size",
-	ecodeInvalidRemoveDelay: "Standby remove delay",
-
-	// client related errors
-	ecodeClientInternal: "Client Internal Error",
-}
-
-var errorStatus = map[int]int{
-	EcodeKeyNotFound:  http.StatusNotFound,
-	EcodeNotFile:      http.StatusForbidden,
-	EcodeDirNotEmpty:  http.StatusForbidden,
-	EcodeUnauthorized: http.StatusUnauthorized,
-	EcodeTestFailed:   http.StatusPreconditionFailed,
-	EcodeNodeExist:    http.StatusPreconditionFailed,
-	EcodeRaftInternal: http.StatusInternalServerError,
-	EcodeLeaderElect:  http.StatusInternalServerError,
-}
-
-const (
-	EcodeKeyNotFound      = 100
-	EcodeTestFailed       = 101
-	EcodeNotFile          = 102
-	ecodeNoMorePeer       = 103
-	EcodeNotDir           = 104
-	EcodeNodeExist        = 105
-	ecodeKeyIsPreserved   = 106
-	EcodeRootROnly        = 107
-	EcodeDirNotEmpty      = 108
-	ecodeExistingPeerAddr = 109
-	EcodeUnauthorized     = 110
-
-	ecodeValueRequired        = 200
-	EcodePrevValueRequired    = 201
-	EcodeTTLNaN               = 202
-	EcodeIndexNaN             = 203
-	ecodeValueOrTTLRequired   = 204
-	ecodeTimeoutNaN           = 205
-	ecodeNameRequired         = 206
-	ecodeIndexOrValueRequired = 207
-	ecodeIndexValueMutex      = 208
-	EcodeInvalidField         = 209
-	EcodeInvalidForm          = 210
-	EcodeRefreshValue         = 211
-	EcodeRefreshTTLRequired   = 212
-
-	EcodeRaftInternal = 300
-	EcodeLeaderElect  = 301
-
-	EcodeWatcherCleared     = 400
-	EcodeEventIndexCleared  = 401
-	ecodeStandbyInternal    = 402
-	ecodeInvalidActiveSize  = 403
-	ecodeInvalidRemoveDelay = 404
-
-	ecodeClientInternal = 500
-)
-
-type Error struct {
-	ErrorCode int    `json:"errorCode"`
-	Message   string `json:"message"`
-	Cause     string `json:"cause,omitempty"`
-	Index     uint64 `json:"index"`
-}
-
-func NewRequestError(errorCode int, cause string) *Error {
-	return NewError(errorCode, cause, 0)
-}
-
-func NewError(errorCode int, cause string, index uint64) *Error {
-	return &Error{
-		ErrorCode: errorCode,
-		Message:   errors[errorCode],
-		Cause:     cause,
-		Index:     index,
-	}
-}
-
-// Error is for the error interface
-func (e Error) Error() string {
-	return e.Message + " (" + e.Cause + ")"
-}
-
-func (e Error) toJsonString() string {
-	b, _ := json.Marshal(e)
-	return string(b)
-}
-
-func (e Error) StatusCode() int {
-	status, ok := errorStatus[e.ErrorCode]
-	if !ok {
-		status = http.StatusBadRequest
-	}
-	return status
-}
-
-func (e Error) WriteTo(w http.ResponseWriter) error {
-	w.Header().Add("X-Etcd-Index", fmt.Sprint(e.Index))
-	w.Header().Set("Content-Type", "application/json")
-	w.WriteHeader(e.StatusCode())
-	_, err := w.Write([]byte(e.toJsonString() + "\n"))
-	return err
-}
diff --git a/vendor/github.com/coreos/etcd/etcd.conf.yml.sample b/vendor/github.com/coreos/etcd/etcd.conf.yml.sample
deleted file mode 100644
index 2bc115f..0000000
--- a/vendor/github.com/coreos/etcd/etcd.conf.yml.sample
+++ /dev/null
@@ -1,144 +0,0 @@
-# This is the configuration file for the etcd server.
-
-# Human-readable name for this member.
-name: 'default'
-
-# Path to the data directory.
-data-dir:
-
-# Path to the dedicated wal directory.
-wal-dir:
-
-# Number of committed transactions to trigger a snapshot to disk.
-snapshot-count: 10000
-
-# Time (in milliseconds) of a heartbeat interval.
-heartbeat-interval: 100
-
-# Time (in milliseconds) for an election to timeout.
-election-timeout: 1000
-
-# Raise alarms when backend size exceeds the given quota. 0 means use the
-# default quota.
-quota-backend-bytes: 0
-
-# List of comma separated URLs to listen on for peer traffic.
-listen-peer-urls: http://localhost:2380
-
-# List of comma separated URLs to listen on for client traffic.
-listen-client-urls: http://localhost:2379
-
-# Maximum number of snapshot files to retain (0 is unlimited).
-max-snapshots: 5
-
-# Maximum number of wal files to retain (0 is unlimited).
-max-wals: 5
-
-# Comma-separated white list of origins for CORS (cross-origin resource sharing).
-cors:
-
-# List of this member's peer URLs to advertise to the rest of the cluster.
-# The URLs needed to be a comma-separated list.
-initial-advertise-peer-urls: http://localhost:2380
-
-# List of this member's client URLs to advertise to the public.
-# The URLs needed to be a comma-separated list.
-advertise-client-urls: http://localhost:2379
-
-# Discovery URL used to bootstrap the cluster.
-discovery:
-
-# Valid values include 'exit', 'proxy'
-discovery-fallback: 'proxy'
-
-# HTTP proxy to use for traffic to discovery service.
-discovery-proxy:
-
-# DNS domain used to bootstrap initial cluster.
-discovery-srv:
-
-# Initial cluster configuration for bootstrapping.
-initial-cluster:
-
-# Initial cluster token for the etcd cluster during bootstrap.
-initial-cluster-token: 'etcd-cluster'
-
-# Initial cluster state ('new' or 'existing').
-initial-cluster-state: 'new'
-
-# Reject reconfiguration requests that would cause quorum loss.
-strict-reconfig-check: false
-
-# Accept etcd V2 client requests
-enable-v2: true
-
-# Enable runtime profiling data via HTTP server
-enable-pprof: true
-
-# Valid values include 'on', 'readonly', 'off'
-proxy: 'off'
-
-# Time (in milliseconds) an endpoint will be held in a failed state.
-proxy-failure-wait: 5000
-
-# Time (in milliseconds) of the endpoints refresh interval.
-proxy-refresh-interval: 30000
-
-# Time (in milliseconds) for a dial to timeout.
-proxy-dial-timeout: 1000
-
-# Time (in milliseconds) for a write to timeout.
-proxy-write-timeout: 5000
-
-# Time (in milliseconds) for a read to timeout.
-proxy-read-timeout: 0
-
-client-transport-security:
-  # DEPRECATED: Path to the client server TLS CA file.
-  ca-file:
-
-  # Path to the client server TLS cert file.
-  cert-file:
-
-  # Path to the client server TLS key file.
-  key-file:
-
-  # Enable client cert authentication.
-  client-cert-auth: false
-
-  # Path to the client server TLS trusted CA cert file.
-  trusted-ca-file:
-
-  # Client TLS using generated certificates
-  auto-tls: false
-
-peer-transport-security:
-  # DEPRECATED: Path to the peer server TLS CA file.
-  ca-file:
-
-  # Path to the peer server TLS cert file.
-  cert-file:
-
-  # Path to the peer server TLS key file.
-  key-file:
-
-  # Enable peer client cert authentication.
-  peer-client-cert-auth: false
-
-  # Path to the peer server TLS trusted CA cert file.
-  trusted-ca-file:
-
-  # Peer TLS using generated certificates.
-  auto-tls: false
-
-# Enable debug-level logging for etcd.
-debug: false
-
-# Specify a particular log level for each etcd package (eg: 'etcdmain=CRITICAL,etcdserver=DEBUG'.
-log-package-levels:
-
-# Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.
-log-output: default
-
-# Force to create a new one member cluster.
-force-new-cluster: false
diff --git a/vendor/github.com/coreos/etcd/etcdmain/config.go b/vendor/github.com/coreos/etcd/etcdmain/config.go
deleted file mode 100644
index 2a5faa7..0000000
--- a/vendor/github.com/coreos/etcd/etcdmain/config.go
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Every change should be reflected on help.go as well.
-
-package etcdmain
-
-import (
-	"flag"
-	"fmt"
-	"io/ioutil"
-	"net/url"
-	"os"
-	"runtime"
-	"strings"
-
-	"github.com/coreos/etcd/embed"
-	"github.com/coreos/etcd/pkg/flags"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/version"
-
-	"github.com/ghodss/yaml"
-)
-
-var (
-	proxyFlagOff      = "off"
-	proxyFlagReadonly = "readonly"
-	proxyFlagOn       = "on"
-
-	fallbackFlagExit  = "exit"
-	fallbackFlagProxy = "proxy"
-
-	ignored = []string{
-		"cluster-active-size",
-		"cluster-remove-delay",
-		"cluster-sync-interval",
-		"config",
-		"force",
-		"max-result-buffer",
-		"max-retry-attempts",
-		"peer-heartbeat-interval",
-		"peer-election-timeout",
-		"retry-interval",
-		"snapshot",
-		"v",
-		"vv",
-		// for coverage testing
-		"test.coverprofile",
-		"test.outputdir",
-	}
-)
-
-type configProxy struct {
-	ProxyFailureWaitMs     uint `json:"proxy-failure-wait"`
-	ProxyRefreshIntervalMs uint `json:"proxy-refresh-interval"`
-	ProxyDialTimeoutMs     uint `json:"proxy-dial-timeout"`
-	ProxyWriteTimeoutMs    uint `json:"proxy-write-timeout"`
-	ProxyReadTimeoutMs     uint `json:"proxy-read-timeout"`
-	Fallback               string
-	Proxy                  string
-	ProxyJSON              string `json:"proxy"`
-	FallbackJSON           string `json:"discovery-fallback"`
-}
-
-// config holds the config for a command line invocation of etcd
-type config struct {
-	ec           embed.Config
-	cp           configProxy
-	cf           configFlags
-	configFile   string
-	printVersion bool
-	ignored      []string
-}
-
-// configFlags has the set of flags used for command line parsing a Config
-type configFlags struct {
-	flagSet      *flag.FlagSet
-	clusterState *flags.StringsFlag
-	fallback     *flags.StringsFlag
-	proxy        *flags.StringsFlag
-}
-
-func newConfig() *config {
-	cfg := &config{
-		ec: *embed.NewConfig(),
-		cp: configProxy{
-			Proxy:                  proxyFlagOff,
-			ProxyFailureWaitMs:     5000,
-			ProxyRefreshIntervalMs: 30000,
-			ProxyDialTimeoutMs:     1000,
-			ProxyWriteTimeoutMs:    5000,
-		},
-		ignored: ignored,
-	}
-	cfg.cf = configFlags{
-		flagSet: flag.NewFlagSet("etcd", flag.ContinueOnError),
-		clusterState: flags.NewStringsFlag(
-			embed.ClusterStateFlagNew,
-			embed.ClusterStateFlagExisting,
-		),
-		fallback: flags.NewStringsFlag(
-			fallbackFlagProxy,
-			fallbackFlagExit,
-		),
-		proxy: flags.NewStringsFlag(
-			proxyFlagOff,
-			proxyFlagReadonly,
-			proxyFlagOn,
-		),
-	}
-
-	fs := cfg.cf.flagSet
-	fs.Usage = func() {
-		fmt.Fprintln(os.Stderr, usageline)
-	}
-
-	fs.StringVar(&cfg.configFile, "config-file", "", "Path to the server configuration file")
-
-	// member
-	fs.Var(cfg.ec.CorsInfo, "cors", "Comma-separated white list of origins for CORS (cross-origin resource sharing).")
-	fs.StringVar(&cfg.ec.Dir, "data-dir", cfg.ec.Dir, "Path to the data directory.")
-	fs.StringVar(&cfg.ec.WalDir, "wal-dir", cfg.ec.WalDir, "Path to the dedicated wal directory.")
-	fs.Var(flags.NewURLsValue(embed.DefaultListenPeerURLs), "listen-peer-urls", "List of URLs to listen on for peer traffic.")
-	fs.Var(flags.NewURLsValue(embed.DefaultListenClientURLs), "listen-client-urls", "List of URLs to listen on for client traffic.")
-	fs.StringVar(&cfg.ec.ListenMetricsUrlsJSON, "listen-metrics-urls", "", "List of URLs to listen on for metrics.")
-	fs.UintVar(&cfg.ec.MaxSnapFiles, "max-snapshots", cfg.ec.MaxSnapFiles, "Maximum number of snapshot files to retain (0 is unlimited).")
-	fs.UintVar(&cfg.ec.MaxWalFiles, "max-wals", cfg.ec.MaxWalFiles, "Maximum number of wal files to retain (0 is unlimited).")
-	fs.StringVar(&cfg.ec.Name, "name", cfg.ec.Name, "Human-readable name for this member.")
-	fs.Uint64Var(&cfg.ec.SnapCount, "snapshot-count", cfg.ec.SnapCount, "Number of committed transactions to trigger a snapshot to disk.")
-	fs.UintVar(&cfg.ec.TickMs, "heartbeat-interval", cfg.ec.TickMs, "Time (in milliseconds) of a heartbeat interval.")
-	fs.UintVar(&cfg.ec.ElectionMs, "election-timeout", cfg.ec.ElectionMs, "Time (in milliseconds) for an election to timeout.")
-	fs.BoolVar(&cfg.ec.InitialElectionTickAdvance, "initial-election-tick-advance", cfg.ec.InitialElectionTickAdvance, "Whether to fast-forward initial election ticks on boot for faster election.")
-	fs.Int64Var(&cfg.ec.QuotaBackendBytes, "quota-backend-bytes", cfg.ec.QuotaBackendBytes, "Raise alarms when backend size exceeds the given quota. 0 means use the default quota.")
-	fs.UintVar(&cfg.ec.MaxTxnOps, "max-txn-ops", cfg.ec.MaxTxnOps, "Maximum number of operations permitted in a transaction.")
-	fs.UintVar(&cfg.ec.MaxRequestBytes, "max-request-bytes", cfg.ec.MaxRequestBytes, "Maximum client request size in bytes the server will accept.")
-	fs.DurationVar(&cfg.ec.GRPCKeepAliveMinTime, "grpc-keepalive-min-time", cfg.ec.GRPCKeepAliveMinTime, "Minimum interval duration that a client should wait before pinging server.")
-	fs.DurationVar(&cfg.ec.GRPCKeepAliveInterval, "grpc-keepalive-interval", cfg.ec.GRPCKeepAliveInterval, "Frequency duration of server-to-client ping to check if a connection is alive (0 to disable).")
-	fs.DurationVar(&cfg.ec.GRPCKeepAliveTimeout, "grpc-keepalive-timeout", cfg.ec.GRPCKeepAliveTimeout, "Additional duration of wait before closing a non-responsive connection (0 to disable).")
-
-	// clustering
-	fs.Var(flags.NewURLsValue(embed.DefaultInitialAdvertisePeerURLs), "initial-advertise-peer-urls", "List of this member's peer URLs to advertise to the rest of the cluster.")
-	fs.Var(flags.NewURLsValue(embed.DefaultAdvertiseClientURLs), "advertise-client-urls", "List of this member's client URLs to advertise to the public.")
-	fs.StringVar(&cfg.ec.Durl, "discovery", cfg.ec.Durl, "Discovery URL used to bootstrap the cluster.")
-	fs.Var(cfg.cf.fallback, "discovery-fallback", fmt.Sprintf("Valid values include %s", strings.Join(cfg.cf.fallback.Values, ", ")))
-
-	fs.StringVar(&cfg.ec.Dproxy, "discovery-proxy", cfg.ec.Dproxy, "HTTP proxy to use for traffic to discovery service.")
-	fs.StringVar(&cfg.ec.DNSCluster, "discovery-srv", cfg.ec.DNSCluster, "DNS domain used to bootstrap initial cluster.")
-	fs.StringVar(&cfg.ec.InitialCluster, "initial-cluster", cfg.ec.InitialCluster, "Initial cluster configuration for bootstrapping.")
-	fs.StringVar(&cfg.ec.InitialClusterToken, "initial-cluster-token", cfg.ec.InitialClusterToken, "Initial cluster token for the etcd cluster during bootstrap.")
-	fs.Var(cfg.cf.clusterState, "initial-cluster-state", "Initial cluster state ('new' or 'existing').")
-
-	fs.BoolVar(&cfg.ec.StrictReconfigCheck, "strict-reconfig-check", cfg.ec.StrictReconfigCheck, "Reject reconfiguration requests that would cause quorum loss.")
-	fs.BoolVar(&cfg.ec.EnableV2, "enable-v2", cfg.ec.EnableV2, "Accept etcd V2 client requests.")
-	fs.StringVar(&cfg.ec.ExperimentalEnableV2V3, "experimental-enable-v2v3", cfg.ec.ExperimentalEnableV2V3, "v3 prefix for serving emulated v2 state.")
-
-	// proxy
-	fs.Var(cfg.cf.proxy, "proxy", fmt.Sprintf("Valid values include %s", strings.Join(cfg.cf.proxy.Values, ", ")))
-
-	fs.UintVar(&cfg.cp.ProxyFailureWaitMs, "proxy-failure-wait", cfg.cp.ProxyFailureWaitMs, "Time (in milliseconds) an endpoint will be held in a failed state.")
-	fs.UintVar(&cfg.cp.ProxyRefreshIntervalMs, "proxy-refresh-interval", cfg.cp.ProxyRefreshIntervalMs, "Time (in milliseconds) of the endpoints refresh interval.")
-	fs.UintVar(&cfg.cp.ProxyDialTimeoutMs, "proxy-dial-timeout", cfg.cp.ProxyDialTimeoutMs, "Time (in milliseconds) for a dial to timeout.")
-	fs.UintVar(&cfg.cp.ProxyWriteTimeoutMs, "proxy-write-timeout", cfg.cp.ProxyWriteTimeoutMs, "Time (in milliseconds) for a write to timeout.")
-	fs.UintVar(&cfg.cp.ProxyReadTimeoutMs, "proxy-read-timeout", cfg.cp.ProxyReadTimeoutMs, "Time (in milliseconds) for a read to timeout.")
-
-	// security
-	fs.StringVar(&cfg.ec.ClientTLSInfo.CAFile, "ca-file", "", "DEPRECATED: Path to the client server TLS CA file.")
-	fs.StringVar(&cfg.ec.ClientTLSInfo.CertFile, "cert-file", "", "Path to the client server TLS cert file.")
-	fs.StringVar(&cfg.ec.ClientTLSInfo.KeyFile, "key-file", "", "Path to the client server TLS key file.")
-	fs.BoolVar(&cfg.ec.ClientTLSInfo.ClientCertAuth, "client-cert-auth", false, "Enable client cert authentication.")
-	fs.StringVar(&cfg.ec.ClientTLSInfo.CRLFile, "client-crl-file", "", "Path to the client certificate revocation list file.")
-	fs.StringVar(&cfg.ec.ClientTLSInfo.TrustedCAFile, "trusted-ca-file", "", "Path to the client server TLS trusted CA cert file.")
-	fs.BoolVar(&cfg.ec.ClientAutoTLS, "auto-tls", false, "Client TLS using generated certificates")
-	fs.StringVar(&cfg.ec.PeerTLSInfo.CAFile, "peer-ca-file", "", "DEPRECATED: Path to the peer server TLS CA file.")
-	fs.StringVar(&cfg.ec.PeerTLSInfo.CertFile, "peer-cert-file", "", "Path to the peer server TLS cert file.")
-	fs.StringVar(&cfg.ec.PeerTLSInfo.KeyFile, "peer-key-file", "", "Path to the peer server TLS key file.")
-	fs.BoolVar(&cfg.ec.PeerTLSInfo.ClientCertAuth, "peer-client-cert-auth", false, "Enable peer client cert authentication.")
-	fs.StringVar(&cfg.ec.PeerTLSInfo.TrustedCAFile, "peer-trusted-ca-file", "", "Path to the peer server TLS trusted CA file.")
-	fs.BoolVar(&cfg.ec.PeerAutoTLS, "peer-auto-tls", false, "Peer TLS using generated certificates")
-	fs.StringVar(&cfg.ec.PeerTLSInfo.CRLFile, "peer-crl-file", "", "Path to the peer certificate revocation list file.")
-	fs.StringVar(&cfg.ec.PeerTLSInfo.AllowedCN, "peer-cert-allowed-cn", "", "Allowed CN for inter peer authentication.")
-
-	fs.Var(flags.NewStringsValueV2(""), "cipher-suites", "Comma-separated list of supported TLS cipher suites between client/server and peers (empty will be auto-populated by Go).")
-
-	// logging
-	fs.BoolVar(&cfg.ec.Debug, "debug", false, "Enable debug-level logging for etcd.")
-	fs.StringVar(&cfg.ec.LogPkgLevels, "log-package-levels", "", "Specify a particular log level for each etcd package (eg: 'etcdmain=CRITICAL,etcdserver=DEBUG').")
-	fs.StringVar(&cfg.ec.LogOutput, "log-output", embed.DefaultLogOutput, "Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.")
-
-	// unsafe
-	fs.BoolVar(&cfg.ec.ForceNewCluster, "force-new-cluster", false, "Force to create a new one member cluster.")
-
-	// version
-	fs.BoolVar(&cfg.printVersion, "version", false, "Print the version and exit.")
-
-	fs.StringVar(&cfg.ec.AutoCompactionRetention, "auto-compaction-retention", "0", "Auto compaction retention for mvcc key value store. 0 means disable auto compaction.")
-	fs.StringVar(&cfg.ec.AutoCompactionMode, "auto-compaction-mode", "periodic", "interpret 'auto-compaction-retention' one of: periodic|revision. 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. '5m'). 'revision' for revision number based retention.")
-
-	// pprof profiler via HTTP
-	fs.BoolVar(&cfg.ec.EnablePprof, "enable-pprof", false, "Enable runtime profiling data via HTTP server. Address is at client URL + \"/debug/pprof/\"")
-
-	// additional metrics
-	fs.StringVar(&cfg.ec.Metrics, "metrics", cfg.ec.Metrics, "Set level of detail for exported metrics, specify 'extensive' to include histogram metrics")
-
-	// auth
-	fs.StringVar(&cfg.ec.AuthToken, "auth-token", cfg.ec.AuthToken, "Specify auth token specific options.")
-
-	// experimental
-	fs.BoolVar(&cfg.ec.ExperimentalInitialCorruptCheck, "experimental-initial-corrupt-check", cfg.ec.ExperimentalInitialCorruptCheck, "Enable to check data corruption before serving any client/peer traffic.")
-	fs.DurationVar(&cfg.ec.ExperimentalCorruptCheckTime, "experimental-corrupt-check-time", cfg.ec.ExperimentalCorruptCheckTime, "Duration of time between cluster corruption check passes.")
-
-	// ignored
-	for _, f := range cfg.ignored {
-		fs.Var(&flags.IgnoredFlag{Name: f}, f, "")
-	}
-	return cfg
-}
-
-func (cfg *config) parse(arguments []string) error {
-	perr := cfg.cf.flagSet.Parse(arguments)
-	switch perr {
-	case nil:
-	case flag.ErrHelp:
-		fmt.Println(flagsline)
-		os.Exit(0)
-	default:
-		os.Exit(2)
-	}
-	if len(cfg.cf.flagSet.Args()) != 0 {
-		return fmt.Errorf("'%s' is not a valid flag", cfg.cf.flagSet.Arg(0))
-	}
-
-	if cfg.printVersion {
-		fmt.Printf("etcd Version: %s\n", version.Version)
-		fmt.Printf("Git SHA: %s\n", version.GitSHA)
-		fmt.Printf("Go Version: %s\n", runtime.Version())
-		fmt.Printf("Go OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
-		os.Exit(0)
-	}
-
-	var err error
-	if cfg.configFile != "" {
-		plog.Infof("Loading server configuration from %q", cfg.configFile)
-		err = cfg.configFromFile(cfg.configFile)
-	} else {
-		err = cfg.configFromCmdLine()
-	}
-	return err
-}
-
-func (cfg *config) configFromCmdLine() error {
-	err := flags.SetFlagsFromEnv("ETCD", cfg.cf.flagSet)
-	if err != nil {
-		plog.Fatalf("%v", err)
-	}
-
-	cfg.ec.LPUrls = flags.URLsFromFlag(cfg.cf.flagSet, "listen-peer-urls")
-	cfg.ec.APUrls = flags.URLsFromFlag(cfg.cf.flagSet, "initial-advertise-peer-urls")
-	cfg.ec.LCUrls = flags.URLsFromFlag(cfg.cf.flagSet, "listen-client-urls")
-	cfg.ec.ACUrls = flags.URLsFromFlag(cfg.cf.flagSet, "advertise-client-urls")
-
-	if len(cfg.ec.ListenMetricsUrlsJSON) > 0 {
-		u, err := types.NewURLs(strings.Split(cfg.ec.ListenMetricsUrlsJSON, ","))
-		if err != nil {
-			plog.Fatalf("unexpected error setting up listen-metrics-urls: %v", err)
-		}
-		cfg.ec.ListenMetricsUrls = []url.URL(u)
-	}
-
-	cfg.ec.CipherSuites = flags.StringsFromFlagV2(cfg.cf.flagSet, "cipher-suites")
-
-	cfg.ec.ClusterState = cfg.cf.clusterState.String()
-	cfg.cp.Fallback = cfg.cf.fallback.String()
-	cfg.cp.Proxy = cfg.cf.proxy.String()
-
-	// disable default advertise-client-urls if lcurls is set
-	missingAC := flags.IsSet(cfg.cf.flagSet, "listen-client-urls") && !flags.IsSet(cfg.cf.flagSet, "advertise-client-urls")
-	if !cfg.mayBeProxy() && missingAC {
-		cfg.ec.ACUrls = nil
-	}
-
-	// disable default initial-cluster if discovery is set
-	if (cfg.ec.Durl != "" || cfg.ec.DNSCluster != "") && !flags.IsSet(cfg.cf.flagSet, "initial-cluster") {
-		cfg.ec.InitialCluster = ""
-	}
-
-	return cfg.validate()
-}
-
-func (cfg *config) configFromFile(path string) error {
-	eCfg, err := embed.ConfigFromFile(path)
-	if err != nil {
-		return err
-	}
-	cfg.ec = *eCfg
-
-	// load extra config information
-	b, rerr := ioutil.ReadFile(path)
-	if rerr != nil {
-		return rerr
-	}
-	if yerr := yaml.Unmarshal(b, &cfg.cp); yerr != nil {
-		return yerr
-	}
-	if cfg.cp.FallbackJSON != "" {
-		if err := cfg.cf.fallback.Set(cfg.cp.FallbackJSON); err != nil {
-			plog.Panicf("unexpected error setting up discovery-fallback flag: %v", err)
-		}
-		cfg.cp.Fallback = cfg.cf.fallback.String()
-	}
-	if cfg.cp.ProxyJSON != "" {
-		if err := cfg.cf.proxy.Set(cfg.cp.ProxyJSON); err != nil {
-			plog.Panicf("unexpected error setting up proxyFlag: %v", err)
-		}
-		cfg.cp.Proxy = cfg.cf.proxy.String()
-	}
-	return nil
-}
-
-func (cfg *config) mayBeProxy() bool {
-	mayFallbackToProxy := cfg.ec.Durl != "" && cfg.cp.Fallback == fallbackFlagProxy
-	return cfg.cp.Proxy != proxyFlagOff || mayFallbackToProxy
-}
-
-func (cfg *config) validate() error {
-	err := cfg.ec.Validate()
-	// TODO(yichengq): check this for joining through discovery service case
-	if err == embed.ErrUnsetAdvertiseClientURLsFlag && cfg.mayBeProxy() {
-		return nil
-	}
-	return err
-}
-
-func (cfg config) isProxy() bool               { return cfg.cf.proxy.String() != proxyFlagOff }
-func (cfg config) isReadonlyProxy() bool       { return cfg.cf.proxy.String() == proxyFlagReadonly }
-func (cfg config) shouldFallbackToProxy() bool { return cfg.cf.fallback.String() == fallbackFlagProxy }
diff --git a/vendor/github.com/coreos/etcd/etcdmain/doc.go b/vendor/github.com/coreos/etcd/etcdmain/doc.go
deleted file mode 100644
index ff281aa..0000000
--- a/vendor/github.com/coreos/etcd/etcdmain/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package etcdmain contains the main entry point for the etcd binary.
-package etcdmain
diff --git a/vendor/github.com/coreos/etcd/etcdmain/etcd.go b/vendor/github.com/coreos/etcd/etcdmain/etcd.go
deleted file mode 100644
index 87e9b25..0000000
--- a/vendor/github.com/coreos/etcd/etcdmain/etcd.go
+++ /dev/null
@@ -1,399 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdmain
-
-import (
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"os"
-	"path/filepath"
-	"reflect"
-	"runtime"
-	"strings"
-	"time"
-
-	"github.com/coreos/etcd/discovery"
-	"github.com/coreos/etcd/embed"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/etcdhttp"
-	"github.com/coreos/etcd/pkg/cors"
-	"github.com/coreos/etcd/pkg/fileutil"
-	pkgioutil "github.com/coreos/etcd/pkg/ioutil"
-	"github.com/coreos/etcd/pkg/osutil"
-	"github.com/coreos/etcd/pkg/transport"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/proxy/httpproxy"
-	"github.com/coreos/etcd/version"
-
-	"github.com/coreos/pkg/capnslog"
-	"google.golang.org/grpc"
-)
-
-type dirType string
-
-var plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdmain")
-
-var (
-	dirMember = dirType("member")
-	dirProxy  = dirType("proxy")
-	dirEmpty  = dirType("empty")
-)
-
-func startEtcdOrProxyV2() {
-	grpc.EnableTracing = false
-
-	cfg := newConfig()
-	defaultInitialCluster := cfg.ec.InitialCluster
-
-	err := cfg.parse(os.Args[1:])
-	if err != nil {
-		plog.Errorf("error verifying flags, %v. See 'etcd --help'.", err)
-		switch err {
-		case embed.ErrUnsetAdvertiseClientURLsFlag:
-			plog.Errorf("When listening on specific address(es), this etcd process must advertise accessible url(s) to each connected client.")
-		}
-		os.Exit(1)
-	}
-	cfg.ec.SetupLogging()
-
-	var stopped <-chan struct{}
-	var errc <-chan error
-
-	plog.Infof("etcd Version: %s\n", version.Version)
-	plog.Infof("Git SHA: %s\n", version.GitSHA)
-	plog.Infof("Go Version: %s\n", runtime.Version())
-	plog.Infof("Go OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
-
-	GoMaxProcs := runtime.GOMAXPROCS(0)
-	plog.Infof("setting maximum number of CPUs to %d, total number of available CPUs is %d", GoMaxProcs, runtime.NumCPU())
-
-	defaultHost, dhErr := (&cfg.ec).UpdateDefaultClusterFromName(defaultInitialCluster)
-	if defaultHost != "" {
-		plog.Infof("advertising using detected default host %q", defaultHost)
-	}
-	if dhErr != nil {
-		plog.Noticef("failed to detect default host (%v)", dhErr)
-	}
-
-	if cfg.ec.Dir == "" {
-		cfg.ec.Dir = fmt.Sprintf("%v.etcd", cfg.ec.Name)
-		plog.Warningf("no data-dir provided, using default data-dir ./%s", cfg.ec.Dir)
-	}
-
-	which := identifyDataDirOrDie(cfg.ec.Dir)
-	if which != dirEmpty {
-		plog.Noticef("the server is already initialized as %v before, starting as etcd %v...", which, which)
-		switch which {
-		case dirMember:
-			stopped, errc, err = startEtcd(&cfg.ec)
-		case dirProxy:
-			err = startProxy(cfg)
-		default:
-			plog.Panicf("unhandled dir type %v", which)
-		}
-	} else {
-		shouldProxy := cfg.isProxy()
-		if !shouldProxy {
-			stopped, errc, err = startEtcd(&cfg.ec)
-			if derr, ok := err.(*etcdserver.DiscoveryError); ok && derr.Err == discovery.ErrFullCluster {
-				if cfg.shouldFallbackToProxy() {
-					plog.Noticef("discovery cluster full, falling back to %s", fallbackFlagProxy)
-					shouldProxy = true
-				}
-			}
-		}
-		if shouldProxy {
-			err = startProxy(cfg)
-		}
-	}
-
-	if err != nil {
-		if derr, ok := err.(*etcdserver.DiscoveryError); ok {
-			switch derr.Err {
-			case discovery.ErrDuplicateID:
-				plog.Errorf("member %q has previously registered with discovery service token (%s).", cfg.ec.Name, cfg.ec.Durl)
-				plog.Errorf("But etcd could not find valid cluster configuration in the given data dir (%s).", cfg.ec.Dir)
-				plog.Infof("Please check the given data dir path if the previous bootstrap succeeded")
-				plog.Infof("or use a new discovery token if the previous bootstrap failed.")
-			case discovery.ErrDuplicateName:
-				plog.Errorf("member with duplicated name has registered with discovery service token(%s).", cfg.ec.Durl)
-				plog.Errorf("please check (cURL) the discovery token for more information.")
-				plog.Errorf("please do not reuse the discovery token and generate a new one to bootstrap the cluster.")
-			default:
-				plog.Errorf("%v", err)
-				plog.Infof("discovery token %s was used, but failed to bootstrap the cluster.", cfg.ec.Durl)
-				plog.Infof("please generate a new discovery token and try to bootstrap again.")
-			}
-			os.Exit(1)
-		}
-
-		if strings.Contains(err.Error(), "include") && strings.Contains(err.Error(), "--initial-cluster") {
-			plog.Infof("%v", err)
-			if cfg.ec.InitialCluster == cfg.ec.InitialClusterFromName(cfg.ec.Name) {
-				plog.Infof("forgot to set --initial-cluster flag?")
-			}
-			if types.URLs(cfg.ec.APUrls).String() == embed.DefaultInitialAdvertisePeerURLs {
-				plog.Infof("forgot to set --initial-advertise-peer-urls flag?")
-			}
-			if cfg.ec.InitialCluster == cfg.ec.InitialClusterFromName(cfg.ec.Name) && len(cfg.ec.Durl) == 0 {
-				plog.Infof("if you want to use discovery service, please set --discovery flag.")
-			}
-			os.Exit(1)
-		}
-		plog.Fatalf("%v", err)
-	}
-
-	osutil.HandleInterrupts()
-
-	// At this point, the initialization of etcd is done.
-	// The listeners are listening on the TCP ports and ready
-	// for accepting connections. The etcd instance should be
-	// joined with the cluster and ready to serve incoming
-	// connections.
-	notifySystemd()
-
-	select {
-	case lerr := <-errc:
-		// fatal out on listener errors
-		plog.Fatal(lerr)
-	case <-stopped:
-	}
-
-	osutil.Exit(0)
-}
-
-// startEtcd runs StartEtcd in addition to hooks needed for standalone etcd.
-func startEtcd(cfg *embed.Config) (<-chan struct{}, <-chan error, error) {
-	e, err := embed.StartEtcd(cfg)
-	if err != nil {
-		return nil, nil, err
-	}
-	osutil.RegisterInterruptHandler(e.Close)
-	select {
-	case <-e.Server.ReadyNotify(): // wait for e.Server to join the cluster
-	case <-e.Server.StopNotify(): // publish aborted from 'ErrStopped'
-	}
-	return e.Server.StopNotify(), e.Err(), nil
-}
-
-// startProxy launches an HTTP proxy for client communication which proxies to other etcd nodes.
-func startProxy(cfg *config) error {
-	plog.Notice("proxy: this proxy supports v2 API only!")
-
-	clientTLSInfo := cfg.ec.ClientTLSInfo
-	if clientTLSInfo.Empty() {
-		// Support old proxy behavior of defaulting to PeerTLSInfo
-		// for both client and peer connections.
-		clientTLSInfo = cfg.ec.PeerTLSInfo
-	}
-	clientTLSInfo.InsecureSkipVerify = cfg.ec.ClientAutoTLS
-	cfg.ec.PeerTLSInfo.InsecureSkipVerify = cfg.ec.PeerAutoTLS
-
-	pt, err := transport.NewTimeoutTransport(clientTLSInfo, time.Duration(cfg.cp.ProxyDialTimeoutMs)*time.Millisecond, time.Duration(cfg.cp.ProxyReadTimeoutMs)*time.Millisecond, time.Duration(cfg.cp.ProxyWriteTimeoutMs)*time.Millisecond)
-	if err != nil {
-		return err
-	}
-	pt.MaxIdleConnsPerHost = httpproxy.DefaultMaxIdleConnsPerHost
-
-	if err = cfg.ec.PeerSelfCert(); err != nil {
-		plog.Fatalf("could not get certs (%v)", err)
-	}
-	tr, err := transport.NewTimeoutTransport(cfg.ec.PeerTLSInfo, time.Duration(cfg.cp.ProxyDialTimeoutMs)*time.Millisecond, time.Duration(cfg.cp.ProxyReadTimeoutMs)*time.Millisecond, time.Duration(cfg.cp.ProxyWriteTimeoutMs)*time.Millisecond)
-	if err != nil {
-		return err
-	}
-
-	cfg.ec.Dir = filepath.Join(cfg.ec.Dir, "proxy")
-	err = os.MkdirAll(cfg.ec.Dir, fileutil.PrivateDirMode)
-	if err != nil {
-		return err
-	}
-
-	var peerURLs []string
-	clusterfile := filepath.Join(cfg.ec.Dir, "cluster")
-
-	b, err := ioutil.ReadFile(clusterfile)
-	switch {
-	case err == nil:
-		if cfg.ec.Durl != "" {
-			plog.Warningf("discovery token ignored since the proxy has already been initialized. Valid cluster file found at %q", clusterfile)
-		}
-		if cfg.ec.DNSCluster != "" {
-			plog.Warningf("DNS SRV discovery ignored since the proxy has already been initialized. Valid cluster file found at %q", clusterfile)
-		}
-		urls := struct{ PeerURLs []string }{}
-		err = json.Unmarshal(b, &urls)
-		if err != nil {
-			return err
-		}
-		peerURLs = urls.PeerURLs
-		plog.Infof("proxy: using peer urls %v from cluster file %q", peerURLs, clusterfile)
-	case os.IsNotExist(err):
-		var urlsmap types.URLsMap
-		urlsmap, _, err = cfg.ec.PeerURLsMapAndToken("proxy")
-		if err != nil {
-			return fmt.Errorf("error setting up initial cluster: %v", err)
-		}
-
-		if cfg.ec.Durl != "" {
-			var s string
-			s, err = discovery.GetCluster(cfg.ec.Durl, cfg.ec.Dproxy)
-			if err != nil {
-				return err
-			}
-			if urlsmap, err = types.NewURLsMap(s); err != nil {
-				return err
-			}
-		}
-		peerURLs = urlsmap.URLs()
-		plog.Infof("proxy: using peer urls %v ", peerURLs)
-	default:
-		return err
-	}
-
-	clientURLs := []string{}
-	uf := func() []string {
-		gcls, gerr := etcdserver.GetClusterFromRemotePeers(peerURLs, tr)
-
-		if gerr != nil {
-			plog.Warningf("proxy: %v", gerr)
-			return []string{}
-		}
-
-		clientURLs = gcls.ClientURLs()
-
-		urls := struct{ PeerURLs []string }{gcls.PeerURLs()}
-		b, jerr := json.Marshal(urls)
-		if jerr != nil {
-			plog.Warningf("proxy: error on marshal peer urls %s", jerr)
-			return clientURLs
-		}
-
-		err = pkgioutil.WriteAndSyncFile(clusterfile+".bak", b, 0600)
-		if err != nil {
-			plog.Warningf("proxy: error on writing urls %s", err)
-			return clientURLs
-		}
-		err = os.Rename(clusterfile+".bak", clusterfile)
-		if err != nil {
-			plog.Warningf("proxy: error on updating clusterfile %s", err)
-			return clientURLs
-		}
-		if !reflect.DeepEqual(gcls.PeerURLs(), peerURLs) {
-			plog.Noticef("proxy: updated peer urls in cluster file from %v to %v", peerURLs, gcls.PeerURLs())
-		}
-		peerURLs = gcls.PeerURLs()
-
-		return clientURLs
-	}
-	ph := httpproxy.NewHandler(pt, uf, time.Duration(cfg.cp.ProxyFailureWaitMs)*time.Millisecond, time.Duration(cfg.cp.ProxyRefreshIntervalMs)*time.Millisecond)
-	ph = &cors.CORSHandler{
-		Handler: ph,
-		Info:    cfg.ec.CorsInfo,
-	}
-
-	if cfg.isReadonlyProxy() {
-		ph = httpproxy.NewReadonlyHandler(ph)
-	}
-
-	// setup self signed certs when serving https
-	cHosts, cTLS := []string{}, false
-	for _, u := range cfg.ec.LCUrls {
-		cHosts = append(cHosts, u.Host)
-		cTLS = cTLS || u.Scheme == "https"
-	}
-	for _, u := range cfg.ec.ACUrls {
-		cHosts = append(cHosts, u.Host)
-		cTLS = cTLS || u.Scheme == "https"
-	}
-	listenerTLS := cfg.ec.ClientTLSInfo
-	if cfg.ec.ClientAutoTLS && cTLS {
-		listenerTLS, err = transport.SelfCert(filepath.Join(cfg.ec.Dir, "clientCerts"), cHosts)
-		if err != nil {
-			plog.Fatalf("proxy: could not initialize self-signed client certs (%v)", err)
-		}
-	}
-
-	// Start a proxy server goroutine for each listen address
-	for _, u := range cfg.ec.LCUrls {
-		l, err := transport.NewListener(u.Host, u.Scheme, &listenerTLS)
-		if err != nil {
-			return err
-		}
-
-		host := u.String()
-		go func() {
-			plog.Info("proxy: listening for client requests on ", host)
-			mux := http.NewServeMux()
-			etcdhttp.HandlePrometheus(mux) // v2 proxy just uses the same port
-			mux.Handle("/", ph)
-			plog.Fatal(http.Serve(l, mux))
-		}()
-	}
-	return nil
-}
-
-// identifyDataDirOrDie returns the type of the data dir.
-// Dies if the datadir is invalid.
-func identifyDataDirOrDie(dir string) dirType {
-	names, err := fileutil.ReadDir(dir)
-	if err != nil {
-		if os.IsNotExist(err) {
-			return dirEmpty
-		}
-		plog.Fatalf("error listing data dir: %s", dir)
-	}
-
-	var m, p bool
-	for _, name := range names {
-		switch dirType(name) {
-		case dirMember:
-			m = true
-		case dirProxy:
-			p = true
-		default:
-			plog.Warningf("found invalid file/dir %s under data dir %s (Ignore this if you are upgrading etcd)", name, dir)
-		}
-	}
-
-	if m && p {
-		plog.Fatal("invalid datadir. Both member and proxy directories exist.")
-	}
-	if m {
-		return dirMember
-	}
-	if p {
-		return dirProxy
-	}
-	return dirEmpty
-}
-
-func checkSupportArch() {
-	// TODO qualify arm64
-	if runtime.GOARCH == "amd64" || runtime.GOARCH == "ppc64le" {
-		return
-	}
-	// unsupported arch only configured via environment variable
-	// so unset here to not parse through flag
-	defer os.Unsetenv("ETCD_UNSUPPORTED_ARCH")
-	if env, ok := os.LookupEnv("ETCD_UNSUPPORTED_ARCH"); ok && env == runtime.GOARCH {
-		plog.Warningf("running etcd on unsupported architecture %q since ETCD_UNSUPPORTED_ARCH is set", env)
-		return
-	}
-	plog.Errorf("etcd on unsupported platform without ETCD_UNSUPPORTED_ARCH=%s set.", runtime.GOARCH)
-	os.Exit(1)
-}
diff --git a/vendor/github.com/coreos/etcd/etcdmain/gateway.go b/vendor/github.com/coreos/etcd/etcdmain/gateway.go
deleted file mode 100644
index 5487414..0000000
--- a/vendor/github.com/coreos/etcd/etcdmain/gateway.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdmain
-
-import (
-	"fmt"
-	"net"
-	"net/url"
-	"os"
-	"time"
-
-	"github.com/coreos/etcd/proxy/tcpproxy"
-
-	"github.com/spf13/cobra"
-)
-
-var (
-	gatewayListenAddr        string
-	gatewayEndpoints         []string
-	gatewayDNSCluster        string
-	gatewayInsecureDiscovery bool
-	getewayRetryDelay        time.Duration
-	gatewayCA                string
-)
-
-var (
-	rootCmd = &cobra.Command{
-		Use:        "etcd",
-		Short:      "etcd server",
-		SuggestFor: []string{"etcd"},
-	}
-)
-
-func init() {
-	rootCmd.AddCommand(newGatewayCommand())
-}
-
-// newGatewayCommand returns the cobra command for "gateway".
-func newGatewayCommand() *cobra.Command {
-	lpc := &cobra.Command{
-		Use:   "gateway <subcommand>",
-		Short: "gateway related command",
-	}
-	lpc.AddCommand(newGatewayStartCommand())
-
-	return lpc
-}
-
-func newGatewayStartCommand() *cobra.Command {
-	cmd := cobra.Command{
-		Use:   "start",
-		Short: "start the gateway",
-		Run:   startGateway,
-	}
-
-	cmd.Flags().StringVar(&gatewayListenAddr, "listen-addr", "127.0.0.1:23790", "listen address")
-	cmd.Flags().StringVar(&gatewayDNSCluster, "discovery-srv", "", "DNS domain used to bootstrap initial cluster")
-	cmd.Flags().BoolVar(&gatewayInsecureDiscovery, "insecure-discovery", false, "accept insecure SRV records")
-	cmd.Flags().StringVar(&gatewayCA, "trusted-ca-file", "", "path to the client server TLS CA file.")
-
-	cmd.Flags().StringSliceVar(&gatewayEndpoints, "endpoints", []string{"127.0.0.1:2379"}, "comma separated etcd cluster endpoints")
-
-	cmd.Flags().DurationVar(&getewayRetryDelay, "retry-delay", time.Minute, "duration of delay before retrying failed endpoints")
-
-	return &cmd
-}
-
-func stripSchema(eps []string) []string {
-	var endpoints []string
-
-	for _, ep := range eps {
-
-		if u, err := url.Parse(ep); err == nil && u.Host != "" {
-			ep = u.Host
-		}
-
-		endpoints = append(endpoints, ep)
-	}
-
-	return endpoints
-}
-
-func startGateway(cmd *cobra.Command, args []string) {
-	srvs := discoverEndpoints(gatewayDNSCluster, gatewayCA, gatewayInsecureDiscovery)
-	if len(srvs.Endpoints) == 0 {
-		// no endpoints discovered, fall back to provided endpoints
-		srvs.Endpoints = gatewayEndpoints
-	}
-	// Strip the schema from the endpoints because we start just a TCP proxy
-	srvs.Endpoints = stripSchema(srvs.Endpoints)
-	if len(srvs.SRVs) == 0 {
-		for _, ep := range srvs.Endpoints {
-			h, p, err := net.SplitHostPort(ep)
-			if err != nil {
-				plog.Fatalf("error parsing endpoint %q", ep)
-			}
-			var port uint16
-			fmt.Sscanf(p, "%d", &port)
-			srvs.SRVs = append(srvs.SRVs, &net.SRV{Target: h, Port: port})
-		}
-	}
-
-	if len(srvs.Endpoints) == 0 {
-		plog.Fatalf("no endpoints found")
-	}
-
-	l, err := net.Listen("tcp", gatewayListenAddr)
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-
-	tp := tcpproxy.TCPProxy{
-		Listener:        l,
-		Endpoints:       srvs.SRVs,
-		MonitorInterval: getewayRetryDelay,
-	}
-
-	// At this point, etcd gateway listener is initialized
-	notifySystemd()
-
-	tp.Run()
-}
diff --git a/vendor/github.com/coreos/etcd/etcdmain/grpc_proxy.go b/vendor/github.com/coreos/etcd/etcdmain/grpc_proxy.go
deleted file mode 100644
index 6a8e39f..0000000
--- a/vendor/github.com/coreos/etcd/etcdmain/grpc_proxy.go
+++ /dev/null
@@ -1,399 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdmain
-
-import (
-	"context"
-	"fmt"
-	"io/ioutil"
-	"math"
-	"net"
-	"net/http"
-	"net/url"
-	"os"
-	"path/filepath"
-	"time"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/clientv3/leasing"
-	"github.com/coreos/etcd/clientv3/namespace"
-	"github.com/coreos/etcd/clientv3/ordering"
-	"github.com/coreos/etcd/etcdserver/api/etcdhttp"
-	"github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb"
-	"github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/pkg/debugutil"
-	"github.com/coreos/etcd/pkg/transport"
-	"github.com/coreos/etcd/proxy/grpcproxy"
-
-	"github.com/coreos/pkg/capnslog"
-	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
-	"github.com/soheilhy/cmux"
-	"github.com/spf13/cobra"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/grpclog"
-)
-
-var (
-	grpcProxyListenAddr        string
-	grpcProxyMetricsListenAddr string
-	grpcProxyEndpoints         []string
-	grpcProxyDNSCluster        string
-	grpcProxyInsecureDiscovery bool
-	grpcProxyDataDir           string
-	grpcMaxCallSendMsgSize     int
-	grpcMaxCallRecvMsgSize     int
-
-	// tls for connecting to etcd
-
-	grpcProxyCA                    string
-	grpcProxyCert                  string
-	grpcProxyKey                   string
-	grpcProxyInsecureSkipTLSVerify bool
-
-	// tls for clients connecting to proxy
-
-	grpcProxyListenCA      string
-	grpcProxyListenCert    string
-	grpcProxyListenKey     string
-	grpcProxyListenAutoTLS bool
-	grpcProxyListenCRL     string
-
-	grpcProxyAdvertiseClientURL string
-	grpcProxyResolverPrefix     string
-	grpcProxyResolverTTL        int
-
-	grpcProxyNamespace string
-	grpcProxyLeasing   string
-
-	grpcProxyEnablePprof    bool
-	grpcProxyEnableOrdering bool
-
-	grpcProxyDebug bool
-)
-
-const defaultGRPCMaxCallSendMsgSize = 1.5 * 1024 * 1024
-
-func init() {
-	rootCmd.AddCommand(newGRPCProxyCommand())
-}
-
-// newGRPCProxyCommand returns the cobra command for "grpc-proxy".
-func newGRPCProxyCommand() *cobra.Command {
-	lpc := &cobra.Command{
-		Use:   "grpc-proxy <subcommand>",
-		Short: "grpc-proxy related command",
-	}
-	lpc.AddCommand(newGRPCProxyStartCommand())
-
-	return lpc
-}
-
-func newGRPCProxyStartCommand() *cobra.Command {
-	cmd := cobra.Command{
-		Use:   "start",
-		Short: "start the grpc proxy",
-		Run:   startGRPCProxy,
-	}
-
-	cmd.Flags().StringVar(&grpcProxyListenAddr, "listen-addr", "127.0.0.1:23790", "listen address")
-	cmd.Flags().StringVar(&grpcProxyDNSCluster, "discovery-srv", "", "DNS domain used to bootstrap initial cluster")
-	cmd.Flags().StringVar(&grpcProxyMetricsListenAddr, "metrics-addr", "", "listen for /metrics requests on an additional interface")
-	cmd.Flags().BoolVar(&grpcProxyInsecureDiscovery, "insecure-discovery", false, "accept insecure SRV records")
-	cmd.Flags().StringSliceVar(&grpcProxyEndpoints, "endpoints", []string{"127.0.0.1:2379"}, "comma separated etcd cluster endpoints")
-	cmd.Flags().StringVar(&grpcProxyAdvertiseClientURL, "advertise-client-url", "127.0.0.1:23790", "advertise address to register (must be reachable by client)")
-	cmd.Flags().StringVar(&grpcProxyResolverPrefix, "resolver-prefix", "", "prefix to use for registering proxy (must be shared with other grpc-proxy members)")
-	cmd.Flags().IntVar(&grpcProxyResolverTTL, "resolver-ttl", 0, "specify TTL, in seconds, when registering proxy endpoints")
-	cmd.Flags().StringVar(&grpcProxyNamespace, "namespace", "", "string to prefix to all keys for namespacing requests")
-	cmd.Flags().BoolVar(&grpcProxyEnablePprof, "enable-pprof", false, `Enable runtime profiling data via HTTP server. Address is at client URL + "/debug/pprof/"`)
-	cmd.Flags().StringVar(&grpcProxyDataDir, "data-dir", "default.proxy", "Data directory for persistent data")
-	cmd.Flags().IntVar(&grpcMaxCallSendMsgSize, "max-send-bytes", defaultGRPCMaxCallSendMsgSize, "message send limits in bytes (default value is 1.5 MiB)")
-	cmd.Flags().IntVar(&grpcMaxCallRecvMsgSize, "max-recv-bytes", math.MaxInt32, "message receive limits in bytes (default value is math.MaxInt32)")
-
-	// client TLS for connecting to server
-	cmd.Flags().StringVar(&grpcProxyCert, "cert", "", "identify secure connections with etcd servers using this TLS certificate file")
-	cmd.Flags().StringVar(&grpcProxyKey, "key", "", "identify secure connections with etcd servers using this TLS key file")
-	cmd.Flags().StringVar(&grpcProxyCA, "cacert", "", "verify certificates of TLS-enabled secure etcd servers using this CA bundle")
-	cmd.Flags().BoolVar(&grpcProxyInsecureSkipTLSVerify, "insecure-skip-tls-verify", false, "skip authentication of etcd server TLS certificates")
-
-	// client TLS for connecting to proxy
-	cmd.Flags().StringVar(&grpcProxyListenCert, "cert-file", "", "identify secure connections to the proxy using this TLS certificate file")
-	cmd.Flags().StringVar(&grpcProxyListenKey, "key-file", "", "identify secure connections to the proxy using this TLS key file")
-	cmd.Flags().StringVar(&grpcProxyListenCA, "trusted-ca-file", "", "verify certificates of TLS-enabled secure proxy using this CA bundle")
-	cmd.Flags().BoolVar(&grpcProxyListenAutoTLS, "auto-tls", false, "proxy TLS using generated certificates")
-	cmd.Flags().StringVar(&grpcProxyListenCRL, "client-crl-file", "", "proxy client certificate revocation list file.")
-
-	// experimental flags
-	cmd.Flags().BoolVar(&grpcProxyEnableOrdering, "experimental-serializable-ordering", false, "Ensure serializable reads have monotonically increasing store revisions across endpoints.")
-	cmd.Flags().StringVar(&grpcProxyLeasing, "experimental-leasing-prefix", "", "leasing metadata prefix for disconnected linearized reads.")
-
-	cmd.Flags().BoolVar(&grpcProxyDebug, "debug", false, "Enable debug-level logging for grpc-proxy.")
-
-	return &cmd
-}
-
-func startGRPCProxy(cmd *cobra.Command, args []string) {
-	checkArgs()
-
-	capnslog.SetGlobalLogLevel(capnslog.INFO)
-	if grpcProxyDebug {
-		capnslog.SetGlobalLogLevel(capnslog.DEBUG)
-		grpc.EnableTracing = true
-		// enable info, warning, error
-		grpclog.SetLoggerV2(grpclog.NewLoggerV2(os.Stderr, os.Stderr, os.Stderr))
-	} else {
-		// only discard info
-		grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, os.Stderr, os.Stderr))
-	}
-
-	tlsinfo := newTLS(grpcProxyListenCA, grpcProxyListenCert, grpcProxyListenKey)
-	if tlsinfo == nil && grpcProxyListenAutoTLS {
-		host := []string{"https://" + grpcProxyListenAddr}
-		dir := filepath.Join(grpcProxyDataDir, "fixtures", "proxy")
-		autoTLS, err := transport.SelfCert(dir, host)
-		if err != nil {
-			plog.Fatal(err)
-		}
-		tlsinfo = &autoTLS
-	}
-	if tlsinfo != nil {
-		plog.Infof("ServerTLS: %s", tlsinfo)
-	}
-	m := mustListenCMux(tlsinfo)
-
-	grpcl := m.Match(cmux.HTTP2())
-	defer func() {
-		grpcl.Close()
-		plog.Infof("stopping listening for grpc-proxy client requests on %s", grpcProxyListenAddr)
-	}()
-
-	client := mustNewClient()
-
-	srvhttp, httpl := mustHTTPListener(m, tlsinfo, client)
-	errc := make(chan error)
-	go func() { errc <- newGRPCProxyServer(client).Serve(grpcl) }()
-	go func() { errc <- srvhttp.Serve(httpl) }()
-	go func() { errc <- m.Serve() }()
-	if len(grpcProxyMetricsListenAddr) > 0 {
-		mhttpl := mustMetricsListener(tlsinfo)
-		go func() {
-			mux := http.NewServeMux()
-			etcdhttp.HandlePrometheus(mux)
-			grpcproxy.HandleHealth(mux, client)
-			plog.Fatal(http.Serve(mhttpl, mux))
-		}()
-	}
-
-	// grpc-proxy is initialized, ready to serve
-	notifySystemd()
-
-	fmt.Fprintln(os.Stderr, <-errc)
-	os.Exit(1)
-}
-
-func checkArgs() {
-	if grpcProxyResolverPrefix != "" && grpcProxyResolverTTL < 1 {
-		fmt.Fprintln(os.Stderr, fmt.Errorf("invalid resolver-ttl %d", grpcProxyResolverTTL))
-		os.Exit(1)
-	}
-	if grpcProxyResolverPrefix == "" && grpcProxyResolverTTL > 0 {
-		fmt.Fprintln(os.Stderr, fmt.Errorf("invalid resolver-prefix %q", grpcProxyResolverPrefix))
-		os.Exit(1)
-	}
-	if grpcProxyResolverPrefix != "" && grpcProxyResolverTTL > 0 && grpcProxyAdvertiseClientURL == "" {
-		fmt.Fprintln(os.Stderr, fmt.Errorf("invalid advertise-client-url %q", grpcProxyAdvertiseClientURL))
-		os.Exit(1)
-	}
-}
-
-func mustNewClient() *clientv3.Client {
-	srvs := discoverEndpoints(grpcProxyDNSCluster, grpcProxyCA, grpcProxyInsecureDiscovery)
-	eps := srvs.Endpoints
-	if len(eps) == 0 {
-		eps = grpcProxyEndpoints
-	}
-	cfg, err := newClientCfg(eps)
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-	cfg.DialOptions = append(cfg.DialOptions,
-		grpc.WithUnaryInterceptor(grpcproxy.AuthUnaryClientInterceptor))
-	cfg.DialOptions = append(cfg.DialOptions,
-		grpc.WithStreamInterceptor(grpcproxy.AuthStreamClientInterceptor))
-	client, err := clientv3.New(*cfg)
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-	return client
-}
-
-func newClientCfg(eps []string) (*clientv3.Config, error) {
-	// set tls if any one tls option set
-	cfg := clientv3.Config{
-		Endpoints:   eps,
-		DialTimeout: 5 * time.Second,
-	}
-
-	if grpcMaxCallSendMsgSize > 0 {
-		cfg.MaxCallSendMsgSize = grpcMaxCallSendMsgSize
-	}
-	if grpcMaxCallRecvMsgSize > 0 {
-		cfg.MaxCallRecvMsgSize = grpcMaxCallRecvMsgSize
-	}
-
-	tls := newTLS(grpcProxyCA, grpcProxyCert, grpcProxyKey)
-	if tls == nil && grpcProxyInsecureSkipTLSVerify {
-		tls = &transport.TLSInfo{}
-	}
-	if tls != nil {
-		clientTLS, err := tls.ClientConfig()
-		if err != nil {
-			return nil, err
-		}
-		clientTLS.InsecureSkipVerify = grpcProxyInsecureSkipTLSVerify
-		cfg.TLS = clientTLS
-		plog.Infof("ClientTLS: %s", tls)
-	}
-	return &cfg, nil
-}
-
-func newTLS(ca, cert, key string) *transport.TLSInfo {
-	if ca == "" && cert == "" && key == "" {
-		return nil
-	}
-	return &transport.TLSInfo{CAFile: ca, CertFile: cert, KeyFile: key}
-}
-
-func mustListenCMux(tlsinfo *transport.TLSInfo) cmux.CMux {
-	l, err := net.Listen("tcp", grpcProxyListenAddr)
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-
-	if l, err = transport.NewKeepAliveListener(l, "tcp", nil); err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-	if tlsinfo != nil {
-		tlsinfo.CRLFile = grpcProxyListenCRL
-		if l, err = transport.NewTLSListener(l, tlsinfo); err != nil {
-			plog.Fatal(err)
-		}
-	}
-
-	plog.Infof("listening for grpc-proxy client requests on %s", grpcProxyListenAddr)
-	return cmux.New(l)
-}
-
-func newGRPCProxyServer(client *clientv3.Client) *grpc.Server {
-	if grpcProxyEnableOrdering {
-		vf := ordering.NewOrderViolationSwitchEndpointClosure(*client)
-		client.KV = ordering.NewKV(client.KV, vf)
-		plog.Infof("waiting for linearized read from cluster to recover ordering")
-		for {
-			_, err := client.KV.Get(context.TODO(), "_", clientv3.WithKeysOnly())
-			if err == nil {
-				break
-			}
-			plog.Warningf("ordering recovery failed, retrying in 1s (%v)", err)
-			time.Sleep(time.Second)
-		}
-	}
-
-	if len(grpcProxyNamespace) > 0 {
-		client.KV = namespace.NewKV(client.KV, grpcProxyNamespace)
-		client.Watcher = namespace.NewWatcher(client.Watcher, grpcProxyNamespace)
-		client.Lease = namespace.NewLease(client.Lease, grpcProxyNamespace)
-	}
-
-	if len(grpcProxyLeasing) > 0 {
-		client.KV, _, _ = leasing.NewKV(client, grpcProxyLeasing)
-	}
-
-	kvp, _ := grpcproxy.NewKvProxy(client)
-	watchp, _ := grpcproxy.NewWatchProxy(client)
-	if grpcProxyResolverPrefix != "" {
-		grpcproxy.Register(client, grpcProxyResolverPrefix, grpcProxyAdvertiseClientURL, grpcProxyResolverTTL)
-	}
-	clusterp, _ := grpcproxy.NewClusterProxy(client, grpcProxyAdvertiseClientURL, grpcProxyResolverPrefix)
-	leasep, _ := grpcproxy.NewLeaseProxy(client)
-	mainp := grpcproxy.NewMaintenanceProxy(client)
-	authp := grpcproxy.NewAuthProxy(client)
-	electionp := grpcproxy.NewElectionProxy(client)
-	lockp := grpcproxy.NewLockProxy(client)
-
-	server := grpc.NewServer(
-		grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
-		grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
-		grpc.MaxConcurrentStreams(math.MaxUint32),
-	)
-
-	pb.RegisterKVServer(server, kvp)
-	pb.RegisterWatchServer(server, watchp)
-	pb.RegisterClusterServer(server, clusterp)
-	pb.RegisterLeaseServer(server, leasep)
-	pb.RegisterMaintenanceServer(server, mainp)
-	pb.RegisterAuthServer(server, authp)
-	v3electionpb.RegisterElectionServer(server, electionp)
-	v3lockpb.RegisterLockServer(server, lockp)
-
-	// set zero values for metrics registered for this grpc server
-	grpc_prometheus.Register(server)
-
-	return server
-}
-
-func mustHTTPListener(m cmux.CMux, tlsinfo *transport.TLSInfo, c *clientv3.Client) (*http.Server, net.Listener) {
-	httpmux := http.NewServeMux()
-	httpmux.HandleFunc("/", http.NotFound)
-	etcdhttp.HandlePrometheus(httpmux)
-	grpcproxy.HandleHealth(httpmux, c)
-	if grpcProxyEnablePprof {
-		for p, h := range debugutil.PProfHandlers() {
-			httpmux.Handle(p, h)
-		}
-		plog.Infof("pprof is enabled under %s", debugutil.HTTPPrefixPProf)
-	}
-	srvhttp := &http.Server{Handler: httpmux}
-
-	if tlsinfo == nil {
-		return srvhttp, m.Match(cmux.HTTP1())
-	}
-
-	srvTLS, err := tlsinfo.ServerConfig()
-	if err != nil {
-		plog.Fatalf("could not setup TLS (%v)", err)
-	}
-	srvhttp.TLSConfig = srvTLS
-	return srvhttp, m.Match(cmux.Any())
-}
-
-func mustMetricsListener(tlsinfo *transport.TLSInfo) net.Listener {
-	murl, err := url.Parse(grpcProxyMetricsListenAddr)
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "cannot parse %q", grpcProxyMetricsListenAddr)
-		os.Exit(1)
-	}
-	ml, err := transport.NewListener(murl.Host, murl.Scheme, tlsinfo)
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-	plog.Info("grpc-proxy: listening for metrics on ", murl.String())
-	return ml
-}
diff --git a/vendor/github.com/coreos/etcd/etcdmain/help.go b/vendor/github.com/coreos/etcd/etcdmain/help.go
deleted file mode 100644
index c64dab3..0000000
--- a/vendor/github.com/coreos/etcd/etcdmain/help.go
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdmain
-
-import (
-	"strconv"
-
-	"github.com/coreos/etcd/embed"
-)
-
-var (
-	usageline = `usage: etcd [flags]
-       start an etcd server
-
-       etcd --version
-       show the version of etcd
-
-       etcd -h | --help
-       show the help information about etcd
-
-       etcd --config-file
-       path to the server configuration file
-
-       etcd gateway
-       run the stateless pass-through etcd TCP connection forwarding proxy
-
-       etcd grpc-proxy
-       run the stateless etcd v3 gRPC L7 reverse proxy
-	`
-	flagsline = `
-member flags:
-
-	--name 'default'
-		human-readable name for this member.
-	--data-dir '${name}.etcd'
-		path to the data directory.
-	--wal-dir ''
-		path to the dedicated wal directory.
-	--snapshot-count '100000'
-		number of committed transactions to trigger a snapshot to disk.
-	--heartbeat-interval '100'
-		time (in milliseconds) of a heartbeat interval.
-	--election-timeout '1000'
-		time (in milliseconds) for an election to timeout. See tuning documentation for details.
-	--initial-election-tick-advance 'true'
-		whether to fast-forward initial election ticks on boot for faster election.
-	--listen-peer-urls 'http://localhost:2380'
-		list of URLs to listen on for peer traffic.
-	--listen-client-urls 'http://localhost:2379'
-		list of URLs to listen on for client traffic.
-	--max-snapshots '` + strconv.Itoa(embed.DefaultMaxSnapshots) + `'
-		maximum number of snapshot files to retain (0 is unlimited).
-	--max-wals '` + strconv.Itoa(embed.DefaultMaxWALs) + `'
-		maximum number of wal files to retain (0 is unlimited).
-	--cors ''
-		comma-separated whitelist of origins for CORS (cross-origin resource sharing).
-	--quota-backend-bytes '0'
-		raise alarms when backend size exceeds the given quota (0 defaults to low space quota).
-	--max-txn-ops '128'
-		maximum number of operations permitted in a transaction.
-	--max-request-bytes '1572864'
-		maximum client request size in bytes the server will accept.
-	--grpc-keepalive-min-time '5s'
-		minimum duration interval that a client should wait before pinging server.
-	--grpc-keepalive-interval '2h'
-		frequency duration of server-to-client ping to check if a connection is alive (0 to disable).
-	--grpc-keepalive-timeout '20s'
-		additional duration of wait before closing a non-responsive connection (0 to disable).
-
-clustering flags:
-
-	--initial-advertise-peer-urls 'http://localhost:2380'
-		list of this member's peer URLs to advertise to the rest of the cluster.
-	--initial-cluster 'default=http://localhost:2380'
-		initial cluster configuration for bootstrapping.
-	--initial-cluster-state 'new'
-		initial cluster state ('new' or 'existing').
-	--initial-cluster-token 'etcd-cluster'
-		initial cluster token for the etcd cluster during bootstrap.
-		Specifying this can protect you from unintended cross-cluster interaction when running multiple clusters.
-	--advertise-client-urls 'http://localhost:2379'
-		list of this member's client URLs to advertise to the public.
-		The client URLs advertised should be accessible to machines that talk to etcd cluster. etcd client libraries parse these URLs to connect to the cluster.
-	--discovery ''
-		discovery URL used to bootstrap the cluster.
-	--discovery-fallback 'proxy'
-		expected behavior ('exit' or 'proxy') when discovery services fails.
-		"proxy" supports v2 API only.
-	--discovery-proxy ''
-		HTTP proxy to use for traffic to discovery service.
-	--discovery-srv ''
-		dns srv domain used to bootstrap the cluster.
-	--strict-reconfig-check '` + strconv.FormatBool(embed.DefaultStrictReconfigCheck) + `'
-		reject reconfiguration requests that would cause quorum loss.
-	--auto-compaction-retention '0'
-		auto compaction retention length. 0 means disable auto compaction.
-	--auto-compaction-mode 'periodic'
-		interpret 'auto-compaction-retention' one of: periodic|revision. 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. '5m'). 'revision' for revision number based retention.
-	--enable-v2 '` + strconv.FormatBool(embed.DefaultEnableV2) + `'
-		Accept etcd V2 client requests.
-
-proxy flags:
-	"proxy" supports v2 API only.
-
-	--proxy 'off'
-		proxy mode setting ('off', 'readonly' or 'on').
-	--proxy-failure-wait 5000
-		time (in milliseconds) an endpoint will be held in a failed state.
-	--proxy-refresh-interval 30000
-		time (in milliseconds) of the endpoints refresh interval.
-	--proxy-dial-timeout 1000
-		time (in milliseconds) for a dial to timeout.
-	--proxy-write-timeout 5000
-		time (in milliseconds) for a write to timeout.
-	--proxy-read-timeout 0
-		time (in milliseconds) for a read to timeout.
-
-
-security flags:
-
-	--ca-file '' [DEPRECATED]
-		path to the client server TLS CA file. '-ca-file ca.crt' could be replaced by '-trusted-ca-file ca.crt -client-cert-auth' and etcd will perform the same.
-	--cert-file ''
-		path to the client server TLS cert file.
-	--key-file ''
-		path to the client server TLS key file.
-	--client-cert-auth 'false'
-		enable client cert authentication.
-	--client-crl-file ''
-		path to the client certificate revocation list file.
-	--trusted-ca-file ''
-		path to the client server TLS trusted CA cert file.
-	--auto-tls 'false'
-		client TLS using generated certificates.
-	--peer-ca-file '' [DEPRECATED]
-		path to the peer server TLS CA file. '-peer-ca-file ca.crt' could be replaced by '-peer-trusted-ca-file ca.crt -peer-client-cert-auth' and etcd will perform the same.
-	--peer-cert-file ''
-		path to the peer server TLS cert file.
-	--peer-key-file ''
-		path to the peer server TLS key file.
-	--peer-client-cert-auth 'false'
-		enable peer client cert authentication.
-	--peer-trusted-ca-file ''
-		path to the peer server TLS trusted CA file.
-	--peer-cert-allowed-cn ''
-		Required CN for client certs connecting to the peer endpoint.
-	--peer-auto-tls 'false'
-		peer TLS using self-generated certificates if --peer-key-file and --peer-cert-file are not provided.
-	--peer-crl-file ''
-		path to the peer certificate revocation list file.
-	--cipher-suites ''
-		comma-separated list of supported TLS cipher suites between client/server and peers (empty will be auto-populated by Go).
-
-logging flags
-
-	--debug 'false'
-		enable debug-level logging for etcd.
-	--log-package-levels ''
-		specify a particular log level for each etcd package (eg: 'etcdmain=CRITICAL,etcdserver=DEBUG').
-	--log-output 'default'
-		specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.
-
-unsafe flags:
-
-Please be CAUTIOUS when using unsafe flags because it will break the guarantees
-given by the consensus protocol.
-
-	--force-new-cluster 'false'
-		force to create a new one-member cluster.
-
-profiling flags:
-	--enable-pprof 'false'
-		Enable runtime profiling data via HTTP server. Address is at client URL + "/debug/pprof/"
-	--metrics 'basic'
-		Set level of detail for exported metrics, specify 'extensive' to include histogram metrics.
-	--listen-metrics-urls ''
-		List of URLs to listen on for metrics.
-
-auth flags:
-	--auth-token 'simple'
-		Specify a v3 authentication token type and its options ('simple' or 'jwt').
-
-experimental flags:
-	--experimental-initial-corrupt-check 'false'
-		enable to check data corruption before serving any client/peer traffic.
-	--experimental-corrupt-check-time '0s'
-		duration of time between cluster corruption check passes.
-	--experimental-enable-v2v3 ''
-		serve v2 requests through the v3 backend under a given prefix.
-`
-)
diff --git a/vendor/github.com/coreos/etcd/etcdmain/main.go b/vendor/github.com/coreos/etcd/etcdmain/main.go
deleted file mode 100644
index 06bbae5..0000000
--- a/vendor/github.com/coreos/etcd/etcdmain/main.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdmain
-
-import (
-	"fmt"
-	"os"
-	"strings"
-
-	"github.com/coreos/go-systemd/daemon"
-	systemdutil "github.com/coreos/go-systemd/util"
-)
-
-func Main() {
-	checkSupportArch()
-
-	if len(os.Args) > 1 {
-		cmd := os.Args[1]
-		if covArgs := os.Getenv("ETCDCOV_ARGS"); len(covArgs) > 0 {
-			args := strings.Split(os.Getenv("ETCDCOV_ARGS"), "\xe7\xcd")[1:]
-			rootCmd.SetArgs(args)
-			cmd = "grpc-proxy"
-		}
-		switch cmd {
-		case "gateway", "grpc-proxy":
-			if err := rootCmd.Execute(); err != nil {
-				fmt.Fprint(os.Stderr, err)
-				os.Exit(1)
-			}
-			return
-		}
-	}
-
-	startEtcdOrProxyV2()
-}
-
-func notifySystemd() {
-	if !systemdutil.IsRunningSystemd() {
-		return
-	}
-	sent, err := daemon.SdNotify(false, "READY=1")
-	if err != nil {
-		plog.Errorf("failed to notify systemd for readiness: %v", err)
-	}
-	if !sent {
-		plog.Errorf("forgot to set Type=notify in systemd service file?")
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdmain/util.go b/vendor/github.com/coreos/etcd/etcdmain/util.go
deleted file mode 100644
index 9657271..0000000
--- a/vendor/github.com/coreos/etcd/etcdmain/util.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdmain
-
-import (
-	"fmt"
-	"os"
-
-	"github.com/coreos/etcd/pkg/srv"
-	"github.com/coreos/etcd/pkg/transport"
-)
-
-func discoverEndpoints(dns string, ca string, insecure bool) (s srv.SRVClients) {
-	if dns == "" {
-		return s
-	}
-	srvs, err := srv.GetClient("etcd-client", dns)
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-	endpoints := srvs.Endpoints
-	plog.Infof("discovered the cluster %s from %s", endpoints, dns)
-	if insecure {
-		return *srvs
-	}
-	// confirm TLS connections are good
-	tlsInfo := transport.TLSInfo{
-		TrustedCAFile: ca,
-		ServerName:    dns,
-	}
-	plog.Infof("validating discovered endpoints %v", endpoints)
-	endpoints, err = transport.ValidateSecureEndpoints(tlsInfo, endpoints)
-	if err != nil {
-		plog.Warningf("%v", err)
-	}
-	plog.Infof("using discovered endpoints %v", endpoints)
-
-	// map endpoints back to SRVClients struct with SRV data
-	eps := make(map[string]struct{})
-	for _, ep := range endpoints {
-		eps[ep] = struct{}{}
-	}
-	for i := range srvs.Endpoints {
-		if _, ok := eps[srvs.Endpoints[i]]; !ok {
-			continue
-		}
-		s.Endpoints = append(s.Endpoints, srvs.Endpoints[i])
-		s.SRVs = append(s.SRVs, srvs.SRVs[i])
-	}
-
-	return s
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/capability.go b/vendor/github.com/coreos/etcd/etcdserver/api/capability.go
deleted file mode 100644
index eb34383..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/capability.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package api
-
-import (
-	"sync"
-
-	"github.com/coreos/etcd/version"
-	"github.com/coreos/go-semver/semver"
-	"github.com/coreos/pkg/capnslog"
-)
-
-type Capability string
-
-const (
-	AuthCapability  Capability = "auth"
-	V3rpcCapability Capability = "v3rpc"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/api")
-
-	// capabilityMaps is a static map of version to capability map.
-	capabilityMaps = map[string]map[Capability]bool{
-		"3.0.0": {AuthCapability: true, V3rpcCapability: true},
-		"3.1.0": {AuthCapability: true, V3rpcCapability: true},
-		"3.2.0": {AuthCapability: true, V3rpcCapability: true},
-		"3.3.0": {AuthCapability: true, V3rpcCapability: true},
-	}
-
-	enableMapMu sync.RWMutex
-	// enabledMap points to a map in capabilityMaps
-	enabledMap map[Capability]bool
-
-	curVersion *semver.Version
-)
-
-func init() {
-	enabledMap = map[Capability]bool{
-		AuthCapability:  true,
-		V3rpcCapability: true,
-	}
-}
-
-// UpdateCapability updates the enabledMap when the cluster version increases.
-func UpdateCapability(v *semver.Version) {
-	if v == nil {
-		// if recovered but version was never set by cluster
-		return
-	}
-	enableMapMu.Lock()
-	if curVersion != nil && !curVersion.LessThan(*v) {
-		enableMapMu.Unlock()
-		return
-	}
-	curVersion = v
-	enabledMap = capabilityMaps[curVersion.String()]
-	enableMapMu.Unlock()
-	plog.Infof("enabled capabilities for version %s", version.Cluster(v.String()))
-}
-
-func IsCapabilityEnabled(c Capability) bool {
-	enableMapMu.RLock()
-	defer enableMapMu.RUnlock()
-	if enabledMap == nil {
-		return false
-	}
-	return enabledMap[c]
-}
-
-func EnableCapability(c Capability) {
-	enableMapMu.Lock()
-	defer enableMapMu.Unlock()
-	enabledMap[c] = true
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/cluster.go b/vendor/github.com/coreos/etcd/etcdserver/api/cluster.go
deleted file mode 100644
index 654c258..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/cluster.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package api
-
-import (
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/pkg/types"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-// Cluster is an interface representing a collection of members in one etcd cluster.
-type Cluster interface {
-	// ID returns the cluster ID
-	ID() types.ID
-	// ClientURLs returns an aggregate set of all URLs on which this
-	// cluster is listening for client requests
-	ClientURLs() []string
-	// Members returns a slice of members sorted by their ID
-	Members() []*membership.Member
-	// Member retrieves a particular member based on ID, or nil if the
-	// member does not exist in the cluster
-	Member(id types.ID) *membership.Member
-	// Version is the cluster-wide minimum major.minor version.
-	Version() *semver.Version
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/doc.go b/vendor/github.com/coreos/etcd/etcdserver/api/doc.go
deleted file mode 100644
index f44881b..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package api manages the capabilities and features that are exposed to clients by the etcd cluster.
-package api
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/base.go b/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/base.go
deleted file mode 100644
index f0d3b0b..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/base.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdhttp
-
-import (
-	"encoding/json"
-	"expvar"
-	"fmt"
-	"net/http"
-	"strings"
-
-	etcdErr "github.com/coreos/etcd/error"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api"
-	"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
-	"github.com/coreos/etcd/pkg/logutil"
-	"github.com/coreos/etcd/version"
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/api/etcdhttp")
-	mlog = logutil.NewMergeLogger(plog)
-)
-
-const (
-	configPath  = "/config"
-	varsPath    = "/debug/vars"
-	versionPath = "/version"
-)
-
-// HandleBasic adds handlers to a mux for serving JSON etcd client requests
-// that do not access the v2 store.
-func HandleBasic(mux *http.ServeMux, server etcdserver.ServerPeer) {
-	mux.HandleFunc(varsPath, serveVars)
-	mux.HandleFunc(configPath+"/local/log", logHandleFunc)
-	HandleMetricsHealth(mux, server)
-	mux.HandleFunc(versionPath, versionHandler(server.Cluster(), serveVersion))
-}
-
-func versionHandler(c api.Cluster, fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		v := c.Version()
-		if v != nil {
-			fn(w, r, v.String())
-		} else {
-			fn(w, r, "not_decided")
-		}
-	}
-}
-
-func serveVersion(w http.ResponseWriter, r *http.Request, clusterV string) {
-	if !allowMethod(w, r, "GET") {
-		return
-	}
-	vs := version.Versions{
-		Server:  version.Version,
-		Cluster: clusterV,
-	}
-
-	w.Header().Set("Content-Type", "application/json")
-	b, err := json.Marshal(&vs)
-	if err != nil {
-		plog.Panicf("cannot marshal versions to json (%v)", err)
-	}
-	w.Write(b)
-}
-
-func logHandleFunc(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r, "PUT") {
-		return
-	}
-
-	in := struct{ Level string }{}
-
-	d := json.NewDecoder(r.Body)
-	if err := d.Decode(&in); err != nil {
-		WriteError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid json body"))
-		return
-	}
-
-	logl, err := capnslog.ParseLevel(strings.ToUpper(in.Level))
-	if err != nil {
-		WriteError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid log level "+in.Level))
-		return
-	}
-
-	plog.Noticef("globalLogLevel set to %q", logl.String())
-	capnslog.SetGlobalLogLevel(logl)
-	w.WriteHeader(http.StatusNoContent)
-}
-
-func serveVars(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r, "GET") {
-		return
-	}
-
-	w.Header().Set("Content-Type", "application/json; charset=utf-8")
-	fmt.Fprintf(w, "{\n")
-	first := true
-	expvar.Do(func(kv expvar.KeyValue) {
-		if !first {
-			fmt.Fprintf(w, ",\n")
-		}
-		first = false
-		fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value)
-	})
-	fmt.Fprintf(w, "\n}\n")
-}
-
-func allowMethod(w http.ResponseWriter, r *http.Request, m string) bool {
-	if m == r.Method {
-		return true
-	}
-	w.Header().Set("Allow", m)
-	http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-	return false
-}
-
-// WriteError logs and writes the given Error to the ResponseWriter
-// If Error is an etcdErr, it is rendered to the ResponseWriter
-// Otherwise, it is assumed to be a StatusInternalServerError
-func WriteError(w http.ResponseWriter, r *http.Request, err error) {
-	if err == nil {
-		return
-	}
-	switch e := err.(type) {
-	case *etcdErr.Error:
-		e.WriteTo(w)
-	case *httptypes.HTTPError:
-		if et := e.WriteTo(w); et != nil {
-			plog.Debugf("error writing HTTPError (%v) to %s", et, r.RemoteAddr)
-		}
-	default:
-		switch err {
-		case etcdserver.ErrTimeoutDueToLeaderFail, etcdserver.ErrTimeoutDueToConnectionLost, etcdserver.ErrNotEnoughStartedMembers, etcdserver.ErrUnhealthy:
-			mlog.MergeError(err)
-		default:
-			mlog.MergeErrorf("got unexpected response error (%v)", err)
-		}
-		herr := httptypes.NewHTTPError(http.StatusInternalServerError, "Internal Server Error")
-		if et := herr.WriteTo(w); et != nil {
-			plog.Debugf("error writing HTTPError (%v) to %s", et, r.RemoteAddr)
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/doc.go b/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/doc.go
deleted file mode 100644
index a03b626..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package etcdhttp implements HTTP transportation layer for etcdserver.
-package etcdhttp
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/metrics.go
deleted file mode 100644
index aeaf350..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/metrics.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdhttp
-
-import (
-	"context"
-	"encoding/json"
-	"net/http"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/raft"
-
-	"github.com/prometheus/client_golang/prometheus"
-	"github.com/prometheus/client_golang/prometheus/promhttp"
-)
-
-const (
-	pathMetrics = "/metrics"
-	PathHealth  = "/health"
-)
-
-// HandleMetricsHealth registers metrics and health handlers.
-func HandleMetricsHealth(mux *http.ServeMux, srv etcdserver.ServerV2) {
-	mux.Handle(pathMetrics, promhttp.Handler())
-	mux.Handle(PathHealth, NewHealthHandler(func() Health { return checkHealth(srv) }))
-}
-
-// HandlePrometheus registers prometheus handler on '/metrics'.
-func HandlePrometheus(mux *http.ServeMux) {
-	mux.Handle(pathMetrics, promhttp.Handler())
-}
-
-// NewHealthHandler handles '/health' requests.
-func NewHealthHandler(hfunc func() Health) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		if r.Method != http.MethodGet {
-			w.Header().Set("Allow", http.MethodGet)
-			http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-			return
-		}
-		h := hfunc()
-		d, _ := json.Marshal(h)
-		if h.Health != "true" {
-			http.Error(w, string(d), http.StatusServiceUnavailable)
-			return
-		}
-		w.WriteHeader(http.StatusOK)
-		w.Write(d)
-	}
-}
-
-var (
-	healthSuccess = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "health_success",
-		Help:      "The total number of successful health checks",
-	})
-	healthFailed = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "health_failures",
-		Help:      "The total number of failed health checks",
-	})
-)
-
-func init() {
-	prometheus.MustRegister(healthSuccess)
-	prometheus.MustRegister(healthFailed)
-}
-
-// Health defines etcd server health status.
-// TODO: remove manual parsing in etcdctl cluster-health
-type Health struct {
-	Health string `json:"health"`
-}
-
-// TODO: server NOSPACE, etcdserver.ErrNoLeader in health API
-
-func checkHealth(srv etcdserver.ServerV2) Health {
-	h := Health{Health: "true"}
-
-	as := srv.Alarms()
-	if len(as) > 0 {
-		h.Health = "false"
-	}
-
-	if h.Health == "true" {
-		if uint64(srv.Leader()) == raft.None {
-			h.Health = "false"
-		}
-	}
-
-	if h.Health == "true" {
-		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
-		_, err := srv.Do(ctx, etcdserverpb.Request{Method: "QGET"})
-		cancel()
-		if err != nil {
-			h.Health = "false"
-		}
-	}
-
-	if h.Health == "true" {
-		healthSuccess.Inc()
-	} else {
-		healthFailed.Inc()
-	}
-	return h
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/peer.go b/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/peer.go
deleted file mode 100644
index 0a9213b..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/etcdhttp/peer.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdhttp
-
-import (
-	"encoding/json"
-	"net/http"
-
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api"
-	"github.com/coreos/etcd/lease/leasehttp"
-	"github.com/coreos/etcd/rafthttp"
-)
-
-const (
-	peerMembersPrefix = "/members"
-)
-
-// NewPeerHandler generates an http.Handler to handle etcd peer requests.
-func NewPeerHandler(s etcdserver.ServerPeer) http.Handler {
-	return newPeerHandler(s.Cluster(), s.RaftHandler(), s.LeaseHandler())
-}
-
-func newPeerHandler(cluster api.Cluster, raftHandler http.Handler, leaseHandler http.Handler) http.Handler {
-	mh := &peerMembersHandler{
-		cluster: cluster,
-	}
-
-	mux := http.NewServeMux()
-	mux.HandleFunc("/", http.NotFound)
-	mux.Handle(rafthttp.RaftPrefix, raftHandler)
-	mux.Handle(rafthttp.RaftPrefix+"/", raftHandler)
-	mux.Handle(peerMembersPrefix, mh)
-	if leaseHandler != nil {
-		mux.Handle(leasehttp.LeasePrefix, leaseHandler)
-		mux.Handle(leasehttp.LeaseInternalPrefix, leaseHandler)
-	}
-	mux.HandleFunc(versionPath, versionHandler(cluster, serveVersion))
-	return mux
-}
-
-type peerMembersHandler struct {
-	cluster api.Cluster
-}
-
-func (h *peerMembersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r, "GET") {
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", h.cluster.ID().String())
-
-	if r.URL.Path != peerMembersPrefix {
-		http.Error(w, "bad path", http.StatusBadRequest)
-		return
-	}
-	ms := h.cluster.Members()
-	w.Header().Set("Content-Type", "application/json")
-	if err := json.NewEncoder(w).Encode(ms); err != nil {
-		plog.Warningf("failed to encode members response (%v)", err)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/capability.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/capability.go
deleted file mode 100644
index fa0bcca..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/capability.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2http
-
-import (
-	"fmt"
-	"net/http"
-
-	"github.com/coreos/etcd/etcdserver/api"
-	"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
-)
-
-func capabilityHandler(c api.Capability, fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		if !api.IsCapabilityEnabled(c) {
-			notCapable(w, r, c)
-			return
-		}
-		fn(w, r)
-	}
-}
-
-func notCapable(w http.ResponseWriter, r *http.Request, c api.Capability) {
-	herr := httptypes.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Not capable of accessing %s feature during rolling upgrades.", c))
-	if err := herr.WriteTo(w); err != nil {
-		plog.Debugf("error writing HTTPError (%v) to %s", err, r.RemoteAddr)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client.go
deleted file mode 100644
index 6aaf3db..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client.go
+++ /dev/null
@@ -1,719 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2http
-
-import (
-	"context"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"net/url"
-	"path"
-	"strconv"
-	"strings"
-	"time"
-
-	etcdErr "github.com/coreos/etcd/error"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api"
-	"github.com/coreos/etcd/etcdserver/api/etcdhttp"
-	"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
-	"github.com/coreos/etcd/etcdserver/auth"
-	"github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/etcdserver/stats"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/store"
-
-	"github.com/jonboulle/clockwork"
-)
-
-const (
-	authPrefix     = "/v2/auth"
-	keysPrefix     = "/v2/keys"
-	machinesPrefix = "/v2/machines"
-	membersPrefix  = "/v2/members"
-	statsPrefix    = "/v2/stats"
-)
-
-// NewClientHandler generates a muxed http.Handler with the given parameters to serve etcd client requests.
-func NewClientHandler(server etcdserver.ServerPeer, timeout time.Duration) http.Handler {
-	mux := http.NewServeMux()
-	etcdhttp.HandleBasic(mux, server)
-	handleV2(mux, server, timeout)
-	return requestLogger(mux)
-}
-
-func handleV2(mux *http.ServeMux, server etcdserver.ServerV2, timeout time.Duration) {
-	sec := auth.NewStore(server, timeout)
-	kh := &keysHandler{
-		sec:                   sec,
-		server:                server,
-		cluster:               server.Cluster(),
-		timeout:               timeout,
-		clientCertAuthEnabled: server.ClientCertAuthEnabled(),
-	}
-
-	sh := &statsHandler{
-		stats: server,
-	}
-
-	mh := &membersHandler{
-		sec:     sec,
-		server:  server,
-		cluster: server.Cluster(),
-		timeout: timeout,
-		clock:   clockwork.NewRealClock(),
-		clientCertAuthEnabled: server.ClientCertAuthEnabled(),
-	}
-
-	mah := &machinesHandler{cluster: server.Cluster()}
-
-	sech := &authHandler{
-		sec:                   sec,
-		cluster:               server.Cluster(),
-		clientCertAuthEnabled: server.ClientCertAuthEnabled(),
-	}
-	mux.HandleFunc("/", http.NotFound)
-	mux.Handle(keysPrefix, kh)
-	mux.Handle(keysPrefix+"/", kh)
-	mux.HandleFunc(statsPrefix+"/store", sh.serveStore)
-	mux.HandleFunc(statsPrefix+"/self", sh.serveSelf)
-	mux.HandleFunc(statsPrefix+"/leader", sh.serveLeader)
-	mux.Handle(membersPrefix, mh)
-	mux.Handle(membersPrefix+"/", mh)
-	mux.Handle(machinesPrefix, mah)
-	handleAuth(mux, sech)
-}
-
-type keysHandler struct {
-	sec                   auth.Store
-	server                etcdserver.ServerV2
-	cluster               api.Cluster
-	timeout               time.Duration
-	clientCertAuthEnabled bool
-}
-
-func (h *keysHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "HEAD", "GET", "PUT", "POST", "DELETE") {
-		return
-	}
-
-	w.Header().Set("X-Etcd-Cluster-ID", h.cluster.ID().String())
-
-	ctx, cancel := context.WithTimeout(context.Background(), h.timeout)
-	defer cancel()
-	clock := clockwork.NewRealClock()
-	startTime := clock.Now()
-	rr, noValueOnSuccess, err := parseKeyRequest(r, clock)
-	if err != nil {
-		writeKeyError(w, err)
-		return
-	}
-	// The path must be valid at this point (we've parsed the request successfully).
-	if !hasKeyPrefixAccess(h.sec, r, r.URL.Path[len(keysPrefix):], rr.Recursive, h.clientCertAuthEnabled) {
-		writeKeyNoAuth(w)
-		return
-	}
-	if !rr.Wait {
-		reportRequestReceived(rr)
-	}
-	resp, err := h.server.Do(ctx, rr)
-	if err != nil {
-		err = trimErrorPrefix(err, etcdserver.StoreKeysPrefix)
-		writeKeyError(w, err)
-		reportRequestFailed(rr, err)
-		return
-	}
-	switch {
-	case resp.Event != nil:
-		if err := writeKeyEvent(w, resp, noValueOnSuccess); err != nil {
-			// Should never be reached
-			plog.Errorf("error writing event (%v)", err)
-		}
-		reportRequestCompleted(rr, resp, startTime)
-	case resp.Watcher != nil:
-		ctx, cancel := context.WithTimeout(context.Background(), defaultWatchTimeout)
-		defer cancel()
-		handleKeyWatch(ctx, w, resp, rr.Stream)
-	default:
-		writeKeyError(w, errors.New("received response with no Event/Watcher!"))
-	}
-}
-
-type machinesHandler struct {
-	cluster api.Cluster
-}
-
-func (h *machinesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET", "HEAD") {
-		return
-	}
-	endpoints := h.cluster.ClientURLs()
-	w.Write([]byte(strings.Join(endpoints, ", ")))
-}
-
-type membersHandler struct {
-	sec                   auth.Store
-	server                etcdserver.ServerV2
-	cluster               api.Cluster
-	timeout               time.Duration
-	clock                 clockwork.Clock
-	clientCertAuthEnabled bool
-}
-
-func (h *membersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET", "POST", "DELETE", "PUT") {
-		return
-	}
-	if !hasWriteRootAccess(h.sec, r, h.clientCertAuthEnabled) {
-		writeNoAuth(w, r)
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", h.cluster.ID().String())
-
-	ctx, cancel := context.WithTimeout(context.Background(), h.timeout)
-	defer cancel()
-
-	switch r.Method {
-	case "GET":
-		switch trimPrefix(r.URL.Path, membersPrefix) {
-		case "":
-			mc := newMemberCollection(h.cluster.Members())
-			w.Header().Set("Content-Type", "application/json")
-			if err := json.NewEncoder(w).Encode(mc); err != nil {
-				plog.Warningf("failed to encode members response (%v)", err)
-			}
-		case "leader":
-			id := h.server.Leader()
-			if id == 0 {
-				writeError(w, r, httptypes.NewHTTPError(http.StatusServiceUnavailable, "During election"))
-				return
-			}
-			m := newMember(h.cluster.Member(id))
-			w.Header().Set("Content-Type", "application/json")
-			if err := json.NewEncoder(w).Encode(m); err != nil {
-				plog.Warningf("failed to encode members response (%v)", err)
-			}
-		default:
-			writeError(w, r, httptypes.NewHTTPError(http.StatusNotFound, "Not found"))
-		}
-	case "POST":
-		req := httptypes.MemberCreateRequest{}
-		if ok := unmarshalRequest(r, &req, w); !ok {
-			return
-		}
-		now := h.clock.Now()
-		m := membership.NewMember("", req.PeerURLs, "", &now)
-		_, err := h.server.AddMember(ctx, *m)
-		switch {
-		case err == membership.ErrIDExists || err == membership.ErrPeerURLexists:
-			writeError(w, r, httptypes.NewHTTPError(http.StatusConflict, err.Error()))
-			return
-		case err != nil:
-			plog.Errorf("error adding member %s (%v)", m.ID, err)
-			writeError(w, r, err)
-			return
-		}
-		res := newMember(m)
-		w.Header().Set("Content-Type", "application/json")
-		w.WriteHeader(http.StatusCreated)
-		if err := json.NewEncoder(w).Encode(res); err != nil {
-			plog.Warningf("failed to encode members response (%v)", err)
-		}
-	case "DELETE":
-		id, ok := getID(r.URL.Path, w)
-		if !ok {
-			return
-		}
-		_, err := h.server.RemoveMember(ctx, uint64(id))
-		switch {
-		case err == membership.ErrIDRemoved:
-			writeError(w, r, httptypes.NewHTTPError(http.StatusGone, fmt.Sprintf("Member permanently removed: %s", id)))
-		case err == membership.ErrIDNotFound:
-			writeError(w, r, httptypes.NewHTTPError(http.StatusNotFound, fmt.Sprintf("No such member: %s", id)))
-		case err != nil:
-			plog.Errorf("error removing member %s (%v)", id, err)
-			writeError(w, r, err)
-		default:
-			w.WriteHeader(http.StatusNoContent)
-		}
-	case "PUT":
-		id, ok := getID(r.URL.Path, w)
-		if !ok {
-			return
-		}
-		req := httptypes.MemberUpdateRequest{}
-		if ok := unmarshalRequest(r, &req, w); !ok {
-			return
-		}
-		m := membership.Member{
-			ID:             id,
-			RaftAttributes: membership.RaftAttributes{PeerURLs: req.PeerURLs.StringSlice()},
-		}
-		_, err := h.server.UpdateMember(ctx, m)
-		switch {
-		case err == membership.ErrPeerURLexists:
-			writeError(w, r, httptypes.NewHTTPError(http.StatusConflict, err.Error()))
-		case err == membership.ErrIDNotFound:
-			writeError(w, r, httptypes.NewHTTPError(http.StatusNotFound, fmt.Sprintf("No such member: %s", id)))
-		case err != nil:
-			plog.Errorf("error updating member %s (%v)", m.ID, err)
-			writeError(w, r, err)
-		default:
-			w.WriteHeader(http.StatusNoContent)
-		}
-	}
-}
-
-type statsHandler struct {
-	stats stats.Stats
-}
-
-func (h *statsHandler) serveStore(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-	w.Header().Set("Content-Type", "application/json")
-	w.Write(h.stats.StoreStats())
-}
-
-func (h *statsHandler) serveSelf(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-	w.Header().Set("Content-Type", "application/json")
-	w.Write(h.stats.SelfStats())
-}
-
-func (h *statsHandler) serveLeader(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-	stats := h.stats.LeaderStats()
-	if stats == nil {
-		etcdhttp.WriteError(w, r, httptypes.NewHTTPError(http.StatusForbidden, "not current leader"))
-		return
-	}
-	w.Header().Set("Content-Type", "application/json")
-	w.Write(stats)
-}
-
-// parseKeyRequest converts a received http.Request on keysPrefix to
-// a server Request, performing validation of supplied fields as appropriate.
-// If any validation fails, an empty Request and non-nil error is returned.
-func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Request, bool, error) {
-	var noValueOnSuccess bool
-	emptyReq := etcdserverpb.Request{}
-
-	err := r.ParseForm()
-	if err != nil {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeInvalidForm,
-			err.Error(),
-		)
-	}
-
-	if !strings.HasPrefix(r.URL.Path, keysPrefix) {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeInvalidForm,
-			"incorrect key prefix",
-		)
-	}
-	p := path.Join(etcdserver.StoreKeysPrefix, r.URL.Path[len(keysPrefix):])
-
-	var pIdx, wIdx uint64
-	if pIdx, err = getUint64(r.Form, "prevIndex"); err != nil {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeIndexNaN,
-			`invalid value for "prevIndex"`,
-		)
-	}
-	if wIdx, err = getUint64(r.Form, "waitIndex"); err != nil {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeIndexNaN,
-			`invalid value for "waitIndex"`,
-		)
-	}
-
-	var rec, sort, wait, dir, quorum, stream bool
-	if rec, err = getBool(r.Form, "recursive"); err != nil {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeInvalidField,
-			`invalid value for "recursive"`,
-		)
-	}
-	if sort, err = getBool(r.Form, "sorted"); err != nil {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeInvalidField,
-			`invalid value for "sorted"`,
-		)
-	}
-	if wait, err = getBool(r.Form, "wait"); err != nil {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeInvalidField,
-			`invalid value for "wait"`,
-		)
-	}
-	// TODO(jonboulle): define what parameters dir is/isn't compatible with?
-	if dir, err = getBool(r.Form, "dir"); err != nil {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeInvalidField,
-			`invalid value for "dir"`,
-		)
-	}
-	if quorum, err = getBool(r.Form, "quorum"); err != nil {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeInvalidField,
-			`invalid value for "quorum"`,
-		)
-	}
-	if stream, err = getBool(r.Form, "stream"); err != nil {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeInvalidField,
-			`invalid value for "stream"`,
-		)
-	}
-
-	if wait && r.Method != "GET" {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeInvalidField,
-			`"wait" can only be used with GET requests`,
-		)
-	}
-
-	pV := r.FormValue("prevValue")
-	if _, ok := r.Form["prevValue"]; ok && pV == "" {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodePrevValueRequired,
-			`"prevValue" cannot be empty`,
-		)
-	}
-
-	if noValueOnSuccess, err = getBool(r.Form, "noValueOnSuccess"); err != nil {
-		return emptyReq, false, etcdErr.NewRequestError(
-			etcdErr.EcodeInvalidField,
-			`invalid value for "noValueOnSuccess"`,
-		)
-	}
-
-	// TTL is nullable, so leave it null if not specified
-	// or an empty string
-	var ttl *uint64
-	if len(r.FormValue("ttl")) > 0 {
-		i, err := getUint64(r.Form, "ttl")
-		if err != nil {
-			return emptyReq, false, etcdErr.NewRequestError(
-				etcdErr.EcodeTTLNaN,
-				`invalid value for "ttl"`,
-			)
-		}
-		ttl = &i
-	}
-
-	// prevExist is nullable, so leave it null if not specified
-	var pe *bool
-	if _, ok := r.Form["prevExist"]; ok {
-		bv, err := getBool(r.Form, "prevExist")
-		if err != nil {
-			return emptyReq, false, etcdErr.NewRequestError(
-				etcdErr.EcodeInvalidField,
-				"invalid value for prevExist",
-			)
-		}
-		pe = &bv
-	}
-
-	// refresh is nullable, so leave it null if not specified
-	var refresh *bool
-	if _, ok := r.Form["refresh"]; ok {
-		bv, err := getBool(r.Form, "refresh")
-		if err != nil {
-			return emptyReq, false, etcdErr.NewRequestError(
-				etcdErr.EcodeInvalidField,
-				"invalid value for refresh",
-			)
-		}
-		refresh = &bv
-		if refresh != nil && *refresh {
-			val := r.FormValue("value")
-			if _, ok := r.Form["value"]; ok && val != "" {
-				return emptyReq, false, etcdErr.NewRequestError(
-					etcdErr.EcodeRefreshValue,
-					`A value was provided on a refresh`,
-				)
-			}
-			if ttl == nil {
-				return emptyReq, false, etcdErr.NewRequestError(
-					etcdErr.EcodeRefreshTTLRequired,
-					`No TTL value set`,
-				)
-			}
-		}
-	}
-
-	rr := etcdserverpb.Request{
-		Method:    r.Method,
-		Path:      p,
-		Val:       r.FormValue("value"),
-		Dir:       dir,
-		PrevValue: pV,
-		PrevIndex: pIdx,
-		PrevExist: pe,
-		Wait:      wait,
-		Since:     wIdx,
-		Recursive: rec,
-		Sorted:    sort,
-		Quorum:    quorum,
-		Stream:    stream,
-	}
-
-	if pe != nil {
-		rr.PrevExist = pe
-	}
-
-	if refresh != nil {
-		rr.Refresh = refresh
-	}
-
-	// Null TTL is equivalent to unset Expiration
-	if ttl != nil {
-		expr := time.Duration(*ttl) * time.Second
-		rr.Expiration = clock.Now().Add(expr).UnixNano()
-	}
-
-	return rr, noValueOnSuccess, nil
-}
-
-// writeKeyEvent trims the prefix of key path in a single Event under
-// StoreKeysPrefix, serializes it and writes the resulting JSON to the given
-// ResponseWriter, along with the appropriate headers.
-func writeKeyEvent(w http.ResponseWriter, resp etcdserver.Response, noValueOnSuccess bool) error {
-	ev := resp.Event
-	if ev == nil {
-		return errors.New("cannot write empty Event!")
-	}
-	w.Header().Set("Content-Type", "application/json")
-	w.Header().Set("X-Etcd-Index", fmt.Sprint(ev.EtcdIndex))
-	w.Header().Set("X-Raft-Index", fmt.Sprint(resp.Index))
-	w.Header().Set("X-Raft-Term", fmt.Sprint(resp.Term))
-
-	if ev.IsCreated() {
-		w.WriteHeader(http.StatusCreated)
-	}
-
-	ev = trimEventPrefix(ev, etcdserver.StoreKeysPrefix)
-	if noValueOnSuccess &&
-		(ev.Action == store.Set || ev.Action == store.CompareAndSwap ||
-			ev.Action == store.Create || ev.Action == store.Update) {
-		ev.Node = nil
-		ev.PrevNode = nil
-	}
-	return json.NewEncoder(w).Encode(ev)
-}
-
-func writeKeyNoAuth(w http.ResponseWriter) {
-	e := etcdErr.NewError(etcdErr.EcodeUnauthorized, "Insufficient credentials", 0)
-	e.WriteTo(w)
-}
-
-// writeKeyError logs and writes the given Error to the ResponseWriter.
-// If Error is not an etcdErr, the error will be converted to an etcd error.
-func writeKeyError(w http.ResponseWriter, err error) {
-	if err == nil {
-		return
-	}
-	switch e := err.(type) {
-	case *etcdErr.Error:
-		e.WriteTo(w)
-	default:
-		switch err {
-		case etcdserver.ErrTimeoutDueToLeaderFail, etcdserver.ErrTimeoutDueToConnectionLost:
-			mlog.MergeError(err)
-		default:
-			mlog.MergeErrorf("got unexpected response error (%v)", err)
-		}
-		ee := etcdErr.NewError(etcdErr.EcodeRaftInternal, err.Error(), 0)
-		ee.WriteTo(w)
-	}
-}
-
-func handleKeyWatch(ctx context.Context, w http.ResponseWriter, resp etcdserver.Response, stream bool) {
-	wa := resp.Watcher
-	defer wa.Remove()
-	ech := wa.EventChan()
-	var nch <-chan bool
-	if x, ok := w.(http.CloseNotifier); ok {
-		nch = x.CloseNotify()
-	}
-
-	w.Header().Set("Content-Type", "application/json")
-	w.Header().Set("X-Etcd-Index", fmt.Sprint(wa.StartIndex()))
-	w.Header().Set("X-Raft-Index", fmt.Sprint(resp.Index))
-	w.Header().Set("X-Raft-Term", fmt.Sprint(resp.Term))
-	w.WriteHeader(http.StatusOK)
-
-	// Ensure headers are flushed early, in case of long polling
-	w.(http.Flusher).Flush()
-
-	for {
-		select {
-		case <-nch:
-			// Client closed connection. Nothing to do.
-			return
-		case <-ctx.Done():
-			// Timed out. net/http will close the connection for us, so nothing to do.
-			return
-		case ev, ok := <-ech:
-			if !ok {
-				// If the channel is closed this may be an indication of
-				// that notifications are much more than we are able to
-				// send to the client in time. Then we simply end streaming.
-				return
-			}
-			ev = trimEventPrefix(ev, etcdserver.StoreKeysPrefix)
-			if err := json.NewEncoder(w).Encode(ev); err != nil {
-				// Should never be reached
-				plog.Warningf("error writing event (%v)", err)
-				return
-			}
-			if !stream {
-				return
-			}
-			w.(http.Flusher).Flush()
-		}
-	}
-}
-
-func trimEventPrefix(ev *store.Event, prefix string) *store.Event {
-	if ev == nil {
-		return nil
-	}
-	// Since the *Event may reference one in the store history
-	// history, we must copy it before modifying
-	e := ev.Clone()
-	trimNodeExternPrefix(e.Node, prefix)
-	trimNodeExternPrefix(e.PrevNode, prefix)
-	return e
-}
-
-func trimNodeExternPrefix(n *store.NodeExtern, prefix string) {
-	if n == nil {
-		return
-	}
-	n.Key = strings.TrimPrefix(n.Key, prefix)
-	for _, nn := range n.Nodes {
-		trimNodeExternPrefix(nn, prefix)
-	}
-}
-
-func trimErrorPrefix(err error, prefix string) error {
-	if e, ok := err.(*etcdErr.Error); ok {
-		e.Cause = strings.TrimPrefix(e.Cause, prefix)
-	}
-	return err
-}
-
-func unmarshalRequest(r *http.Request, req json.Unmarshaler, w http.ResponseWriter) bool {
-	ctype := r.Header.Get("Content-Type")
-	semicolonPosition := strings.Index(ctype, ";")
-	if semicolonPosition != -1 {
-		ctype = strings.TrimSpace(strings.ToLower(ctype[0:semicolonPosition]))
-	}
-	if ctype != "application/json" {
-		writeError(w, r, httptypes.NewHTTPError(http.StatusUnsupportedMediaType, fmt.Sprintf("Bad Content-Type %s, accept application/json", ctype)))
-		return false
-	}
-	b, err := ioutil.ReadAll(r.Body)
-	if err != nil {
-		writeError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, err.Error()))
-		return false
-	}
-	if err := req.UnmarshalJSON(b); err != nil {
-		writeError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, err.Error()))
-		return false
-	}
-	return true
-}
-
-func getID(p string, w http.ResponseWriter) (types.ID, bool) {
-	idStr := trimPrefix(p, membersPrefix)
-	if idStr == "" {
-		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-		return 0, false
-	}
-	id, err := types.IDFromString(idStr)
-	if err != nil {
-		writeError(w, nil, httptypes.NewHTTPError(http.StatusNotFound, fmt.Sprintf("No such member: %s", idStr)))
-		return 0, false
-	}
-	return id, true
-}
-
-// getUint64 extracts a uint64 by the given key from a Form. If the key does
-// not exist in the form, 0 is returned. If the key exists but the value is
-// badly formed, an error is returned. If multiple values are present only the
-// first is considered.
-func getUint64(form url.Values, key string) (i uint64, err error) {
-	if vals, ok := form[key]; ok {
-		i, err = strconv.ParseUint(vals[0], 10, 64)
-	}
-	return
-}
-
-// getBool extracts a bool by the given key from a Form. If the key does not
-// exist in the form, false is returned. If the key exists but the value is
-// badly formed, an error is returned. If multiple values are present only the
-// first is considered.
-func getBool(form url.Values, key string) (b bool, err error) {
-	if vals, ok := form[key]; ok {
-		b, err = strconv.ParseBool(vals[0])
-	}
-	return
-}
-
-// trimPrefix removes a given prefix and any slash following the prefix
-// e.g.: trimPrefix("foo", "foo") == trimPrefix("foo/", "foo") == ""
-func trimPrefix(p, prefix string) (s string) {
-	s = strings.TrimPrefix(p, prefix)
-	s = strings.TrimPrefix(s, "/")
-	return
-}
-
-func newMemberCollection(ms []*membership.Member) *httptypes.MemberCollection {
-	c := httptypes.MemberCollection(make([]httptypes.Member, len(ms)))
-
-	for i, m := range ms {
-		c[i] = newMember(m)
-	}
-
-	return &c
-}
-
-func newMember(m *membership.Member) httptypes.Member {
-	tm := httptypes.Member{
-		ID:         m.ID.String(),
-		Name:       m.Name,
-		PeerURLs:   make([]string, len(m.PeerURLs)),
-		ClientURLs: make([]string, len(m.ClientURLs)),
-	}
-
-	copy(tm.PeerURLs, m.PeerURLs)
-	copy(tm.ClientURLs, m.ClientURLs)
-
-	return tm
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client_auth.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client_auth.go
deleted file mode 100644
index 606e2e0..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/client_auth.go
+++ /dev/null
@@ -1,543 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2http
-
-import (
-	"encoding/json"
-	"net/http"
-	"path"
-	"strings"
-
-	"github.com/coreos/etcd/etcdserver/api"
-	"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
-	"github.com/coreos/etcd/etcdserver/auth"
-)
-
-type authHandler struct {
-	sec                   auth.Store
-	cluster               api.Cluster
-	clientCertAuthEnabled bool
-}
-
-func hasWriteRootAccess(sec auth.Store, r *http.Request, clientCertAuthEnabled bool) bool {
-	if r.Method == "GET" || r.Method == "HEAD" {
-		return true
-	}
-	return hasRootAccess(sec, r, clientCertAuthEnabled)
-}
-
-func userFromBasicAuth(sec auth.Store, r *http.Request) *auth.User {
-	username, password, ok := r.BasicAuth()
-	if !ok {
-		plog.Warningf("auth: malformed basic auth encoding")
-		return nil
-	}
-	user, err := sec.GetUser(username)
-	if err != nil {
-		return nil
-	}
-
-	ok = sec.CheckPassword(user, password)
-	if !ok {
-		plog.Warningf("auth: incorrect password for user: %s", username)
-		return nil
-	}
-	return &user
-}
-
-func userFromClientCertificate(sec auth.Store, r *http.Request) *auth.User {
-	if r.TLS == nil {
-		return nil
-	}
-
-	for _, chains := range r.TLS.VerifiedChains {
-		for _, chain := range chains {
-			plog.Debugf("auth: found common name %s.\n", chain.Subject.CommonName)
-			user, err := sec.GetUser(chain.Subject.CommonName)
-			if err == nil {
-				plog.Debugf("auth: authenticated user %s by cert common name.", user.User)
-				return &user
-			}
-		}
-	}
-	return nil
-}
-
-func hasRootAccess(sec auth.Store, r *http.Request, clientCertAuthEnabled bool) bool {
-	if sec == nil {
-		// No store means no auth available, eg, tests.
-		return true
-	}
-	if !sec.AuthEnabled() {
-		return true
-	}
-
-	var rootUser *auth.User
-	if r.Header.Get("Authorization") == "" && clientCertAuthEnabled {
-		rootUser = userFromClientCertificate(sec, r)
-		if rootUser == nil {
-			return false
-		}
-	} else {
-		rootUser = userFromBasicAuth(sec, r)
-		if rootUser == nil {
-			return false
-		}
-	}
-
-	for _, role := range rootUser.Roles {
-		if role == auth.RootRoleName {
-			return true
-		}
-	}
-	plog.Warningf("auth: user %s does not have the %s role for resource %s.", rootUser.User, auth.RootRoleName, r.URL.Path)
-	return false
-}
-
-func hasKeyPrefixAccess(sec auth.Store, r *http.Request, key string, recursive, clientCertAuthEnabled bool) bool {
-	if sec == nil {
-		// No store means no auth available, eg, tests.
-		return true
-	}
-	if !sec.AuthEnabled() {
-		return true
-	}
-
-	var user *auth.User
-	if r.Header.Get("Authorization") == "" {
-		if clientCertAuthEnabled {
-			user = userFromClientCertificate(sec, r)
-		}
-		if user == nil {
-			return hasGuestAccess(sec, r, key)
-		}
-	} else {
-		user = userFromBasicAuth(sec, r)
-		if user == nil {
-			return false
-		}
-	}
-
-	writeAccess := r.Method != "GET" && r.Method != "HEAD"
-	for _, roleName := range user.Roles {
-		role, err := sec.GetRole(roleName)
-		if err != nil {
-			continue
-		}
-		if recursive {
-			if role.HasRecursiveAccess(key, writeAccess) {
-				return true
-			}
-		} else if role.HasKeyAccess(key, writeAccess) {
-			return true
-		}
-	}
-	plog.Warningf("auth: invalid access for user %s on key %s.", user.User, key)
-	return false
-}
-
-func hasGuestAccess(sec auth.Store, r *http.Request, key string) bool {
-	writeAccess := r.Method != "GET" && r.Method != "HEAD"
-	role, err := sec.GetRole(auth.GuestRoleName)
-	if err != nil {
-		return false
-	}
-	if role.HasKeyAccess(key, writeAccess) {
-		return true
-	}
-	plog.Warningf("auth: invalid access for unauthenticated user on resource %s.", key)
-	return false
-}
-
-func writeNoAuth(w http.ResponseWriter, r *http.Request) {
-	herr := httptypes.NewHTTPError(http.StatusUnauthorized, "Insufficient credentials")
-	if err := herr.WriteTo(w); err != nil {
-		plog.Debugf("error writing HTTPError (%v) to %s", err, r.RemoteAddr)
-	}
-}
-
-func handleAuth(mux *http.ServeMux, sh *authHandler) {
-	mux.HandleFunc(authPrefix+"/roles", capabilityHandler(api.AuthCapability, sh.baseRoles))
-	mux.HandleFunc(authPrefix+"/roles/", capabilityHandler(api.AuthCapability, sh.handleRoles))
-	mux.HandleFunc(authPrefix+"/users", capabilityHandler(api.AuthCapability, sh.baseUsers))
-	mux.HandleFunc(authPrefix+"/users/", capabilityHandler(api.AuthCapability, sh.handleUsers))
-	mux.HandleFunc(authPrefix+"/enable", capabilityHandler(api.AuthCapability, sh.enableDisable))
-}
-
-func (sh *authHandler) baseRoles(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-	if !hasRootAccess(sh.sec, r, sh.clientCertAuthEnabled) {
-		writeNoAuth(w, r)
-		return
-	}
-
-	w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
-	w.Header().Set("Content-Type", "application/json")
-
-	roles, err := sh.sec.AllRoles()
-	if err != nil {
-		writeError(w, r, err)
-		return
-	}
-	if roles == nil {
-		roles = make([]string, 0)
-	}
-
-	err = r.ParseForm()
-	if err != nil {
-		writeError(w, r, err)
-		return
-	}
-
-	var rolesCollections struct {
-		Roles []auth.Role `json:"roles"`
-	}
-	for _, roleName := range roles {
-		var role auth.Role
-		role, err = sh.sec.GetRole(roleName)
-		if err != nil {
-			writeError(w, r, err)
-			return
-		}
-		rolesCollections.Roles = append(rolesCollections.Roles, role)
-	}
-	err = json.NewEncoder(w).Encode(rolesCollections)
-
-	if err != nil {
-		plog.Warningf("baseRoles error encoding on %s", r.URL)
-		writeError(w, r, err)
-		return
-	}
-}
-
-func (sh *authHandler) handleRoles(w http.ResponseWriter, r *http.Request) {
-	subpath := path.Clean(r.URL.Path[len(authPrefix):])
-	// Split "/roles/rolename/command".
-	// First item is an empty string, second is "roles"
-	pieces := strings.Split(subpath, "/")
-	if len(pieces) == 2 {
-		sh.baseRoles(w, r)
-		return
-	}
-	if len(pieces) != 3 {
-		writeError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid path"))
-		return
-	}
-	sh.forRole(w, r, pieces[2])
-}
-
-func (sh *authHandler) forRole(w http.ResponseWriter, r *http.Request, role string) {
-	if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") {
-		return
-	}
-	if !hasRootAccess(sh.sec, r, sh.clientCertAuthEnabled) {
-		writeNoAuth(w, r)
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
-	w.Header().Set("Content-Type", "application/json")
-
-	switch r.Method {
-	case "GET":
-		data, err := sh.sec.GetRole(role)
-		if err != nil {
-			writeError(w, r, err)
-			return
-		}
-		err = json.NewEncoder(w).Encode(data)
-		if err != nil {
-			plog.Warningf("forRole error encoding on %s", r.URL)
-			return
-		}
-		return
-	case "PUT":
-		var in auth.Role
-		err := json.NewDecoder(r.Body).Decode(&in)
-		if err != nil {
-			writeError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid JSON in request body."))
-			return
-		}
-		if in.Role != role {
-			writeError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Role JSON name does not match the name in the URL"))
-			return
-		}
-
-		var out auth.Role
-
-		// create
-		if in.Grant.IsEmpty() && in.Revoke.IsEmpty() {
-			err = sh.sec.CreateRole(in)
-			if err != nil {
-				writeError(w, r, err)
-				return
-			}
-			w.WriteHeader(http.StatusCreated)
-			out = in
-		} else {
-			if !in.Permissions.IsEmpty() {
-				writeError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Role JSON contains both permissions and grant/revoke"))
-				return
-			}
-			out, err = sh.sec.UpdateRole(in)
-			if err != nil {
-				writeError(w, r, err)
-				return
-			}
-			w.WriteHeader(http.StatusOK)
-		}
-
-		err = json.NewEncoder(w).Encode(out)
-		if err != nil {
-			plog.Warningf("forRole error encoding on %s", r.URL)
-			return
-		}
-		return
-	case "DELETE":
-		err := sh.sec.DeleteRole(role)
-		if err != nil {
-			writeError(w, r, err)
-			return
-		}
-	}
-}
-
-type userWithRoles struct {
-	User  string      `json:"user"`
-	Roles []auth.Role `json:"roles,omitempty"`
-}
-
-type usersCollections struct {
-	Users []userWithRoles `json:"users"`
-}
-
-func (sh *authHandler) baseUsers(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-	if !hasRootAccess(sh.sec, r, sh.clientCertAuthEnabled) {
-		writeNoAuth(w, r)
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
-	w.Header().Set("Content-Type", "application/json")
-
-	users, err := sh.sec.AllUsers()
-	if err != nil {
-		writeError(w, r, err)
-		return
-	}
-	if users == nil {
-		users = make([]string, 0)
-	}
-
-	err = r.ParseForm()
-	if err != nil {
-		writeError(w, r, err)
-		return
-	}
-
-	ucs := usersCollections{}
-	for _, userName := range users {
-		var user auth.User
-		user, err = sh.sec.GetUser(userName)
-		if err != nil {
-			writeError(w, r, err)
-			return
-		}
-
-		uwr := userWithRoles{User: user.User}
-		for _, roleName := range user.Roles {
-			var role auth.Role
-			role, err = sh.sec.GetRole(roleName)
-			if err != nil {
-				continue
-			}
-			uwr.Roles = append(uwr.Roles, role)
-		}
-
-		ucs.Users = append(ucs.Users, uwr)
-	}
-	err = json.NewEncoder(w).Encode(ucs)
-
-	if err != nil {
-		plog.Warningf("baseUsers error encoding on %s", r.URL)
-		writeError(w, r, err)
-		return
-	}
-}
-
-func (sh *authHandler) handleUsers(w http.ResponseWriter, r *http.Request) {
-	subpath := path.Clean(r.URL.Path[len(authPrefix):])
-	// Split "/users/username".
-	// First item is an empty string, second is "users"
-	pieces := strings.Split(subpath, "/")
-	if len(pieces) == 2 {
-		sh.baseUsers(w, r)
-		return
-	}
-	if len(pieces) != 3 {
-		writeError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid path"))
-		return
-	}
-	sh.forUser(w, r, pieces[2])
-}
-
-func (sh *authHandler) forUser(w http.ResponseWriter, r *http.Request, user string) {
-	if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") {
-		return
-	}
-	if !hasRootAccess(sh.sec, r, sh.clientCertAuthEnabled) {
-		writeNoAuth(w, r)
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
-	w.Header().Set("Content-Type", "application/json")
-
-	switch r.Method {
-	case "GET":
-		u, err := sh.sec.GetUser(user)
-		if err != nil {
-			writeError(w, r, err)
-			return
-		}
-
-		err = r.ParseForm()
-		if err != nil {
-			writeError(w, r, err)
-			return
-		}
-
-		uwr := userWithRoles{User: u.User}
-		for _, roleName := range u.Roles {
-			var role auth.Role
-			role, err = sh.sec.GetRole(roleName)
-			if err != nil {
-				writeError(w, r, err)
-				return
-			}
-			uwr.Roles = append(uwr.Roles, role)
-		}
-		err = json.NewEncoder(w).Encode(uwr)
-
-		if err != nil {
-			plog.Warningf("forUser error encoding on %s", r.URL)
-			return
-		}
-		return
-	case "PUT":
-		var u auth.User
-		err := json.NewDecoder(r.Body).Decode(&u)
-		if err != nil {
-			writeError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid JSON in request body."))
-			return
-		}
-		if u.User != user {
-			writeError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, "User JSON name does not match the name in the URL"))
-			return
-		}
-
-		var (
-			out     auth.User
-			created bool
-		)
-
-		if len(u.Grant) == 0 && len(u.Revoke) == 0 {
-			// create or update
-			if len(u.Roles) != 0 {
-				out, err = sh.sec.CreateUser(u)
-			} else {
-				// if user passes in both password and roles, we are unsure about his/her
-				// intention.
-				out, created, err = sh.sec.CreateOrUpdateUser(u)
-			}
-
-			if err != nil {
-				writeError(w, r, err)
-				return
-			}
-		} else {
-			// update case
-			if len(u.Roles) != 0 {
-				writeError(w, r, httptypes.NewHTTPError(http.StatusBadRequest, "User JSON contains both roles and grant/revoke"))
-				return
-			}
-			out, err = sh.sec.UpdateUser(u)
-			if err != nil {
-				writeError(w, r, err)
-				return
-			}
-		}
-
-		if created {
-			w.WriteHeader(http.StatusCreated)
-		} else {
-			w.WriteHeader(http.StatusOK)
-		}
-
-		out.Password = ""
-
-		err = json.NewEncoder(w).Encode(out)
-		if err != nil {
-			plog.Warningf("forUser error encoding on %s", r.URL)
-			return
-		}
-		return
-	case "DELETE":
-		err := sh.sec.DeleteUser(user)
-		if err != nil {
-			writeError(w, r, err)
-			return
-		}
-	}
-}
-
-type enabled struct {
-	Enabled bool `json:"enabled"`
-}
-
-func (sh *authHandler) enableDisable(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") {
-		return
-	}
-	if !hasWriteRootAccess(sh.sec, r, sh.clientCertAuthEnabled) {
-		writeNoAuth(w, r)
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
-	w.Header().Set("Content-Type", "application/json")
-	isEnabled := sh.sec.AuthEnabled()
-	switch r.Method {
-	case "GET":
-		jsonDict := enabled{isEnabled}
-		err := json.NewEncoder(w).Encode(jsonDict)
-		if err != nil {
-			plog.Warningf("error encoding auth state on %s", r.URL)
-		}
-	case "PUT":
-		err := sh.sec.EnableAuth()
-		if err != nil {
-			writeError(w, r, err)
-			return
-		}
-	case "DELETE":
-		err := sh.sec.DisableAuth()
-		if err != nil {
-			writeError(w, r, err)
-			return
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/doc.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/doc.go
deleted file mode 100644
index 475c4b1..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package v2http provides etcd client and server implementations.
-package v2http
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/http.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/http.go
deleted file mode 100644
index 589c172..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/http.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2http
-
-import (
-	"math"
-	"net/http"
-	"strings"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver/api/etcdhttp"
-	"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
-	"github.com/coreos/etcd/etcdserver/auth"
-	"github.com/coreos/etcd/pkg/logutil"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-const (
-	// time to wait for a Watch request
-	defaultWatchTimeout = time.Duration(math.MaxInt64)
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/api/v2http")
-	mlog = logutil.NewMergeLogger(plog)
-)
-
-func writeError(w http.ResponseWriter, r *http.Request, err error) {
-	if err == nil {
-		return
-	}
-	if e, ok := err.(auth.Error); ok {
-		herr := httptypes.NewHTTPError(e.HTTPStatus(), e.Error())
-		if et := herr.WriteTo(w); et != nil {
-			plog.Debugf("error writing HTTPError (%v) to %s", et, r.RemoteAddr)
-		}
-		return
-	}
-	etcdhttp.WriteError(w, r, err)
-}
-
-// allowMethod verifies that the given method is one of the allowed methods,
-// and if not, it writes an error to w.  A boolean is returned indicating
-// whether or not the method is allowed.
-func allowMethod(w http.ResponseWriter, m string, ms ...string) bool {
-	for _, meth := range ms {
-		if m == meth {
-			return true
-		}
-	}
-	w.Header().Set("Allow", strings.Join(ms, ","))
-	http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-	return false
-}
-
-func requestLogger(handler http.Handler) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		plog.Debugf("[%s] %s remote:%s", r.Method, r.RequestURI, r.RemoteAddr)
-		handler.ServeHTTP(w, r)
-	})
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/errors.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/errors.go
deleted file mode 100644
index 0657604..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/errors.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package httptypes
-
-import (
-	"encoding/json"
-	"net/http"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/api/v2http/httptypes")
-)
-
-type HTTPError struct {
-	Message string `json:"message"`
-	// Code is the HTTP status code
-	Code int `json:"-"`
-}
-
-func (e HTTPError) Error() string {
-	return e.Message
-}
-
-func (e HTTPError) WriteTo(w http.ResponseWriter) error {
-	w.Header().Set("Content-Type", "application/json")
-	w.WriteHeader(e.Code)
-	b, err := json.Marshal(e)
-	if err != nil {
-		plog.Panicf("marshal HTTPError should never fail (%v)", err)
-	}
-	if _, err := w.Write(b); err != nil {
-		return err
-	}
-	return nil
-}
-
-func NewHTTPError(code int, m string) *HTTPError {
-	return &HTTPError{
-		Message: m,
-		Code:    code,
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/member.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/member.go
deleted file mode 100644
index 738d744..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/member.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package httptypes defines how etcd's HTTP API entities are serialized to and
-// deserialized from JSON.
-package httptypes
-
-import (
-	"encoding/json"
-
-	"github.com/coreos/etcd/pkg/types"
-)
-
-type Member struct {
-	ID         string   `json:"id"`
-	Name       string   `json:"name"`
-	PeerURLs   []string `json:"peerURLs"`
-	ClientURLs []string `json:"clientURLs"`
-}
-
-type MemberCreateRequest struct {
-	PeerURLs types.URLs
-}
-
-type MemberUpdateRequest struct {
-	MemberCreateRequest
-}
-
-func (m *MemberCreateRequest) UnmarshalJSON(data []byte) error {
-	s := struct {
-		PeerURLs []string `json:"peerURLs"`
-	}{}
-
-	err := json.Unmarshal(data, &s)
-	if err != nil {
-		return err
-	}
-
-	urls, err := types.NewURLs(s.PeerURLs)
-	if err != nil {
-		return err
-	}
-
-	m.PeerURLs = urls
-	return nil
-}
-
-type MemberCollection []Member
-
-func (c *MemberCollection) MarshalJSON() ([]byte, error) {
-	d := struct {
-		Members []Member `json:"members"`
-	}{
-		Members: []Member(*c),
-	}
-
-	return json.Marshal(d)
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2http/metrics.go
deleted file mode 100644
index fdfb0c6..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2http/metrics.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2http
-
-import (
-	"strconv"
-	"time"
-
-	"net/http"
-
-	etcdErr "github.com/coreos/etcd/error"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
-	"github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-var (
-	incomingEvents = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "http",
-			Name:      "received_total",
-			Help:      "Counter of requests received into the system (successfully parsed and authd).",
-		}, []string{"method"})
-
-	failedEvents = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "http",
-			Name:      "failed_total",
-			Help:      "Counter of handle failures of requests (non-watches), by method (GET/PUT etc.) and code (400, 500 etc.).",
-		}, []string{"method", "code"})
-
-	successfulEventsHandlingTime = prometheus.NewHistogramVec(
-		prometheus.HistogramOpts{
-			Namespace: "etcd",
-			Subsystem: "http",
-			Name:      "successful_duration_seconds",
-			Help:      "Bucketed histogram of processing time (s) of successfully handled requests (non-watches), by method (GET/PUT etc.).",
-			Buckets:   prometheus.ExponentialBuckets(0.0005, 2, 13),
-		}, []string{"method"})
-)
-
-func init() {
-	prometheus.MustRegister(incomingEvents)
-	prometheus.MustRegister(failedEvents)
-	prometheus.MustRegister(successfulEventsHandlingTime)
-}
-
-func reportRequestReceived(request etcdserverpb.Request) {
-	incomingEvents.WithLabelValues(methodFromRequest(request)).Inc()
-}
-
-func reportRequestCompleted(request etcdserverpb.Request, response etcdserver.Response, startTime time.Time) {
-	method := methodFromRequest(request)
-	successfulEventsHandlingTime.WithLabelValues(method).Observe(time.Since(startTime).Seconds())
-}
-
-func reportRequestFailed(request etcdserverpb.Request, err error) {
-	method := methodFromRequest(request)
-	failedEvents.WithLabelValues(method, strconv.Itoa(codeFromError(err))).Inc()
-}
-
-func methodFromRequest(request etcdserverpb.Request) string {
-	if request.Method == "GET" && request.Quorum {
-		return "QGET"
-	}
-	return request.Method
-}
-
-func codeFromError(err error) int {
-	if err == nil {
-		return http.StatusInternalServerError
-	}
-	switch e := err.(type) {
-	case *etcdErr.Error:
-		return (*etcdErr.Error)(e).StatusCode()
-	case *httptypes.HTTPError:
-		return (*httptypes.HTTPError)(e).Code
-	default:
-		return http.StatusInternalServerError
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/cluster.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/cluster.go
deleted file mode 100644
index b53e6d7..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/cluster.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2v3
-
-import (
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/pkg/types"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-func (s *v2v3Server) ID() types.ID {
-	// TODO: use an actual member ID
-	return types.ID(0xe7cd2f00d)
-}
-func (s *v2v3Server) ClientURLs() []string                  { panic("STUB") }
-func (s *v2v3Server) Members() []*membership.Member         { panic("STUB") }
-func (s *v2v3Server) Member(id types.ID) *membership.Member { panic("STUB") }
-func (s *v2v3Server) Version() *semver.Version              { panic("STUB") }
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/doc.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/doc.go
deleted file mode 100644
index 2ff372f..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package v2v3 provides a ServerV2 implementation backed by clientv3.Client.
-package v2v3
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/server.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/server.go
deleted file mode 100644
index 2ef63ce..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/server.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2v3
-
-import (
-	"context"
-	"net/http"
-	"time"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/pkg/types"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-type fakeStats struct{}
-
-func (s *fakeStats) SelfStats() []byte   { return nil }
-func (s *fakeStats) LeaderStats() []byte { return nil }
-func (s *fakeStats) StoreStats() []byte  { return nil }
-
-type v2v3Server struct {
-	c     *clientv3.Client
-	store *v2v3Store
-	fakeStats
-}
-
-func NewServer(c *clientv3.Client, pfx string) etcdserver.ServerPeer {
-	return &v2v3Server{c: c, store: newStore(c, pfx)}
-}
-
-func (s *v2v3Server) ClientCertAuthEnabled() bool { return false }
-
-func (s *v2v3Server) LeaseHandler() http.Handler { panic("STUB: lease handler") }
-func (s *v2v3Server) RaftHandler() http.Handler  { panic("STUB: raft handler") }
-
-func (s *v2v3Server) Leader() types.ID {
-	ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)
-	defer cancel()
-	resp, err := s.c.Status(ctx, s.c.Endpoints()[0])
-	if err != nil {
-		return 0
-	}
-	return types.ID(resp.Leader)
-}
-
-func (s *v2v3Server) AddMember(ctx context.Context, memb membership.Member) ([]*membership.Member, error) {
-	resp, err := s.c.MemberAdd(ctx, memb.PeerURLs)
-	if err != nil {
-		return nil, err
-	}
-	return v3MembersToMembership(resp.Members), nil
-}
-
-func (s *v2v3Server) RemoveMember(ctx context.Context, id uint64) ([]*membership.Member, error) {
-	resp, err := s.c.MemberRemove(ctx, id)
-	if err != nil {
-		return nil, err
-	}
-	return v3MembersToMembership(resp.Members), nil
-}
-
-func (s *v2v3Server) UpdateMember(ctx context.Context, m membership.Member) ([]*membership.Member, error) {
-	resp, err := s.c.MemberUpdate(ctx, uint64(m.ID), m.PeerURLs)
-	if err != nil {
-		return nil, err
-	}
-	return v3MembersToMembership(resp.Members), nil
-}
-
-func v3MembersToMembership(v3membs []*pb.Member) []*membership.Member {
-	membs := make([]*membership.Member, len(v3membs))
-	for i, m := range v3membs {
-		membs[i] = &membership.Member{
-			ID: types.ID(m.ID),
-			RaftAttributes: membership.RaftAttributes{
-				PeerURLs: m.PeerURLs,
-			},
-			Attributes: membership.Attributes{
-				Name:       m.Name,
-				ClientURLs: m.ClientURLs,
-			},
-		}
-	}
-	return membs
-}
-
-func (s *v2v3Server) ClusterVersion() *semver.Version { return s.Version() }
-func (s *v2v3Server) Cluster() api.Cluster            { return s }
-func (s *v2v3Server) Alarms() []*pb.AlarmMember       { return nil }
-
-func (s *v2v3Server) Do(ctx context.Context, r pb.Request) (etcdserver.Response, error) {
-	applier := etcdserver.NewApplierV2(s.store, nil)
-	reqHandler := etcdserver.NewStoreRequestV2Handler(s.store, applier)
-	req := (*etcdserver.RequestV2)(&r)
-	resp, err := req.Handle(ctx, reqHandler)
-	if resp.Err != nil {
-		return resp, resp.Err
-	}
-	return resp, err
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/store.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/store.go
deleted file mode 100644
index 444f93f..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/store.go
+++ /dev/null
@@ -1,620 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2v3
-
-import (
-	"context"
-	"fmt"
-	"path"
-	"strings"
-	"time"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/clientv3/concurrency"
-	etcdErr "github.com/coreos/etcd/error"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-	"github.com/coreos/etcd/store"
-)
-
-// store implements the Store interface for V2 using
-// a v3 client.
-type v2v3Store struct {
-	c *clientv3.Client
-	// pfx is the v3 prefix where keys should be stored.
-	pfx string
-	ctx context.Context
-}
-
-const maxPathDepth = 63
-
-var errUnsupported = fmt.Errorf("TTLs are unsupported")
-
-func NewStore(c *clientv3.Client, pfx string) store.Store { return newStore(c, pfx) }
-
-func newStore(c *clientv3.Client, pfx string) *v2v3Store { return &v2v3Store{c, pfx, c.Ctx()} }
-
-func (s *v2v3Store) Index() uint64 { panic("STUB") }
-
-func (s *v2v3Store) Get(nodePath string, recursive, sorted bool) (*store.Event, error) {
-	key := s.mkPath(nodePath)
-	resp, err := s.c.Txn(s.ctx).Then(
-		clientv3.OpGet(key+"/"),
-		clientv3.OpGet(key),
-	).Commit()
-	if err != nil {
-		return nil, err
-	}
-
-	if kvs := resp.Responses[0].GetResponseRange().Kvs; len(kvs) != 0 || isRoot(nodePath) {
-		nodes, err := s.getDir(nodePath, recursive, sorted, resp.Header.Revision)
-		if err != nil {
-			return nil, err
-		}
-		cidx, midx := uint64(0), uint64(0)
-		if len(kvs) > 0 {
-			cidx, midx = mkV2Rev(kvs[0].CreateRevision), mkV2Rev(kvs[0].ModRevision)
-		}
-		return &store.Event{
-			Action: store.Get,
-			Node: &store.NodeExtern{
-				Key:           nodePath,
-				Dir:           true,
-				Nodes:         nodes,
-				CreatedIndex:  cidx,
-				ModifiedIndex: midx,
-			},
-			EtcdIndex: mkV2Rev(resp.Header.Revision),
-		}, nil
-	}
-
-	kvs := resp.Responses[1].GetResponseRange().Kvs
-	if len(kvs) == 0 {
-		return nil, etcdErr.NewError(etcdErr.EcodeKeyNotFound, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-
-	return &store.Event{
-		Action:    store.Get,
-		Node:      s.mkV2Node(kvs[0]),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) getDir(nodePath string, recursive, sorted bool, rev int64) ([]*store.NodeExtern, error) {
-	rootNodes, err := s.getDirDepth(nodePath, 1, rev)
-	if err != nil || !recursive {
-		return rootNodes, err
-	}
-	nextNodes := rootNodes
-	nodes := make(map[string]*store.NodeExtern)
-	// Breadth walk the subdirectories
-	for i := 2; len(nextNodes) > 0; i++ {
-		for _, n := range nextNodes {
-			nodes[n.Key] = n
-			if parent := nodes[path.Dir(n.Key)]; parent != nil {
-				parent.Nodes = append(parent.Nodes, n)
-			}
-		}
-		if nextNodes, err = s.getDirDepth(nodePath, i, rev); err != nil {
-			return nil, err
-		}
-	}
-	return rootNodes, nil
-}
-
-func (s *v2v3Store) getDirDepth(nodePath string, depth int, rev int64) ([]*store.NodeExtern, error) {
-	pd := s.mkPathDepth(nodePath, depth)
-	resp, err := s.c.Get(s.ctx, pd, clientv3.WithPrefix(), clientv3.WithRev(rev))
-	if err != nil {
-		return nil, err
-	}
-
-	nodes := make([]*store.NodeExtern, len(resp.Kvs))
-	for i, kv := range resp.Kvs {
-		nodes[i] = s.mkV2Node(kv)
-	}
-	return nodes, nil
-}
-
-func (s *v2v3Store) Set(
-	nodePath string,
-	dir bool,
-	value string,
-	expireOpts store.TTLOptionSet,
-) (*store.Event, error) {
-	if expireOpts.Refresh || !expireOpts.ExpireTime.IsZero() {
-		return nil, errUnsupported
-	}
-
-	if isRoot(nodePath) {
-		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, nodePath, 0)
-	}
-
-	ecode := 0
-	applyf := func(stm concurrency.STM) error {
-		parent := path.Dir(nodePath)
-		if !isRoot(parent) && stm.Rev(s.mkPath(parent)+"/") == 0 {
-			ecode = etcdErr.EcodeKeyNotFound
-			return nil
-		}
-
-		key := s.mkPath(nodePath)
-		if dir {
-			if stm.Rev(key) != 0 {
-				// exists as non-dir
-				ecode = etcdErr.EcodeNotDir
-				return nil
-			}
-			key = key + "/"
-		} else if stm.Rev(key+"/") != 0 {
-			ecode = etcdErr.EcodeNotFile
-			return nil
-		}
-		stm.Put(key, value, clientv3.WithPrevKV())
-		stm.Put(s.mkActionKey(), store.Set)
-		return nil
-	}
-
-	resp, err := s.newSTM(applyf)
-	if err != nil {
-		return nil, err
-	}
-	if ecode != 0 {
-		return nil, etcdErr.NewError(ecode, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-
-	createRev := resp.Header.Revision
-	var pn *store.NodeExtern
-	if pkv := prevKeyFromPuts(resp); pkv != nil {
-		pn = s.mkV2Node(pkv)
-		createRev = pkv.CreateRevision
-	}
-
-	vp := &value
-	if dir {
-		vp = nil
-	}
-	return &store.Event{
-		Action: store.Set,
-		Node: &store.NodeExtern{
-			Key:           nodePath,
-			Value:         vp,
-			Dir:           dir,
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-			CreatedIndex:  mkV2Rev(createRev),
-		},
-		PrevNode:  pn,
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) Update(nodePath, newValue string, expireOpts store.TTLOptionSet) (*store.Event, error) {
-	if isRoot(nodePath) {
-		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, nodePath, 0)
-	}
-
-	if expireOpts.Refresh || !expireOpts.ExpireTime.IsZero() {
-		return nil, errUnsupported
-	}
-
-	key := s.mkPath(nodePath)
-	ecode := 0
-	applyf := func(stm concurrency.STM) error {
-		if rev := stm.Rev(key + "/"); rev != 0 {
-			ecode = etcdErr.EcodeNotFile
-			return nil
-		}
-		if rev := stm.Rev(key); rev == 0 {
-			ecode = etcdErr.EcodeKeyNotFound
-			return nil
-		}
-		stm.Put(key, newValue, clientv3.WithPrevKV())
-		stm.Put(s.mkActionKey(), store.Update)
-		return nil
-	}
-
-	resp, err := s.newSTM(applyf)
-	if err != nil {
-		return nil, err
-	}
-	if ecode != 0 {
-		return nil, etcdErr.NewError(etcdErr.EcodeNotFile, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-
-	pkv := prevKeyFromPuts(resp)
-	return &store.Event{
-		Action: store.Update,
-		Node: &store.NodeExtern{
-			Key:           nodePath,
-			Value:         &newValue,
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-			CreatedIndex:  mkV2Rev(pkv.CreateRevision),
-		},
-		PrevNode:  s.mkV2Node(pkv),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) Create(
-	nodePath string,
-	dir bool,
-	value string,
-	unique bool,
-	expireOpts store.TTLOptionSet,
-) (*store.Event, error) {
-	if isRoot(nodePath) {
-		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, nodePath, 0)
-	}
-	if expireOpts.Refresh || !expireOpts.ExpireTime.IsZero() {
-		return nil, errUnsupported
-	}
-	ecode := 0
-	applyf := func(stm concurrency.STM) error {
-		ecode = 0
-		key := s.mkPath(nodePath)
-		if unique {
-			// append unique item under the node path
-			for {
-				key = nodePath + "/" + fmt.Sprintf("%020s", time.Now())
-				key = path.Clean(path.Join("/", key))
-				key = s.mkPath(key)
-				if stm.Rev(key) == 0 {
-					break
-				}
-			}
-		}
-		if stm.Rev(key) > 0 || stm.Rev(key+"/") > 0 {
-			ecode = etcdErr.EcodeNodeExist
-			return nil
-		}
-		// build path if any directories in path do not exist
-		dirs := []string{}
-		for p := path.Dir(nodePath); !isRoot(p); p = path.Dir(p) {
-			pp := s.mkPath(p)
-			if stm.Rev(pp) > 0 {
-				ecode = etcdErr.EcodeNotDir
-				return nil
-			}
-			if stm.Rev(pp+"/") == 0 {
-				dirs = append(dirs, pp+"/")
-			}
-		}
-		for _, d := range dirs {
-			stm.Put(d, "")
-		}
-
-		if dir {
-			// directories marked with extra slash in key name
-			key += "/"
-		}
-		stm.Put(key, value)
-		stm.Put(s.mkActionKey(), store.Create)
-		return nil
-	}
-
-	resp, err := s.newSTM(applyf)
-	if err != nil {
-		return nil, err
-	}
-	if ecode != 0 {
-		return nil, etcdErr.NewError(ecode, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-
-	var v *string
-	if !dir {
-		v = &value
-	}
-
-	return &store.Event{
-		Action: store.Create,
-		Node: &store.NodeExtern{
-			Key:           nodePath,
-			Value:         v,
-			Dir:           dir,
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-			CreatedIndex:  mkV2Rev(resp.Header.Revision),
-		},
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) CompareAndSwap(
-	nodePath string,
-	prevValue string,
-	prevIndex uint64,
-	value string,
-	expireOpts store.TTLOptionSet,
-) (*store.Event, error) {
-	if isRoot(nodePath) {
-		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, nodePath, 0)
-	}
-	if expireOpts.Refresh || !expireOpts.ExpireTime.IsZero() {
-		return nil, errUnsupported
-	}
-
-	key := s.mkPath(nodePath)
-	resp, err := s.c.Txn(s.ctx).If(
-		s.mkCompare(nodePath, prevValue, prevIndex)...,
-	).Then(
-		clientv3.OpPut(key, value, clientv3.WithPrevKV()),
-		clientv3.OpPut(s.mkActionKey(), store.CompareAndSwap),
-	).Else(
-		clientv3.OpGet(key),
-		clientv3.OpGet(key+"/"),
-	).Commit()
-
-	if err != nil {
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, compareFail(nodePath, prevValue, prevIndex, resp)
-	}
-
-	pkv := resp.Responses[0].GetResponsePut().PrevKv
-	return &store.Event{
-		Action: store.CompareAndSwap,
-		Node: &store.NodeExtern{
-			Key:           nodePath,
-			Value:         &value,
-			CreatedIndex:  mkV2Rev(pkv.CreateRevision),
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-		},
-		PrevNode:  s.mkV2Node(pkv),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) Delete(nodePath string, dir, recursive bool) (*store.Event, error) {
-	if isRoot(nodePath) {
-		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, nodePath, 0)
-	}
-	if !dir && !recursive {
-		return s.deleteNode(nodePath)
-	}
-	if !recursive {
-		return s.deleteEmptyDir(nodePath)
-	}
-
-	dels := make([]clientv3.Op, maxPathDepth+1)
-	dels[0] = clientv3.OpDelete(s.mkPath(nodePath)+"/", clientv3.WithPrevKV())
-	for i := 1; i < maxPathDepth; i++ {
-		dels[i] = clientv3.OpDelete(s.mkPathDepth(nodePath, i), clientv3.WithPrefix())
-	}
-	dels[maxPathDepth] = clientv3.OpPut(s.mkActionKey(), store.Delete)
-
-	resp, err := s.c.Txn(s.ctx).If(
-		clientv3.Compare(clientv3.Version(s.mkPath(nodePath)+"/"), ">", 0),
-		clientv3.Compare(clientv3.Version(s.mkPathDepth(nodePath, maxPathDepth)+"/"), "=", 0),
-	).Then(
-		dels...,
-	).Commit()
-	if err != nil {
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, etcdErr.NewError(etcdErr.EcodeNodeExist, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	dresp := resp.Responses[0].GetResponseDeleteRange()
-	return &store.Event{
-		Action:    store.Delete,
-		PrevNode:  s.mkV2Node(dresp.PrevKvs[0]),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) deleteEmptyDir(nodePath string) (*store.Event, error) {
-	resp, err := s.c.Txn(s.ctx).If(
-		clientv3.Compare(clientv3.Version(s.mkPathDepth(nodePath, 1)), "=", 0).WithPrefix(),
-	).Then(
-		clientv3.OpDelete(s.mkPath(nodePath)+"/", clientv3.WithPrevKV()),
-		clientv3.OpPut(s.mkActionKey(), store.Delete),
-	).Commit()
-	if err != nil {
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, etcdErr.NewError(etcdErr.EcodeDirNotEmpty, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	dresp := resp.Responses[0].GetResponseDeleteRange()
-	if len(dresp.PrevKvs) == 0 {
-		return nil, etcdErr.NewError(etcdErr.EcodeNodeExist, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	return &store.Event{
-		Action:    store.Delete,
-		PrevNode:  s.mkV2Node(dresp.PrevKvs[0]),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) deleteNode(nodePath string) (*store.Event, error) {
-	resp, err := s.c.Txn(s.ctx).If(
-		clientv3.Compare(clientv3.Version(s.mkPath(nodePath)+"/"), "=", 0),
-	).Then(
-		clientv3.OpDelete(s.mkPath(nodePath), clientv3.WithPrevKV()),
-		clientv3.OpPut(s.mkActionKey(), store.Delete),
-	).Commit()
-	if err != nil {
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, etcdErr.NewError(etcdErr.EcodeNotFile, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	pkvs := resp.Responses[0].GetResponseDeleteRange().PrevKvs
-	if len(pkvs) == 0 {
-		return nil, etcdErr.NewError(etcdErr.EcodeKeyNotFound, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	pkv := pkvs[0]
-	return &store.Event{
-		Action: store.Delete,
-		Node: &store.NodeExtern{
-			Key:           nodePath,
-			CreatedIndex:  mkV2Rev(pkv.CreateRevision),
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-		},
-		PrevNode:  s.mkV2Node(pkv),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) CompareAndDelete(nodePath, prevValue string, prevIndex uint64) (*store.Event, error) {
-	if isRoot(nodePath) {
-		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, nodePath, 0)
-	}
-
-	key := s.mkPath(nodePath)
-	resp, err := s.c.Txn(s.ctx).If(
-		s.mkCompare(nodePath, prevValue, prevIndex)...,
-	).Then(
-		clientv3.OpDelete(key, clientv3.WithPrevKV()),
-		clientv3.OpPut(s.mkActionKey(), store.CompareAndDelete),
-	).Else(
-		clientv3.OpGet(key),
-		clientv3.OpGet(key+"/"),
-	).Commit()
-
-	if err != nil {
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, compareFail(nodePath, prevValue, prevIndex, resp)
-	}
-
-	// len(pkvs) > 1 since txn only succeeds when key exists
-	pkv := resp.Responses[0].GetResponseDeleteRange().PrevKvs[0]
-	return &store.Event{
-		Action: store.CompareAndDelete,
-		Node: &store.NodeExtern{
-			Key:           nodePath,
-			CreatedIndex:  mkV2Rev(pkv.CreateRevision),
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-		},
-		PrevNode:  s.mkV2Node(pkv),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func compareFail(nodePath, prevValue string, prevIndex uint64, resp *clientv3.TxnResponse) error {
-	if dkvs := resp.Responses[1].GetResponseRange().Kvs; len(dkvs) > 0 {
-		return etcdErr.NewError(etcdErr.EcodeNotFile, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	kvs := resp.Responses[0].GetResponseRange().Kvs
-	if len(kvs) == 0 {
-		return etcdErr.NewError(etcdErr.EcodeKeyNotFound, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	kv := kvs[0]
-	indexMatch := (prevIndex == 0 || kv.ModRevision == int64(prevIndex))
-	valueMatch := (prevValue == "" || string(kv.Value) == prevValue)
-	var cause string
-	switch {
-	case indexMatch && !valueMatch:
-		cause = fmt.Sprintf("[%v != %v]", prevValue, string(kv.Value))
-	case valueMatch && !indexMatch:
-		cause = fmt.Sprintf("[%v != %v]", prevIndex, kv.ModRevision)
-	default:
-		cause = fmt.Sprintf("[%v != %v] [%v != %v]", prevValue, string(kv.Value), prevIndex, kv.ModRevision)
-	}
-	return etcdErr.NewError(etcdErr.EcodeTestFailed, cause, mkV2Rev(resp.Header.Revision))
-}
-
-func (s *v2v3Store) mkCompare(nodePath, prevValue string, prevIndex uint64) []clientv3.Cmp {
-	key := s.mkPath(nodePath)
-	cmps := []clientv3.Cmp{clientv3.Compare(clientv3.Version(key), ">", 0)}
-	if prevIndex != 0 {
-		cmps = append(cmps, clientv3.Compare(clientv3.ModRevision(key), "=", mkV3Rev(prevIndex)))
-	}
-	if prevValue != "" {
-		cmps = append(cmps, clientv3.Compare(clientv3.Value(key), "=", prevValue))
-	}
-	return cmps
-}
-
-func (s *v2v3Store) JsonStats() []byte                  { panic("STUB") }
-func (s *v2v3Store) DeleteExpiredKeys(cutoff time.Time) { panic("STUB") }
-
-func (s *v2v3Store) Version() int { return 2 }
-
-// TODO: move this out of the Store interface?
-
-func (s *v2v3Store) Save() ([]byte, error)       { panic("STUB") }
-func (s *v2v3Store) Recovery(state []byte) error { panic("STUB") }
-func (s *v2v3Store) Clone() store.Store          { panic("STUB") }
-func (s *v2v3Store) SaveNoCopy() ([]byte, error) { panic("STUB") }
-func (s *v2v3Store) HasTTLKeys() bool            { panic("STUB") }
-
-func (s *v2v3Store) mkPath(nodePath string) string { return s.mkPathDepth(nodePath, 0) }
-
-func (s *v2v3Store) mkNodePath(p string) string {
-	return path.Clean(p[len(s.pfx)+len("/k/000/"):])
-}
-
-// mkPathDepth makes a path to a key that encodes its directory depth
-// for fast directory listing. If a depth is provided, it is added
-// to the computed depth.
-func (s *v2v3Store) mkPathDepth(nodePath string, depth int) string {
-	normalForm := path.Clean(path.Join("/", nodePath))
-	n := strings.Count(normalForm, "/") + depth
-	return fmt.Sprintf("%s/%03d/k/%s", s.pfx, n, normalForm)
-}
-
-func (s *v2v3Store) mkActionKey() string { return s.pfx + "/act" }
-
-func isRoot(s string) bool { return len(s) == 0 || s == "/" || s == "/0" || s == "/1" }
-
-func mkV2Rev(v3Rev int64) uint64 {
-	if v3Rev == 0 {
-		return 0
-	}
-	return uint64(v3Rev - 1)
-}
-
-func mkV3Rev(v2Rev uint64) int64 {
-	if v2Rev == 0 {
-		return 0
-	}
-	return int64(v2Rev + 1)
-}
-
-// mkV2Node creates a V2 NodeExtern from a V3 KeyValue
-func (s *v2v3Store) mkV2Node(kv *mvccpb.KeyValue) *store.NodeExtern {
-	if kv == nil {
-		return nil
-	}
-	n := &store.NodeExtern{
-		Key:           string(s.mkNodePath(string(kv.Key))),
-		Dir:           kv.Key[len(kv.Key)-1] == '/',
-		CreatedIndex:  mkV2Rev(kv.CreateRevision),
-		ModifiedIndex: mkV2Rev(kv.ModRevision),
-	}
-	if !n.Dir {
-		v := string(kv.Value)
-		n.Value = &v
-	}
-	return n
-}
-
-// prevKeyFromPuts gets the prev key that is being put; ignores
-// the put action response.
-func prevKeyFromPuts(resp *clientv3.TxnResponse) *mvccpb.KeyValue {
-	for _, r := range resp.Responses {
-		pkv := r.GetResponsePut().PrevKv
-		if pkv != nil && pkv.CreateRevision > 0 {
-			return pkv
-		}
-	}
-	return nil
-}
-
-func (s *v2v3Store) newSTM(applyf func(concurrency.STM) error) (*clientv3.TxnResponse, error) {
-	return concurrency.NewSTM(s.c, applyf, concurrency.WithIsolation(concurrency.Serializable))
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/watcher.go b/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/watcher.go
deleted file mode 100644
index 1c2680e..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v2v3/watcher.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v2v3
-
-import (
-	"context"
-	"strings"
-
-	"github.com/coreos/etcd/clientv3"
-	etcdErr "github.com/coreos/etcd/error"
-	"github.com/coreos/etcd/store"
-)
-
-func (s *v2v3Store) Watch(prefix string, recursive, stream bool, sinceIndex uint64) (store.Watcher, error) {
-	ctx, cancel := context.WithCancel(s.ctx)
-	wch := s.c.Watch(
-		ctx,
-		// TODO: very pricey; use a single store-wide watch in future
-		s.pfx,
-		clientv3.WithPrefix(),
-		clientv3.WithRev(int64(sinceIndex)),
-		clientv3.WithCreatedNotify(),
-		clientv3.WithPrevKV())
-	resp, ok := <-wch
-	if err := resp.Err(); err != nil || !ok {
-		cancel()
-		return nil, etcdErr.NewError(etcdErr.EcodeRaftInternal, prefix, 0)
-	}
-
-	evc, donec := make(chan *store.Event), make(chan struct{})
-	go func() {
-		defer func() {
-			close(evc)
-			close(donec)
-		}()
-		for resp := range wch {
-			for _, ev := range s.mkV2Events(resp) {
-				k := ev.Node.Key
-				if recursive {
-					if !strings.HasPrefix(k, prefix) {
-						continue
-					}
-					// accept events on hidden keys given in prefix
-					k = strings.Replace(k, prefix, "/", 1)
-					// ignore hidden keys deeper than prefix
-					if strings.Contains(k, "/_") {
-						continue
-					}
-				}
-				if !recursive && k != prefix {
-					continue
-				}
-				select {
-				case evc <- ev:
-				case <-ctx.Done():
-					return
-				}
-				if !stream {
-					return
-				}
-			}
-		}
-	}()
-
-	return &v2v3Watcher{
-		startRev: resp.Header.Revision,
-		evc:      evc,
-		donec:    donec,
-		cancel:   cancel,
-	}, nil
-}
-
-func (s *v2v3Store) mkV2Events(wr clientv3.WatchResponse) (evs []*store.Event) {
-	ak := s.mkActionKey()
-	for _, rev := range mkRevs(wr) {
-		var act, key *clientv3.Event
-		for _, ev := range rev {
-			if string(ev.Kv.Key) == ak {
-				act = ev
-			} else if key != nil && len(key.Kv.Key) < len(ev.Kv.Key) {
-				// use longest key to ignore intermediate new
-				// directories from Create.
-				key = ev
-			} else if key == nil {
-				key = ev
-			}
-		}
-		v2ev := &store.Event{
-			Action:    string(act.Kv.Value),
-			Node:      s.mkV2Node(key.Kv),
-			PrevNode:  s.mkV2Node(key.PrevKv),
-			EtcdIndex: mkV2Rev(wr.Header.Revision),
-		}
-		evs = append(evs, v2ev)
-	}
-	return evs
-}
-
-func mkRevs(wr clientv3.WatchResponse) (revs [][]*clientv3.Event) {
-	var curRev []*clientv3.Event
-	for _, ev := range wr.Events {
-		if curRev != nil && ev.Kv.ModRevision != curRev[0].Kv.ModRevision {
-			revs = append(revs, curRev)
-			curRev = nil
-		}
-		curRev = append(curRev, ev)
-	}
-	if curRev != nil {
-		revs = append(revs, curRev)
-	}
-	return revs
-}
-
-type v2v3Watcher struct {
-	startRev int64
-	evc      chan *store.Event
-	donec    chan struct{}
-	cancel   context.CancelFunc
-}
-
-func (w *v2v3Watcher) StartIndex() uint64 { return mkV2Rev(w.startRev) }
-
-func (w *v2v3Watcher) Remove() {
-	w.cancel()
-	<-w.donec
-}
-
-func (w *v2v3Watcher) EventChan() chan *store.Event { return w.evc }
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3client/doc.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3client/doc.go
deleted file mode 100644
index 310715f..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3client/doc.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package v3client provides clientv3 interfaces from an etcdserver.
-//
-// Use v3client by creating an EtcdServer instance, then wrapping it with v3client.New:
-//
-//	import (
-//		"context"
-//
-//		"github.com/coreos/etcd/embed"
-//		"github.com/coreos/etcd/etcdserver/api/v3client"
-//	)
-//
-//	...
-//
-//	// create an embedded EtcdServer from the default configuration
-//	cfg := embed.NewConfig()
-//	cfg.Dir = "default.etcd"
-//	e, err := embed.StartEtcd(cfg)
-//	if err != nil {
-//		// handle error!
-//	}
-//
-//	// wrap the EtcdServer with v3client
-//	cli := v3client.New(e.Server)
-//
-//	// use like an ordinary clientv3
-//	resp, err := cli.Put(context.TODO(), "some-key", "it works!")
-//	if err != nil {
-//		// handle error!
-//	}
-//
-package v3client
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3client/v3client.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3client/v3client.go
deleted file mode 100644
index ab48ea7..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3client/v3client.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3client
-
-import (
-	"context"
-	"time"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc"
-	"github.com/coreos/etcd/proxy/grpcproxy/adapter"
-)
-
-// New creates a clientv3 client that wraps an in-process EtcdServer. Instead
-// of making gRPC calls through sockets, the client makes direct function calls
-// to the etcd server through its api/v3rpc function interfaces.
-func New(s *etcdserver.EtcdServer) *clientv3.Client {
-	c := clientv3.NewCtxClient(context.Background())
-
-	kvc := adapter.KvServerToKvClient(v3rpc.NewQuotaKVServer(s))
-	c.KV = clientv3.NewKVFromKVClient(kvc, c)
-
-	lc := adapter.LeaseServerToLeaseClient(v3rpc.NewQuotaLeaseServer(s))
-	c.Lease = clientv3.NewLeaseFromLeaseClient(lc, c, time.Second)
-
-	wc := adapter.WatchServerToWatchClient(v3rpc.NewWatchServer(s))
-	c.Watcher = &watchWrapper{clientv3.NewWatchFromWatchClient(wc, c)}
-
-	mc := adapter.MaintenanceServerToMaintenanceClient(v3rpc.NewMaintenanceServer(s))
-	c.Maintenance = clientv3.NewMaintenanceFromMaintenanceClient(mc, c)
-
-	clc := adapter.ClusterServerToClusterClient(v3rpc.NewClusterServer(s))
-	c.Cluster = clientv3.NewClusterFromClusterClient(clc, c)
-
-	// TODO: implement clientv3.Auth interface?
-
-	return c
-}
-
-// BlankContext implements Stringer on a context so the ctx string doesn't
-// depend on the context's WithValue data, which tends to be unsynchronized
-// (e.g., x/net/trace), causing ctx.String() to throw data races.
-type blankContext struct{ context.Context }
-
-func (*blankContext) String() string { return "(blankCtx)" }
-
-// watchWrapper wraps clientv3 watch calls to blank out the context
-// to avoid races on trace data.
-type watchWrapper struct{ clientv3.Watcher }
-
-func (ww *watchWrapper) Watch(ctx context.Context, key string, opts ...clientv3.OpOption) clientv3.WatchChan {
-	return ww.Watcher.Watch(&blankContext{ctx}, key, opts...)
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3election/doc.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3election/doc.go
deleted file mode 100644
index d6fefd7..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3election/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package v3election provides a v3 election service from an etcdserver.
-package v3election
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3election/election.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3election/election.go
deleted file mode 100644
index c66d7a3..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3election/election.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3election
-
-import (
-	"context"
-	"errors"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/clientv3/concurrency"
-	epb "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb"
-)
-
-// ErrMissingLeaderKey is returned when election API request
-// is missing the "leader" field.
-var ErrMissingLeaderKey = errors.New(`"leader" field must be provided`)
-
-type electionServer struct {
-	c *clientv3.Client
-}
-
-func NewElectionServer(c *clientv3.Client) epb.ElectionServer {
-	return &electionServer{c}
-}
-
-func (es *electionServer) Campaign(ctx context.Context, req *epb.CampaignRequest) (*epb.CampaignResponse, error) {
-	s, err := es.session(ctx, req.Lease)
-	if err != nil {
-		return nil, err
-	}
-	e := concurrency.NewElection(s, string(req.Name))
-	if err = e.Campaign(ctx, string(req.Value)); err != nil {
-		return nil, err
-	}
-	return &epb.CampaignResponse{
-		Header: e.Header(),
-		Leader: &epb.LeaderKey{
-			Name:  req.Name,
-			Key:   []byte(e.Key()),
-			Rev:   e.Rev(),
-			Lease: int64(s.Lease()),
-		},
-	}, nil
-}
-
-func (es *electionServer) Proclaim(ctx context.Context, req *epb.ProclaimRequest) (*epb.ProclaimResponse, error) {
-	if req.Leader == nil {
-		return nil, ErrMissingLeaderKey
-	}
-	s, err := es.session(ctx, req.Leader.Lease)
-	if err != nil {
-		return nil, err
-	}
-	e := concurrency.ResumeElection(s, string(req.Leader.Name), string(req.Leader.Key), req.Leader.Rev)
-	if err := e.Proclaim(ctx, string(req.Value)); err != nil {
-		return nil, err
-	}
-	return &epb.ProclaimResponse{Header: e.Header()}, nil
-}
-
-func (es *electionServer) Observe(req *epb.LeaderRequest, stream epb.Election_ObserveServer) error {
-	s, err := es.session(stream.Context(), -1)
-	if err != nil {
-		return err
-	}
-	e := concurrency.NewElection(s, string(req.Name))
-	ch := e.Observe(stream.Context())
-	for stream.Context().Err() == nil {
-		select {
-		case <-stream.Context().Done():
-		case resp, ok := <-ch:
-			if !ok {
-				return nil
-			}
-			lresp := &epb.LeaderResponse{Header: resp.Header, Kv: resp.Kvs[0]}
-			if err := stream.Send(lresp); err != nil {
-				return err
-			}
-		}
-	}
-	return stream.Context().Err()
-}
-
-func (es *electionServer) Leader(ctx context.Context, req *epb.LeaderRequest) (*epb.LeaderResponse, error) {
-	s, err := es.session(ctx, -1)
-	if err != nil {
-		return nil, err
-	}
-	l, lerr := concurrency.NewElection(s, string(req.Name)).Leader(ctx)
-	if lerr != nil {
-		return nil, lerr
-	}
-	return &epb.LeaderResponse{Header: l.Header, Kv: l.Kvs[0]}, nil
-}
-
-func (es *electionServer) Resign(ctx context.Context, req *epb.ResignRequest) (*epb.ResignResponse, error) {
-	if req.Leader == nil {
-		return nil, ErrMissingLeaderKey
-	}
-	s, err := es.session(ctx, req.Leader.Lease)
-	if err != nil {
-		return nil, err
-	}
-	e := concurrency.ResumeElection(s, string(req.Leader.Name), string(req.Leader.Key), req.Leader.Rev)
-	if err := e.Resign(ctx); err != nil {
-		return nil, err
-	}
-	return &epb.ResignResponse{Header: e.Header()}, nil
-}
-
-func (es *electionServer) session(ctx context.Context, lease int64) (*concurrency.Session, error) {
-	s, err := concurrency.NewSession(
-		es.c,
-		concurrency.WithLease(clientv3.LeaseID(lease)),
-		concurrency.WithContext(ctx),
-	)
-	if err != nil {
-		return nil, err
-	}
-	s.Orphan()
-	return s, nil
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/gw/v3election.pb.gw.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/gw/v3election.pb.gw.go
deleted file mode 100644
index 58368bb..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/gw/v3election.pb.gw.go
+++ /dev/null
@@ -1,313 +0,0 @@
-// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
-// source: etcdserver/api/v3election/v3electionpb/v3election.proto
-
-/*
-Package v3electionpb is a reverse proxy.
-
-It translates gRPC into RESTful JSON APIs.
-*/
-package gw
-
-import (
-	"github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb"
-	"io"
-	"net/http"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/grpc-ecosystem/grpc-gateway/runtime"
-	"github.com/grpc-ecosystem/grpc-gateway/utilities"
-	"golang.org/x/net/context"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/grpclog"
-	"google.golang.org/grpc/status"
-)
-
-var _ codes.Code
-var _ io.Reader
-var _ status.Status
-var _ = runtime.String
-var _ = utilities.NewDoubleArray
-
-func request_Election_Campaign_0(ctx context.Context, marshaler runtime.Marshaler, client v3electionpb.ElectionClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3electionpb.CampaignRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Campaign(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Election_Proclaim_0(ctx context.Context, marshaler runtime.Marshaler, client v3electionpb.ElectionClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3electionpb.ProclaimRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Proclaim(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Election_Leader_0(ctx context.Context, marshaler runtime.Marshaler, client v3electionpb.ElectionClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3electionpb.LeaderRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Leader(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Election_Observe_0(ctx context.Context, marshaler runtime.Marshaler, client v3electionpb.ElectionClient, req *http.Request, pathParams map[string]string) (v3electionpb.Election_ObserveClient, runtime.ServerMetadata, error) {
-	var protoReq v3electionpb.LeaderRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	stream, err := client.Observe(ctx, &protoReq)
-	if err != nil {
-		return nil, metadata, err
-	}
-	header, err := stream.Header()
-	if err != nil {
-		return nil, metadata, err
-	}
-	metadata.HeaderMD = header
-	return stream, metadata, nil
-
-}
-
-func request_Election_Resign_0(ctx context.Context, marshaler runtime.Marshaler, client v3electionpb.ElectionClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3electionpb.ResignRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Resign(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-// RegisterElectionHandlerFromEndpoint is same as RegisterElectionHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterElectionHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if err != nil {
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-			return
-		}
-		go func() {
-			<-ctx.Done()
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-		}()
-	}()
-
-	return RegisterElectionHandler(ctx, mux, conn)
-}
-
-// RegisterElectionHandler registers the http handlers for service Election to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterElectionHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterElectionHandlerClient(ctx, mux, v3electionpb.NewElectionClient(conn))
-}
-
-// RegisterElectionHandler registers the http handlers for service Election to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "ElectionClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ElectionClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "ElectionClient" to call the correct interceptors.
-func RegisterElectionHandlerClient(ctx context.Context, mux *runtime.ServeMux, client v3electionpb.ElectionClient) error {
-
-	mux.Handle("POST", pattern_Election_Campaign_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Election_Campaign_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Election_Campaign_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Election_Proclaim_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Election_Proclaim_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Election_Proclaim_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Election_Leader_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Election_Leader_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Election_Leader_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Election_Observe_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Election_Observe_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Election_Observe_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Election_Resign_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Election_Resign_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Election_Resign_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Election_Campaign_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "election", "campaign"}, ""))
-
-	pattern_Election_Proclaim_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "election", "proclaim"}, ""))
-
-	pattern_Election_Leader_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "election", "leader"}, ""))
-
-	pattern_Election_Observe_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "election", "observe"}, ""))
-
-	pattern_Election_Resign_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "election", "resign"}, ""))
-)
-
-var (
-	forward_Election_Campaign_0 = runtime.ForwardResponseMessage
-
-	forward_Election_Proclaim_0 = runtime.ForwardResponseMessage
-
-	forward_Election_Leader_0 = runtime.ForwardResponseMessage
-
-	forward_Election_Observe_0 = runtime.ForwardResponseStream
-
-	forward_Election_Resign_0 = runtime.ForwardResponseMessage
-)
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/v3election.proto b/vendor/github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/v3election.proto
deleted file mode 100644
index cb475b8..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/v3election.proto
+++ /dev/null
@@ -1,119 +0,0 @@
-syntax = "proto3";
-package v3electionpb;
-
-import "gogoproto/gogo.proto";
-import "etcd/etcdserver/etcdserverpb/rpc.proto";
-import "etcd/mvcc/mvccpb/kv.proto";
-
-// for grpc-gateway
-import "google/api/annotations.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-
-// The election service exposes client-side election facilities as a gRPC interface.
-service Election {
-  // Campaign waits to acquire leadership in an election, returning a LeaderKey
-  // representing the leadership if successful. The LeaderKey can then be used
-  // to issue new values on the election, transactionally guard API requests on
-  // leadership still being held, and resign from the election.
-  rpc Campaign(CampaignRequest) returns (CampaignResponse) {
-      option (google.api.http) = {
-        post: "/v3beta/election/campaign"
-        body: "*"
-    };
-  }
-  // Proclaim updates the leader's posted value with a new value.
-  rpc Proclaim(ProclaimRequest) returns (ProclaimResponse) {
-      option (google.api.http) = {
-        post: "/v3beta/election/proclaim"
-        body: "*"
-    };
-  }
-  // Leader returns the current election proclamation, if any.
-  rpc Leader(LeaderRequest) returns (LeaderResponse) {
-      option (google.api.http) = {
-        post: "/v3beta/election/leader"
-        body: "*"
-    };
-  }
-  // Observe streams election proclamations in-order as made by the election's
-  // elected leaders.
-  rpc Observe(LeaderRequest) returns (stream LeaderResponse) {
-      option (google.api.http) = {
-        post: "/v3beta/election/observe"
-        body: "*"
-    };
-  }
-  // Resign releases election leadership so other campaigners may acquire
-  // leadership on the election.
-  rpc Resign(ResignRequest) returns (ResignResponse) {
-      option (google.api.http) = {
-        post: "/v3beta/election/resign"
-        body: "*"
-    };
-  }
-}
-
-message CampaignRequest {
-  // name is the election's identifier for the campaign.
-  bytes name = 1;
-  // lease is the ID of the lease attached to leadership of the election. If the
-  // lease expires or is revoked before resigning leadership, then the
-  // leadership is transferred to the next campaigner, if any.
-  int64 lease = 2;
-  // value is the initial proclaimed value set when the campaigner wins the
-  // election.
-  bytes value = 3;
-}
-
-message CampaignResponse {
-  etcdserverpb.ResponseHeader header = 1;
-  // leader describes the resources used for holding leadereship of the election.
-  LeaderKey leader = 2;
-}
-
-message LeaderKey {
-  // name is the election identifier that correponds to the leadership key.
-  bytes name = 1;
-  // key is an opaque key representing the ownership of the election. If the key
-  // is deleted, then leadership is lost.
-  bytes key = 2;
-  // rev is the creation revision of the key. It can be used to test for ownership
-  // of an election during transactions by testing the key's creation revision
-  // matches rev.
-  int64 rev = 3;
-  // lease is the lease ID of the election leader.
-  int64 lease = 4;
-}
-
-message LeaderRequest {
-  // name is the election identifier for the leadership information.
-  bytes name = 1;
-}
-
-message LeaderResponse {
-  etcdserverpb.ResponseHeader header = 1;
-  // kv is the key-value pair representing the latest leader update.
-  mvccpb.KeyValue kv = 2;
-}
-
-message ResignRequest {
-  // leader is the leadership to relinquish by resignation.
-  LeaderKey leader = 1;
-}
-
-message ResignResponse {
-  etcdserverpb.ResponseHeader header = 1;
-}
-
-message ProclaimRequest {
-  // leader is the leadership hold on the election.
-  LeaderKey leader = 1;
-  // value is an update meant to overwrite the leader's current value.
-  bytes value = 2;
-}
-
-message ProclaimResponse {
-  etcdserverpb.ResponseHeader header = 1;
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/doc.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/doc.go
deleted file mode 100644
index e0a1008..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package v3lock provides a v3 locking service from an etcdserver.
-package v3lock
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/lock.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/lock.go
deleted file mode 100644
index a5efcba..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/lock.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3lock
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/clientv3/concurrency"
-	"github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb"
-)
-
-type lockServer struct {
-	c *clientv3.Client
-}
-
-func NewLockServer(c *clientv3.Client) v3lockpb.LockServer {
-	return &lockServer{c}
-}
-
-func (ls *lockServer) Lock(ctx context.Context, req *v3lockpb.LockRequest) (*v3lockpb.LockResponse, error) {
-	s, err := concurrency.NewSession(
-		ls.c,
-		concurrency.WithLease(clientv3.LeaseID(req.Lease)),
-		concurrency.WithContext(ctx),
-	)
-	if err != nil {
-		return nil, err
-	}
-	s.Orphan()
-	m := concurrency.NewMutex(s, string(req.Name))
-	if err = m.Lock(ctx); err != nil {
-		return nil, err
-	}
-	return &v3lockpb.LockResponse{Header: m.Header(), Key: []byte(m.Key())}, nil
-}
-
-func (ls *lockServer) Unlock(ctx context.Context, req *v3lockpb.UnlockRequest) (*v3lockpb.UnlockResponse, error) {
-	resp, err := ls.c.Delete(ctx, string(req.Key))
-	if err != nil {
-		return nil, err
-	}
-	return &v3lockpb.UnlockResponse{Header: resp.Header}, nil
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/gw/v3lock.pb.gw.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/gw/v3lock.pb.gw.go
deleted file mode 100644
index efecc45..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/gw/v3lock.pb.gw.go
+++ /dev/null
@@ -1,167 +0,0 @@
-// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
-// source: etcdserver/api/v3lock/v3lockpb/v3lock.proto
-
-/*
-Package v3lockpb is a reverse proxy.
-
-It translates gRPC into RESTful JSON APIs.
-*/
-package gw
-
-import (
-	"github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb"
-	"io"
-	"net/http"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/grpc-ecosystem/grpc-gateway/runtime"
-	"github.com/grpc-ecosystem/grpc-gateway/utilities"
-	"golang.org/x/net/context"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/grpclog"
-	"google.golang.org/grpc/status"
-)
-
-var _ codes.Code
-var _ io.Reader
-var _ status.Status
-var _ = runtime.String
-var _ = utilities.NewDoubleArray
-
-func request_Lock_Lock_0(ctx context.Context, marshaler runtime.Marshaler, client v3lockpb.LockClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3lockpb.LockRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Lock(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lock_Unlock_0(ctx context.Context, marshaler runtime.Marshaler, client v3lockpb.LockClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3lockpb.UnlockRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Unlock(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-// RegisterLockHandlerFromEndpoint is same as RegisterLockHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterLockHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if err != nil {
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-			return
-		}
-		go func() {
-			<-ctx.Done()
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-		}()
-	}()
-
-	return RegisterLockHandler(ctx, mux, conn)
-}
-
-// RegisterLockHandler registers the http handlers for service Lock to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterLockHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterLockHandlerClient(ctx, mux, v3lockpb.NewLockClient(conn))
-}
-
-// RegisterLockHandler registers the http handlers for service Lock to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "LockClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "LockClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "LockClient" to call the correct interceptors.
-func RegisterLockHandlerClient(ctx context.Context, mux *runtime.ServeMux, client v3lockpb.LockClient) error {
-
-	mux.Handle("POST", pattern_Lock_Lock_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Lock_Lock_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lock_Lock_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lock_Unlock_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Lock_Unlock_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lock_Unlock_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Lock_Lock_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 1}, []string{"v3beta", "lock"}, ""))
-
-	pattern_Lock_Unlock_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "lock", "unlock"}, ""))
-)
-
-var (
-	forward_Lock_Lock_0 = runtime.ForwardResponseMessage
-
-	forward_Lock_Unlock_0 = runtime.ForwardResponseMessage
-)
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/v3lock.proto b/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/v3lock.proto
deleted file mode 100644
index 44b698d..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/v3lock.proto
+++ /dev/null
@@ -1,65 +0,0 @@
-syntax = "proto3";
-package v3lockpb;
-
-import "gogoproto/gogo.proto";
-import "etcd/etcdserver/etcdserverpb/rpc.proto";
-
-// for grpc-gateway
-import "google/api/annotations.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-
-// The lock service exposes client-side locking facilities as a gRPC interface.
-service Lock {
-  // Lock acquires a distributed shared lock on a given named lock.
-  // On success, it will return a unique key that exists so long as the
-  // lock is held by the caller. This key can be used in conjunction with
-  // transactions to safely ensure updates to etcd only occur while holding
-  // lock ownership. The lock is held until Unlock is called on the key or the
-  // lease associate with the owner expires.
-  rpc Lock(LockRequest) returns (LockResponse) {
-      option (google.api.http) = {
-        post: "/v3beta/lock/lock"
-        body: "*"
-    };
-  }
-
-  // Unlock takes a key returned by Lock and releases the hold on lock. The
-  // next Lock caller waiting for the lock will then be woken up and given
-  // ownership of the lock.
-  rpc Unlock(UnlockRequest) returns (UnlockResponse) {
-      option (google.api.http) = {
-        post: "/v3beta/lock/unlock"
-        body: "*"
-    };
-  }
-}
-
-message LockRequest {
-  // name is the identifier for the distributed shared lock to be acquired.
-  bytes name = 1;
-  // lease is the ID of the lease that will be attached to ownership of the
-  // lock. If the lease expires or is revoked and currently holds the lock,
-  // the lock is automatically released. Calls to Lock with the same lease will
-  // be treated as a single acquistion; locking twice with the same lease is a
-  // no-op.
-  int64 lease = 2;
-}
-
-message LockResponse {
-  etcdserverpb.ResponseHeader header = 1;
-  // key is a key that will exist on etcd for the duration that the Lock caller
-  // owns the lock. Users should not modify this key or the lock may exhibit
-  // undefined behavior.
-  bytes key = 2;
-}
-
-message UnlockRequest {
-  // key is the lock ownership key granted by Lock.
-  bytes key = 1;
-}
-
-message UnlockResponse {
-  etcdserverpb.ResponseHeader header = 1;
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go
deleted file mode 100644
index ca8e53a..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/etcdserver"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-type AuthServer struct {
-	authenticator etcdserver.Authenticator
-}
-
-func NewAuthServer(s *etcdserver.EtcdServer) *AuthServer {
-	return &AuthServer{authenticator: s}
-}
-
-func (as *AuthServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) {
-	resp, err := as.authenticator.AuthEnable(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) {
-	resp, err := as.authenticator.AuthDisable(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
-	resp, err := as.authenticator.Authenticate(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
-	resp, err := as.authenticator.RoleAdd(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) {
-	resp, err := as.authenticator.RoleDelete(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	resp, err := as.authenticator.RoleGet(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
-	resp, err := as.authenticator.RoleList(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
-	resp, err := as.authenticator.RoleRevokePermission(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
-	resp, err := as.authenticator.RoleGrantPermission(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
-	resp, err := as.authenticator.UserAdd(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
-	resp, err := as.authenticator.UserDelete(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	resp, err := as.authenticator.UserGet(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
-	resp, err := as.authenticator.UserList(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
-	resp, err := as.authenticator.UserGrantRole(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
-	resp, err := as.authenticator.UserRevokeRole(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
-	resp, err := as.authenticator.UserChangePassword(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/codec.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/codec.go
deleted file mode 100644
index 17a2c87..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/codec.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import "github.com/gogo/protobuf/proto"
-
-type codec struct{}
-
-func (c *codec) Marshal(v interface{}) ([]byte, error) {
-	b, err := proto.Marshal(v.(proto.Message))
-	sentBytes.Add(float64(len(b)))
-	return b, err
-}
-
-func (c *codec) Unmarshal(data []byte, v interface{}) error {
-	receivedBytes.Add(float64(len(data)))
-	return proto.Unmarshal(data, v.(proto.Message))
-}
-
-func (c *codec) String() string {
-	return "proto"
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go
deleted file mode 100644
index c97e746..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import (
-	"crypto/tls"
-	"math"
-
-	"github.com/coreos/etcd/etcdserver"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"github.com/grpc-ecosystem/go-grpc-middleware"
-	"github.com/grpc-ecosystem/go-grpc-prometheus"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/credentials"
-	"google.golang.org/grpc/health"
-	healthpb "google.golang.org/grpc/health/grpc_health_v1"
-)
-
-const (
-	grpcOverheadBytes = 512 * 1024
-	maxStreams        = math.MaxUint32
-	maxSendBytes      = math.MaxInt32
-)
-
-func Server(s *etcdserver.EtcdServer, tls *tls.Config, gopts ...grpc.ServerOption) *grpc.Server {
-	var opts []grpc.ServerOption
-	opts = append(opts, grpc.CustomCodec(&codec{}))
-	if tls != nil {
-		opts = append(opts, grpc.Creds(credentials.NewTLS(tls)))
-	}
-	opts = append(opts, grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
-		newLogUnaryInterceptor(s),
-		newUnaryInterceptor(s),
-		grpc_prometheus.UnaryServerInterceptor,
-	)))
-	opts = append(opts, grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
-		newStreamInterceptor(s),
-		grpc_prometheus.StreamServerInterceptor,
-	)))
-	opts = append(opts, grpc.MaxRecvMsgSize(int(s.Cfg.MaxRequestBytes+grpcOverheadBytes)))
-	opts = append(opts, grpc.MaxSendMsgSize(maxSendBytes))
-	opts = append(opts, grpc.MaxConcurrentStreams(maxStreams))
-	grpcServer := grpc.NewServer(append(opts, gopts...)...)
-
-	pb.RegisterKVServer(grpcServer, NewQuotaKVServer(s))
-	pb.RegisterWatchServer(grpcServer, NewWatchServer(s))
-	pb.RegisterLeaseServer(grpcServer, NewQuotaLeaseServer(s))
-	pb.RegisterClusterServer(grpcServer, NewClusterServer(s))
-	pb.RegisterAuthServer(grpcServer, NewAuthServer(s))
-	pb.RegisterMaintenanceServer(grpcServer, NewMaintenanceServer(s))
-
-	// server should register all the services manually
-	// use empty service name for all etcd services' health status,
-	// see https://github.com/grpc/grpc/blob/master/doc/health-checking.md for more
-	hsrv := health.NewServer()
-	hsrv.SetServingStatus("", healthpb.HealthCheckResponse_SERVING)
-	healthpb.RegisterHealthServer(grpcServer, hsrv)
-
-	// set zero values for metrics registered for this grpc server
-	grpc_prometheus.Register(grpcServer)
-
-	return grpcServer
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go
deleted file mode 100644
index 75da52f..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import (
-	"github.com/coreos/etcd/etcdserver"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-type header struct {
-	clusterID int64
-	memberID  int64
-	raftTimer etcdserver.RaftTimer
-	rev       func() int64
-}
-
-func newHeader(s *etcdserver.EtcdServer) header {
-	return header{
-		clusterID: int64(s.Cluster().ID()),
-		memberID:  int64(s.ID()),
-		raftTimer: s,
-		rev:       func() int64 { return s.KV().Rev() },
-	}
-}
-
-// fill populates pb.ResponseHeader using etcdserver information
-func (h *header) fill(rh *pb.ResponseHeader) {
-	if rh == nil {
-		plog.Panic("unexpected nil resp.Header")
-	}
-	rh.ClusterId = uint64(h.clusterID)
-	rh.MemberId = uint64(h.memberID)
-	rh.RaftTerm = h.raftTimer.Term()
-	if rh.Revision == 0 {
-		rh.Revision = h.rev()
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go
deleted file mode 100644
index d594ae7..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import (
-	"context"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"go.uber.org/zap"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/peer"
-)
-
-const (
-	maxNoLeaderCnt = 3
-)
-
-type streamsMap struct {
-	mu      sync.Mutex
-	streams map[grpc.ServerStream]struct{}
-}
-
-func newUnaryInterceptor(s *etcdserver.EtcdServer) grpc.UnaryServerInterceptor {
-	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-		if !api.IsCapabilityEnabled(api.V3rpcCapability) {
-			return nil, rpctypes.ErrGRPCNotCapable
-		}
-
-		md, ok := metadata.FromIncomingContext(ctx)
-		if ok {
-			if ks := md[rpctypes.MetadataRequireLeaderKey]; len(ks) > 0 && ks[0] == rpctypes.MetadataHasLeader {
-				if s.Leader() == types.ID(raft.None) {
-					return nil, rpctypes.ErrGRPCNoLeader
-				}
-			}
-		}
-
-		return handler(ctx, req)
-	}
-}
-
-func newLogUnaryInterceptor(s *etcdserver.EtcdServer) grpc.UnaryServerInterceptor {
-	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-		startTime := time.Now()
-		resp, err := handler(ctx, req)
-		defer logUnaryRequestStats(ctx, nil, info, startTime, req, resp)
-		return resp, err
-	}
-}
-
-func logUnaryRequestStats(ctx context.Context, lg *zap.Logger, info *grpc.UnaryServerInfo, startTime time.Time, req interface{}, resp interface{}) {
-	duration := time.Since(startTime)
-	remote := "No remote client info."
-	peerInfo, ok := peer.FromContext(ctx)
-	if ok {
-		remote = peerInfo.Addr.String()
-	}
-	var responseType string = info.FullMethod
-	var reqCount, respCount int64
-	var reqSize, respSize int
-	var reqContent string
-	switch _resp := resp.(type) {
-	case *pb.RangeResponse:
-		_req, ok := req.(*pb.RangeRequest)
-		if ok {
-			reqCount = 0
-			reqSize = _req.Size()
-			reqContent = _req.String()
-		}
-		if _resp != nil {
-			respCount = _resp.GetCount()
-			respSize = _resp.Size()
-		}
-	case *pb.PutResponse:
-		_req, ok := req.(*pb.PutRequest)
-		if ok {
-			reqCount = 1
-			reqSize = _req.Size()
-			reqContent = pb.NewLoggablePutRequest(_req).String()
-			// redact value field from request content, see PR #9821
-		}
-		if _resp != nil {
-			respCount = 0
-			respSize = _resp.Size()
-		}
-	case *pb.DeleteRangeResponse:
-		_req, ok := req.(*pb.DeleteRangeRequest)
-		if ok {
-			reqCount = 0
-			reqSize = _req.Size()
-			reqContent = _req.String()
-		}
-		if _resp != nil {
-			respCount = _resp.GetDeleted()
-			respSize = _resp.Size()
-		}
-	case *pb.TxnResponse:
-		_req, ok := req.(*pb.TxnRequest)
-		if ok && _resp != nil {
-			if _resp.GetSucceeded() { // determine the 'actual' count and size of request based on success or failure
-				reqCount = int64(len(_req.GetSuccess()))
-				reqSize = 0
-				for _, r := range _req.GetSuccess() {
-					reqSize += r.Size()
-				}
-			} else {
-				reqCount = int64(len(_req.GetFailure()))
-				reqSize = 0
-				for _, r := range _req.GetFailure() {
-					reqSize += r.Size()
-				}
-			}
-			reqContent = pb.NewLoggableTxnRequest(_req).String()
-			// redact value field from request content, see PR #9821
-		}
-		if _resp != nil {
-			respCount = 0
-			respSize = _resp.Size()
-		}
-	default:
-		reqCount = -1
-		reqSize = -1
-		respCount = -1
-		respSize = -1
-	}
-
-	logGenericRequestStats(lg, startTime, duration, remote, responseType, reqCount, reqSize, respCount, respSize, reqContent)
-}
-
-func logGenericRequestStats(lg *zap.Logger, startTime time.Time, duration time.Duration, remote string, responseType string,
-	reqCount int64, reqSize int, respCount int64, respSize int, reqContent string) {
-	if lg == nil {
-		plog.Debugf("start time = %v, "+
-			"time spent = %v, "+
-			"remote = %s, "+
-			"response type = %s, "+
-			"request count = %d, "+
-			"request size = %d, "+
-			"response count = %d, "+
-			"response size = %d, "+
-			"request content = %s",
-			startTime, duration, remote, responseType, reqCount, reqSize, respCount, respSize, reqContent,
-		)
-	} else {
-		lg.Debug("request stats",
-			zap.Time("start time", startTime),
-			zap.Duration("time spent", duration),
-			zap.String("remote", remote),
-			zap.String("response type", responseType),
-			zap.Int64("request count", reqCount),
-			zap.Int("request size", reqSize),
-			zap.Int64("response count", respCount),
-			zap.Int("response size", respSize),
-			zap.String("request content", reqContent),
-		)
-	}
-}
-
-func newStreamInterceptor(s *etcdserver.EtcdServer) grpc.StreamServerInterceptor {
-	smap := monitorLeader(s)
-
-	return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
-		if !api.IsCapabilityEnabled(api.V3rpcCapability) {
-			return rpctypes.ErrGRPCNotCapable
-		}
-
-		md, ok := metadata.FromIncomingContext(ss.Context())
-		if ok {
-			if ks := md[rpctypes.MetadataRequireLeaderKey]; len(ks) > 0 && ks[0] == rpctypes.MetadataHasLeader {
-				if s.Leader() == types.ID(raft.None) {
-					return rpctypes.ErrGRPCNoLeader
-				}
-
-				cctx, cancel := context.WithCancel(ss.Context())
-				ss = serverStreamWithCtx{ctx: cctx, cancel: &cancel, ServerStream: ss}
-
-				smap.mu.Lock()
-				smap.streams[ss] = struct{}{}
-				smap.mu.Unlock()
-
-				defer func() {
-					smap.mu.Lock()
-					delete(smap.streams, ss)
-					smap.mu.Unlock()
-					cancel()
-				}()
-
-			}
-		}
-
-		return handler(srv, ss)
-	}
-}
-
-type serverStreamWithCtx struct {
-	grpc.ServerStream
-	ctx    context.Context
-	cancel *context.CancelFunc
-}
-
-func (ssc serverStreamWithCtx) Context() context.Context { return ssc.ctx }
-
-func monitorLeader(s *etcdserver.EtcdServer) *streamsMap {
-	smap := &streamsMap{
-		streams: make(map[grpc.ServerStream]struct{}),
-	}
-
-	go func() {
-		election := time.Duration(s.Cfg.TickMs) * time.Duration(s.Cfg.ElectionTicks) * time.Millisecond
-		noLeaderCnt := 0
-
-		for {
-			select {
-			case <-s.StopNotify():
-				return
-			case <-time.After(election):
-				if s.Leader() == types.ID(raft.None) {
-					noLeaderCnt++
-				} else {
-					noLeaderCnt = 0
-				}
-
-				// We are more conservative on canceling existing streams. Reconnecting streams
-				// cost much more than just rejecting new requests. So we wait until the member
-				// cannot find a leader for maxNoLeaderCnt election timeouts to cancel existing streams.
-				if noLeaderCnt >= maxNoLeaderCnt {
-					smap.mu.Lock()
-					for ss := range smap.streams {
-						if ssWithCtx, ok := ss.(serverStreamWithCtx); ok {
-							(*ssWithCtx.cancel)()
-							<-ss.Context().Done()
-						}
-					}
-					smap.streams = make(map[grpc.ServerStream]struct{})
-					smap.mu.Unlock()
-				}
-			}
-		}
-	}()
-
-	return smap
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go
deleted file mode 100644
index 9781bdd..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package v3rpc implements etcd v3 RPC system based on gRPC.
-package v3rpc
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/pkg/adt"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/api/v3rpc")
-)
-
-type kvServer struct {
-	hdr header
-	kv  etcdserver.RaftKV
-	// maxTxnOps is the max operations per txn.
-	// e.g suppose maxTxnOps = 128.
-	// Txn.Success can have at most 128 operations,
-	// and Txn.Failure can have at most 128 operations.
-	maxTxnOps uint
-}
-
-func NewKVServer(s *etcdserver.EtcdServer) pb.KVServer {
-	return &kvServer{hdr: newHeader(s), kv: s, maxTxnOps: s.Cfg.MaxTxnOps}
-}
-
-func (s *kvServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) {
-	if err := checkRangeRequest(r); err != nil {
-		return nil, err
-	}
-
-	resp, err := s.kv.Range(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	s.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (s *kvServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) {
-	if err := checkPutRequest(r); err != nil {
-		return nil, err
-	}
-
-	resp, err := s.kv.Put(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	s.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (s *kvServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	if err := checkDeleteRequest(r); err != nil {
-		return nil, err
-	}
-
-	resp, err := s.kv.DeleteRange(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	s.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (s *kvServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) {
-	if err := checkTxnRequest(r, int(s.maxTxnOps)); err != nil {
-		return nil, err
-	}
-	// check for forbidden put/del overlaps after checking request to avoid quadratic blowup
-	if _, _, err := checkIntervals(r.Success); err != nil {
-		return nil, err
-	}
-	if _, _, err := checkIntervals(r.Failure); err != nil {
-		return nil, err
-	}
-
-	resp, err := s.kv.Txn(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	s.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (s *kvServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) {
-	resp, err := s.kv.Compact(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	s.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func checkRangeRequest(r *pb.RangeRequest) error {
-	if len(r.Key) == 0 {
-		return rpctypes.ErrGRPCEmptyKey
-	}
-	return nil
-}
-
-func checkPutRequest(r *pb.PutRequest) error {
-	if len(r.Key) == 0 {
-		return rpctypes.ErrGRPCEmptyKey
-	}
-	if r.IgnoreValue && len(r.Value) != 0 {
-		return rpctypes.ErrGRPCValueProvided
-	}
-	if r.IgnoreLease && r.Lease != 0 {
-		return rpctypes.ErrGRPCLeaseProvided
-	}
-	return nil
-}
-
-func checkDeleteRequest(r *pb.DeleteRangeRequest) error {
-	if len(r.Key) == 0 {
-		return rpctypes.ErrGRPCEmptyKey
-	}
-	return nil
-}
-
-func checkTxnRequest(r *pb.TxnRequest, maxTxnOps int) error {
-	opc := len(r.Compare)
-	if opc < len(r.Success) {
-		opc = len(r.Success)
-	}
-	if opc < len(r.Failure) {
-		opc = len(r.Failure)
-	}
-	if opc > maxTxnOps {
-		return rpctypes.ErrGRPCTooManyOps
-	}
-
-	for _, c := range r.Compare {
-		if len(c.Key) == 0 {
-			return rpctypes.ErrGRPCEmptyKey
-		}
-	}
-	for _, u := range r.Success {
-		if err := checkRequestOp(u, maxTxnOps-opc); err != nil {
-			return err
-		}
-	}
-	for _, u := range r.Failure {
-		if err := checkRequestOp(u, maxTxnOps-opc); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-// checkIntervals tests whether puts and deletes overlap for a list of ops. If
-// there is an overlap, returns an error. If no overlap, return put and delete
-// sets for recursive evaluation.
-func checkIntervals(reqs []*pb.RequestOp) (map[string]struct{}, adt.IntervalTree, error) {
-	var dels adt.IntervalTree
-
-	// collect deletes from this level; build first to check lower level overlapped puts
-	for _, req := range reqs {
-		tv, ok := req.Request.(*pb.RequestOp_RequestDeleteRange)
-		if !ok {
-			continue
-		}
-		dreq := tv.RequestDeleteRange
-		if dreq == nil {
-			continue
-		}
-		var iv adt.Interval
-		if len(dreq.RangeEnd) != 0 {
-			iv = adt.NewStringAffineInterval(string(dreq.Key), string(dreq.RangeEnd))
-		} else {
-			iv = adt.NewStringAffinePoint(string(dreq.Key))
-		}
-		dels.Insert(iv, struct{}{})
-	}
-
-	// collect children puts/deletes
-	puts := make(map[string]struct{})
-	for _, req := range reqs {
-		tv, ok := req.Request.(*pb.RequestOp_RequestTxn)
-		if !ok {
-			continue
-		}
-		putsThen, delsThen, err := checkIntervals(tv.RequestTxn.Success)
-		if err != nil {
-			return nil, dels, err
-		}
-		putsElse, delsElse, err := checkIntervals(tv.RequestTxn.Failure)
-		if err != nil {
-			return nil, dels, err
-		}
-		for k := range putsThen {
-			if _, ok := puts[k]; ok {
-				return nil, dels, rpctypes.ErrGRPCDuplicateKey
-			}
-			if dels.Intersects(adt.NewStringAffinePoint(k)) {
-				return nil, dels, rpctypes.ErrGRPCDuplicateKey
-			}
-			puts[k] = struct{}{}
-		}
-		for k := range putsElse {
-			if _, ok := puts[k]; ok {
-				// if key is from putsThen, overlap is OK since
-				// either then/else are mutually exclusive
-				if _, isSafe := putsThen[k]; !isSafe {
-					return nil, dels, rpctypes.ErrGRPCDuplicateKey
-				}
-			}
-			if dels.Intersects(adt.NewStringAffinePoint(k)) {
-				return nil, dels, rpctypes.ErrGRPCDuplicateKey
-			}
-			puts[k] = struct{}{}
-		}
-		dels.Union(delsThen, adt.NewStringAffineInterval("\x00", ""))
-		dels.Union(delsElse, adt.NewStringAffineInterval("\x00", ""))
-	}
-
-	// collect and check this level's puts
-	for _, req := range reqs {
-		tv, ok := req.Request.(*pb.RequestOp_RequestPut)
-		if !ok || tv.RequestPut == nil {
-			continue
-		}
-		k := string(tv.RequestPut.Key)
-		if _, ok := puts[k]; ok {
-			return nil, dels, rpctypes.ErrGRPCDuplicateKey
-		}
-		if dels.Intersects(adt.NewStringAffinePoint(k)) {
-			return nil, dels, rpctypes.ErrGRPCDuplicateKey
-		}
-		puts[k] = struct{}{}
-	}
-	return puts, dels, nil
-}
-
-func checkRequestOp(u *pb.RequestOp, maxTxnOps int) error {
-	// TODO: ensure only one of the field is set.
-	switch uv := u.Request.(type) {
-	case *pb.RequestOp_RequestRange:
-		return checkRangeRequest(uv.RequestRange)
-	case *pb.RequestOp_RequestPut:
-		return checkPutRequest(uv.RequestPut)
-	case *pb.RequestOp_RequestDeleteRange:
-		return checkDeleteRequest(uv.RequestDeleteRange)
-	case *pb.RequestOp_RequestTxn:
-		return checkTxnRequest(uv.RequestTxn, maxTxnOps)
-	default:
-		// empty op / nil entry
-		return rpctypes.ErrGRPCKeyNotFound
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go
deleted file mode 100644
index 5b4f2b1..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import (
-	"context"
-	"io"
-
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/lease"
-)
-
-type LeaseServer struct {
-	hdr header
-	le  etcdserver.Lessor
-}
-
-func NewLeaseServer(s *etcdserver.EtcdServer) pb.LeaseServer {
-	return &LeaseServer{le: s, hdr: newHeader(s)}
-}
-
-func (ls *LeaseServer) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	resp, err := ls.le.LeaseGrant(ctx, cr)
-
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	ls.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ls *LeaseServer) LeaseRevoke(ctx context.Context, rr *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	resp, err := ls.le.LeaseRevoke(ctx, rr)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	ls.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ls *LeaseServer) LeaseTimeToLive(ctx context.Context, rr *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) {
-	resp, err := ls.le.LeaseTimeToLive(ctx, rr)
-	if err != nil && err != lease.ErrLeaseNotFound {
-		return nil, togRPCError(err)
-	}
-	if err == lease.ErrLeaseNotFound {
-		resp = &pb.LeaseTimeToLiveResponse{
-			Header: &pb.ResponseHeader{},
-			ID:     rr.ID,
-			TTL:    -1,
-		}
-	}
-	ls.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ls *LeaseServer) LeaseLeases(ctx context.Context, rr *pb.LeaseLeasesRequest) (*pb.LeaseLeasesResponse, error) {
-	resp, err := ls.le.LeaseLeases(ctx, rr)
-	if err != nil && err != lease.ErrLeaseNotFound {
-		return nil, togRPCError(err)
-	}
-	if err == lease.ErrLeaseNotFound {
-		resp = &pb.LeaseLeasesResponse{
-			Header: &pb.ResponseHeader{},
-			Leases: []*pb.LeaseStatus{},
-		}
-	}
-	ls.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ls *LeaseServer) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) (err error) {
-	errc := make(chan error, 1)
-	go func() {
-		errc <- ls.leaseKeepAlive(stream)
-	}()
-	select {
-	case err = <-errc:
-	case <-stream.Context().Done():
-		// the only server-side cancellation is noleader for now.
-		err = stream.Context().Err()
-		if err == context.Canceled {
-			err = rpctypes.ErrGRPCNoLeader
-		}
-	}
-	return err
-}
-
-func (ls *LeaseServer) leaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) error {
-	for {
-		req, err := stream.Recv()
-		if err == io.EOF {
-			return nil
-		}
-		if err != nil {
-			if isClientCtxErr(stream.Context().Err(), err) {
-				plog.Debugf("failed to receive lease keepalive request from gRPC stream (%q)", err.Error())
-			} else {
-				plog.Warningf("failed to receive lease keepalive request from gRPC stream (%q)", err.Error())
-			}
-			return err
-		}
-
-		// Create header before we sent out the renew request.
-		// This can make sure that the revision is strictly smaller or equal to
-		// when the keepalive happened at the local server (when the local server is the leader)
-		// or remote leader.
-		// Without this, a lease might be revoked at rev 3 but client can see the keepalive succeeded
-		// at rev 4.
-		resp := &pb.LeaseKeepAliveResponse{ID: req.ID, Header: &pb.ResponseHeader{}}
-		ls.hdr.fill(resp.Header)
-
-		ttl, err := ls.le.LeaseRenew(stream.Context(), lease.LeaseID(req.ID))
-		if err == lease.ErrLeaseNotFound {
-			err = nil
-			ttl = 0
-		}
-
-		if err != nil {
-			return togRPCError(err)
-		}
-
-		resp.TTL = ttl
-		err = stream.Send(resp)
-		if err != nil {
-			if isClientCtxErr(stream.Context().Err(), err) {
-				plog.Debugf("failed to send lease keepalive response to gRPC stream (%q)", err.Error())
-			} else {
-				plog.Warningf("failed to send lease keepalive response to gRPC stream (%q)", err.Error())
-			}
-			return err
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go
deleted file mode 100644
index c9df180..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import (
-	"context"
-	"crypto/sha256"
-	"io"
-
-	"github.com/coreos/etcd/auth"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc"
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/version"
-)
-
-type KVGetter interface {
-	KV() mvcc.ConsistentWatchableKV
-}
-
-type BackendGetter interface {
-	Backend() backend.Backend
-}
-
-type Alarmer interface {
-	Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error)
-}
-
-type LeaderTransferrer interface {
-	MoveLeader(ctx context.Context, lead, target uint64) error
-}
-
-type RaftStatusGetter interface {
-	etcdserver.RaftTimer
-	ID() types.ID
-	Leader() types.ID
-}
-
-type AuthGetter interface {
-	AuthInfoFromCtx(ctx context.Context) (*auth.AuthInfo, error)
-	AuthStore() auth.AuthStore
-}
-
-type maintenanceServer struct {
-	rg  RaftStatusGetter
-	kg  KVGetter
-	bg  BackendGetter
-	a   Alarmer
-	lt  LeaderTransferrer
-	hdr header
-}
-
-func NewMaintenanceServer(s *etcdserver.EtcdServer) pb.MaintenanceServer {
-	srv := &maintenanceServer{rg: s, kg: s, bg: s, a: s, lt: s, hdr: newHeader(s)}
-	return &authMaintenanceServer{srv, s}
-}
-
-func (ms *maintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) {
-	plog.Noticef("starting to defragment the storage backend...")
-	err := ms.bg.Backend().Defrag()
-	if err != nil {
-		plog.Errorf("failed to defragment the storage backend (%v)", err)
-		return nil, err
-	}
-	plog.Noticef("finished defragmenting the storage backend")
-	return &pb.DefragmentResponse{}, nil
-}
-
-func (ms *maintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance_SnapshotServer) error {
-	snap := ms.bg.Backend().Snapshot()
-	pr, pw := io.Pipe()
-
-	defer pr.Close()
-
-	go func() {
-		snap.WriteTo(pw)
-		if err := snap.Close(); err != nil {
-			plog.Errorf("error closing snapshot (%v)", err)
-		}
-		pw.Close()
-	}()
-
-	// send file data
-	h := sha256.New()
-	br := int64(0)
-	buf := make([]byte, 32*1024)
-	sz := snap.Size()
-	for br < sz {
-		n, err := io.ReadFull(pr, buf)
-		if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
-			return togRPCError(err)
-		}
-		br += int64(n)
-		resp := &pb.SnapshotResponse{
-			RemainingBytes: uint64(sz - br),
-			Blob:           buf[:n],
-		}
-		if err = srv.Send(resp); err != nil {
-			return togRPCError(err)
-		}
-		h.Write(buf[:n])
-	}
-
-	// send sha
-	sha := h.Sum(nil)
-	hresp := &pb.SnapshotResponse{RemainingBytes: 0, Blob: sha}
-	if err := srv.Send(hresp); err != nil {
-		return togRPCError(err)
-	}
-
-	return nil
-}
-
-func (ms *maintenanceServer) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) {
-	h, rev, err := ms.kg.KV().Hash()
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	resp := &pb.HashResponse{Header: &pb.ResponseHeader{Revision: rev}, Hash: h}
-	ms.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ms *maintenanceServer) HashKV(ctx context.Context, r *pb.HashKVRequest) (*pb.HashKVResponse, error) {
-	h, rev, compactRev, err := ms.kg.KV().HashByRev(r.Revision)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	resp := &pb.HashKVResponse{Header: &pb.ResponseHeader{Revision: rev}, Hash: h, CompactRevision: compactRev}
-	ms.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ms *maintenanceServer) Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error) {
-	return ms.a.Alarm(ctx, ar)
-}
-
-func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) {
-	resp := &pb.StatusResponse{
-		Header:    &pb.ResponseHeader{Revision: ms.hdr.rev()},
-		Version:   version.Version,
-		DbSize:    ms.bg.Backend().Size(),
-		Leader:    uint64(ms.rg.Leader()),
-		RaftIndex: ms.rg.Index(),
-		RaftTerm:  ms.rg.Term(),
-	}
-	ms.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ms *maintenanceServer) MoveLeader(ctx context.Context, tr *pb.MoveLeaderRequest) (*pb.MoveLeaderResponse, error) {
-	if ms.rg.ID() != ms.rg.Leader() {
-		return nil, rpctypes.ErrGRPCNotLeader
-	}
-
-	if err := ms.lt.MoveLeader(ctx, uint64(ms.rg.Leader()), tr.TargetID); err != nil {
-		return nil, togRPCError(err)
-	}
-	return &pb.MoveLeaderResponse{}, nil
-}
-
-type authMaintenanceServer struct {
-	*maintenanceServer
-	ag AuthGetter
-}
-
-func (ams *authMaintenanceServer) isAuthenticated(ctx context.Context) error {
-	authInfo, err := ams.ag.AuthInfoFromCtx(ctx)
-	if err != nil {
-		return err
-	}
-
-	return ams.ag.AuthStore().IsAdminPermitted(authInfo)
-}
-
-func (ams *authMaintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) {
-	if err := ams.isAuthenticated(ctx); err != nil {
-		return nil, err
-	}
-
-	return ams.maintenanceServer.Defragment(ctx, sr)
-}
-
-func (ams *authMaintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance_SnapshotServer) error {
-	if err := ams.isAuthenticated(srv.Context()); err != nil {
-		return err
-	}
-
-	return ams.maintenanceServer.Snapshot(sr, srv)
-}
-
-func (ams *authMaintenanceServer) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) {
-	if err := ams.isAuthenticated(ctx); err != nil {
-		return nil, err
-	}
-
-	return ams.maintenanceServer.Hash(ctx, r)
-}
-
-func (ams *authMaintenanceServer) HashKV(ctx context.Context, r *pb.HashKVRequest) (*pb.HashKVResponse, error) {
-	if err := ams.isAuthenticated(ctx); err != nil {
-		return nil, err
-	}
-	return ams.maintenanceServer.HashKV(ctx, r)
-}
-
-func (ams *authMaintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) {
-	return ams.maintenanceServer.Status(ctx, ar)
-}
-
-func (ams *authMaintenanceServer) MoveLeader(ctx context.Context, tr *pb.MoveLeaderRequest) (*pb.MoveLeaderResponse, error) {
-	return ams.maintenanceServer.MoveLeader(ctx, tr)
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go
deleted file mode 100644
index cbe7b47..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import (
-	"context"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/pkg/types"
-)
-
-type ClusterServer struct {
-	cluster api.Cluster
-	server  etcdserver.ServerV3
-}
-
-func NewClusterServer(s etcdserver.ServerV3) *ClusterServer {
-	return &ClusterServer{
-		cluster: s.Cluster(),
-		server:  s,
-	}
-}
-
-func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) (*pb.MemberAddResponse, error) {
-	urls, err := types.NewURLs(r.PeerURLs)
-	if err != nil {
-		return nil, rpctypes.ErrGRPCMemberBadURLs
-	}
-
-	now := time.Now()
-	m := membership.NewMember("", urls, "", &now)
-	membs, merr := cs.server.AddMember(ctx, *m)
-	if merr != nil {
-		return nil, togRPCError(merr)
-	}
-
-	return &pb.MemberAddResponse{
-		Header:  cs.header(),
-		Member:  &pb.Member{ID: uint64(m.ID), PeerURLs: m.PeerURLs},
-		Members: membersToProtoMembers(membs),
-	}, nil
-}
-
-func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest) (*pb.MemberRemoveResponse, error) {
-	membs, err := cs.server.RemoveMember(ctx, r.ID)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return &pb.MemberRemoveResponse{Header: cs.header(), Members: membersToProtoMembers(membs)}, nil
-}
-
-func (cs *ClusterServer) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest) (*pb.MemberUpdateResponse, error) {
-	m := membership.Member{
-		ID:             types.ID(r.ID),
-		RaftAttributes: membership.RaftAttributes{PeerURLs: r.PeerURLs},
-	}
-	membs, err := cs.server.UpdateMember(ctx, m)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return &pb.MemberUpdateResponse{Header: cs.header(), Members: membersToProtoMembers(membs)}, nil
-}
-
-func (cs *ClusterServer) MemberList(ctx context.Context, r *pb.MemberListRequest) (*pb.MemberListResponse, error) {
-	membs := membersToProtoMembers(cs.cluster.Members())
-	return &pb.MemberListResponse{Header: cs.header(), Members: membs}, nil
-}
-
-func (cs *ClusterServer) header() *pb.ResponseHeader {
-	return &pb.ResponseHeader{ClusterId: uint64(cs.cluster.ID()), MemberId: uint64(cs.server.ID()), RaftTerm: cs.server.Term()}
-}
-
-func membersToProtoMembers(membs []*membership.Member) []*pb.Member {
-	protoMembs := make([]*pb.Member, len(membs))
-	for i := range membs {
-		protoMembs[i] = &pb.Member{
-			Name:       membs[i].Name,
-			ID:         uint64(membs[i].ID),
-			PeerURLs:   membs[i].PeerURLs,
-			ClientURLs: membs[i].ClientURLs,
-		}
-	}
-	return protoMembs
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go
deleted file mode 100644
index 6cb41a6..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	sentBytes = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "client_grpc_sent_bytes_total",
-		Help:      "The total number of bytes sent to grpc clients.",
-	})
-
-	receivedBytes = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "client_grpc_received_bytes_total",
-		Help:      "The total number of bytes received from grpc clients.",
-	})
-)
-
-func init() {
-	prometheus.MustRegister(sentBytes)
-	prometheus.MustRegister(receivedBytes)
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/quota.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/quota.go
deleted file mode 100644
index 02d9960..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/quota.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/pkg/types"
-)
-
-type quotaKVServer struct {
-	pb.KVServer
-	qa quotaAlarmer
-}
-
-type quotaAlarmer struct {
-	q  etcdserver.Quota
-	a  Alarmer
-	id types.ID
-}
-
-// check whether request satisfies the quota. If there is not enough space,
-// ignore request and raise the free space alarm.
-func (qa *quotaAlarmer) check(ctx context.Context, r interface{}) error {
-	if qa.q.Available(r) {
-		return nil
-	}
-	req := &pb.AlarmRequest{
-		MemberID: uint64(qa.id),
-		Action:   pb.AlarmRequest_ACTIVATE,
-		Alarm:    pb.AlarmType_NOSPACE,
-	}
-	qa.a.Alarm(ctx, req)
-	return rpctypes.ErrGRPCNoSpace
-}
-
-func NewQuotaKVServer(s *etcdserver.EtcdServer) pb.KVServer {
-	return &quotaKVServer{
-		NewKVServer(s),
-		quotaAlarmer{etcdserver.NewBackendQuota(s), s, s.ID()},
-	}
-}
-
-func (s *quotaKVServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) {
-	if err := s.qa.check(ctx, r); err != nil {
-		return nil, err
-	}
-	return s.KVServer.Put(ctx, r)
-}
-
-func (s *quotaKVServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) {
-	if err := s.qa.check(ctx, r); err != nil {
-		return nil, err
-	}
-	return s.KVServer.Txn(ctx, r)
-}
-
-type quotaLeaseServer struct {
-	pb.LeaseServer
-	qa quotaAlarmer
-}
-
-func (s *quotaLeaseServer) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	if err := s.qa.check(ctx, cr); err != nil {
-		return nil, err
-	}
-	return s.LeaseServer.LeaseGrant(ctx, cr)
-}
-
-func NewQuotaLeaseServer(s *etcdserver.EtcdServer) pb.LeaseServer {
-	return &quotaLeaseServer{
-		NewLeaseServer(s),
-		quotaAlarmer{etcdserver.NewBackendQuota(s), s, s.ID()},
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go
deleted file mode 100644
index 799c119..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import (
-	"context"
-	"strings"
-
-	"github.com/coreos/etcd/auth"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/mvcc"
-
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/status"
-)
-
-var toGRPCErrorMap = map[error]error{
-	membership.ErrIDRemoved:               rpctypes.ErrGRPCMemberNotFound,
-	membership.ErrIDNotFound:              rpctypes.ErrGRPCMemberNotFound,
-	membership.ErrIDExists:                rpctypes.ErrGRPCMemberExist,
-	membership.ErrPeerURLexists:           rpctypes.ErrGRPCPeerURLExist,
-	etcdserver.ErrNotEnoughStartedMembers: rpctypes.ErrMemberNotEnoughStarted,
-
-	mvcc.ErrCompacted:             rpctypes.ErrGRPCCompacted,
-	mvcc.ErrFutureRev:             rpctypes.ErrGRPCFutureRev,
-	etcdserver.ErrRequestTooLarge: rpctypes.ErrGRPCRequestTooLarge,
-	etcdserver.ErrNoSpace:         rpctypes.ErrGRPCNoSpace,
-	etcdserver.ErrTooManyRequests: rpctypes.ErrTooManyRequests,
-
-	etcdserver.ErrNoLeader:                   rpctypes.ErrGRPCNoLeader,
-	etcdserver.ErrNotLeader:                  rpctypes.ErrGRPCNotLeader,
-	etcdserver.ErrStopped:                    rpctypes.ErrGRPCStopped,
-	etcdserver.ErrTimeout:                    rpctypes.ErrGRPCTimeout,
-	etcdserver.ErrTimeoutDueToLeaderFail:     rpctypes.ErrGRPCTimeoutDueToLeaderFail,
-	etcdserver.ErrTimeoutDueToConnectionLost: rpctypes.ErrGRPCTimeoutDueToConnectionLost,
-	etcdserver.ErrUnhealthy:                  rpctypes.ErrGRPCUnhealthy,
-	etcdserver.ErrKeyNotFound:                rpctypes.ErrGRPCKeyNotFound,
-	etcdserver.ErrCorrupt:                    rpctypes.ErrGRPCCorrupt,
-
-	lease.ErrLeaseNotFound:    rpctypes.ErrGRPCLeaseNotFound,
-	lease.ErrLeaseExists:      rpctypes.ErrGRPCLeaseExist,
-	lease.ErrLeaseTTLTooLarge: rpctypes.ErrGRPCLeaseTTLTooLarge,
-
-	auth.ErrRootUserNotExist:     rpctypes.ErrGRPCRootUserNotExist,
-	auth.ErrRootRoleNotExist:     rpctypes.ErrGRPCRootRoleNotExist,
-	auth.ErrUserAlreadyExist:     rpctypes.ErrGRPCUserAlreadyExist,
-	auth.ErrUserEmpty:            rpctypes.ErrGRPCUserEmpty,
-	auth.ErrUserNotFound:         rpctypes.ErrGRPCUserNotFound,
-	auth.ErrRoleAlreadyExist:     rpctypes.ErrGRPCRoleAlreadyExist,
-	auth.ErrRoleNotFound:         rpctypes.ErrGRPCRoleNotFound,
-	auth.ErrAuthFailed:           rpctypes.ErrGRPCAuthFailed,
-	auth.ErrPermissionDenied:     rpctypes.ErrGRPCPermissionDenied,
-	auth.ErrRoleNotGranted:       rpctypes.ErrGRPCRoleNotGranted,
-	auth.ErrPermissionNotGranted: rpctypes.ErrGRPCPermissionNotGranted,
-	auth.ErrAuthNotEnabled:       rpctypes.ErrGRPCAuthNotEnabled,
-	auth.ErrInvalidAuthToken:     rpctypes.ErrGRPCInvalidAuthToken,
-	auth.ErrInvalidAuthMgmt:      rpctypes.ErrGRPCInvalidAuthMgmt,
-}
-
-func togRPCError(err error) error {
-	// let gRPC server convert to codes.Canceled, codes.DeadlineExceeded
-	if err == context.Canceled || err == context.DeadlineExceeded {
-		return err
-	}
-	grpcErr, ok := toGRPCErrorMap[err]
-	if !ok {
-		return status.Error(codes.Unknown, err.Error())
-	}
-	return grpcErr
-}
-
-func isClientCtxErr(ctxErr error, err error) bool {
-	if ctxErr != nil {
-		return true
-	}
-
-	ev, ok := status.FromError(err)
-	if !ok {
-		return false
-	}
-
-	switch ev.Code() {
-	case codes.Canceled, codes.DeadlineExceeded:
-		// client-side context cancel or deadline exceeded
-		// "rpc error: code = Canceled desc = context canceled"
-		// "rpc error: code = DeadlineExceeded desc = context deadline exceeded"
-		return true
-	case codes.Unavailable:
-		msg := ev.Message()
-		// client-side context cancel or deadline exceeded with TLS ("http2.errClientDisconnected")
-		// "rpc error: code = Unavailable desc = client disconnected"
-		if msg == "client disconnected" {
-			return true
-		}
-		// "grpc/transport.ClientTransport.CloseStream" on canceled streams
-		// "rpc error: code = Unavailable desc = stream error: stream ID 21; CANCEL")
-		if strings.HasPrefix(msg, "stream error: ") && strings.HasSuffix(msg, "; CANCEL") {
-			return true
-		}
-	}
-	return false
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go b/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go
deleted file mode 100644
index dd4f329..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go
+++ /dev/null
@@ -1,447 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v3rpc
-
-import (
-	"context"
-	"io"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/auth"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-type watchServer struct {
-	clusterID int64
-	memberID  int64
-	raftTimer etcdserver.RaftTimer
-	watchable mvcc.WatchableKV
-
-	ag AuthGetter
-}
-
-func NewWatchServer(s *etcdserver.EtcdServer) pb.WatchServer {
-	return &watchServer{
-		clusterID: int64(s.Cluster().ID()),
-		memberID:  int64(s.ID()),
-		raftTimer: s,
-		watchable: s.Watchable(),
-		ag:        s,
-	}
-}
-
-var (
-	// External test can read this with GetProgressReportInterval()
-	// and change this to a small value to finish fast with
-	// SetProgressReportInterval().
-	progressReportInterval   = 10 * time.Minute
-	progressReportIntervalMu sync.RWMutex
-)
-
-func GetProgressReportInterval() time.Duration {
-	progressReportIntervalMu.RLock()
-	defer progressReportIntervalMu.RUnlock()
-	return progressReportInterval
-}
-
-func SetProgressReportInterval(newTimeout time.Duration) {
-	progressReportIntervalMu.Lock()
-	defer progressReportIntervalMu.Unlock()
-	progressReportInterval = newTimeout
-}
-
-const (
-	// We send ctrl response inside the read loop. We do not want
-	// send to block read, but we still want ctrl response we sent to
-	// be serialized. Thus we use a buffered chan to solve the problem.
-	// A small buffer should be OK for most cases, since we expect the
-	// ctrl requests are infrequent.
-	ctrlStreamBufLen = 16
-)
-
-// serverWatchStream is an etcd server side stream. It receives requests
-// from client side gRPC stream. It receives watch events from mvcc.WatchStream,
-// and creates responses that forwarded to gRPC stream.
-// It also forwards control message like watch created and canceled.
-type serverWatchStream struct {
-	clusterID int64
-	memberID  int64
-	raftTimer etcdserver.RaftTimer
-
-	watchable mvcc.WatchableKV
-
-	gRPCStream  pb.Watch_WatchServer
-	watchStream mvcc.WatchStream
-	ctrlStream  chan *pb.WatchResponse
-
-	// mu protects progress, prevKV
-	mu sync.Mutex
-	// progress tracks the watchID that stream might need to send
-	// progress to.
-	// TODO: combine progress and prevKV into a single struct?
-	progress map[mvcc.WatchID]bool
-	prevKV   map[mvcc.WatchID]bool
-
-	// closec indicates the stream is closed.
-	closec chan struct{}
-
-	// wg waits for the send loop to complete
-	wg sync.WaitGroup
-
-	ag AuthGetter
-}
-
-func (ws *watchServer) Watch(stream pb.Watch_WatchServer) (err error) {
-	sws := serverWatchStream{
-		clusterID: ws.clusterID,
-		memberID:  ws.memberID,
-		raftTimer: ws.raftTimer,
-
-		watchable: ws.watchable,
-
-		gRPCStream:  stream,
-		watchStream: ws.watchable.NewWatchStream(),
-		// chan for sending control response like watcher created and canceled.
-		ctrlStream: make(chan *pb.WatchResponse, ctrlStreamBufLen),
-		progress:   make(map[mvcc.WatchID]bool),
-		prevKV:     make(map[mvcc.WatchID]bool),
-		closec:     make(chan struct{}),
-
-		ag: ws.ag,
-	}
-
-	sws.wg.Add(1)
-	go func() {
-		sws.sendLoop()
-		sws.wg.Done()
-	}()
-
-	errc := make(chan error, 1)
-	// Ideally recvLoop would also use sws.wg to signal its completion
-	// but when stream.Context().Done() is closed, the stream's recv
-	// may continue to block since it uses a different context, leading to
-	// deadlock when calling sws.close().
-	go func() {
-		if rerr := sws.recvLoop(); rerr != nil {
-			if isClientCtxErr(stream.Context().Err(), rerr) {
-				plog.Debugf("failed to receive watch request from gRPC stream (%q)", rerr.Error())
-			} else {
-				plog.Warningf("failed to receive watch request from gRPC stream (%q)", rerr.Error())
-			}
-			errc <- rerr
-		}
-	}()
-	select {
-	case err = <-errc:
-		close(sws.ctrlStream)
-	case <-stream.Context().Done():
-		err = stream.Context().Err()
-		// the only server-side cancellation is noleader for now.
-		if err == context.Canceled {
-			err = rpctypes.ErrGRPCNoLeader
-		}
-	}
-	sws.close()
-	return err
-}
-
-func (sws *serverWatchStream) isWatchPermitted(wcr *pb.WatchCreateRequest) bool {
-	authInfo, err := sws.ag.AuthInfoFromCtx(sws.gRPCStream.Context())
-	if err != nil {
-		return false
-	}
-	if authInfo == nil {
-		// if auth is enabled, IsRangePermitted() can cause an error
-		authInfo = &auth.AuthInfo{}
-	}
-
-	return sws.ag.AuthStore().IsRangePermitted(authInfo, wcr.Key, wcr.RangeEnd) == nil
-}
-
-func (sws *serverWatchStream) recvLoop() error {
-	for {
-		req, err := sws.gRPCStream.Recv()
-		if err == io.EOF {
-			return nil
-		}
-		if err != nil {
-			return err
-		}
-
-		switch uv := req.RequestUnion.(type) {
-		case *pb.WatchRequest_CreateRequest:
-			if uv.CreateRequest == nil {
-				break
-			}
-
-			creq := uv.CreateRequest
-			if len(creq.Key) == 0 {
-				// \x00 is the smallest key
-				creq.Key = []byte{0}
-			}
-			if len(creq.RangeEnd) == 0 {
-				// force nil since watchstream.Watch distinguishes
-				// between nil and []byte{} for single key / >=
-				creq.RangeEnd = nil
-			}
-			if len(creq.RangeEnd) == 1 && creq.RangeEnd[0] == 0 {
-				// support  >= key queries
-				creq.RangeEnd = []byte{}
-			}
-
-			if !sws.isWatchPermitted(creq) {
-				wr := &pb.WatchResponse{
-					Header:       sws.newResponseHeader(sws.watchStream.Rev()),
-					WatchId:      -1,
-					Canceled:     true,
-					Created:      true,
-					CancelReason: rpctypes.ErrGRPCPermissionDenied.Error(),
-				}
-
-				select {
-				case sws.ctrlStream <- wr:
-				case <-sws.closec:
-				}
-				return nil
-			}
-
-			filters := FiltersFromRequest(creq)
-
-			wsrev := sws.watchStream.Rev()
-			rev := creq.StartRevision
-			if rev == 0 {
-				rev = wsrev + 1
-			}
-			id := sws.watchStream.Watch(creq.Key, creq.RangeEnd, rev, filters...)
-			if id != -1 {
-				sws.mu.Lock()
-				if creq.ProgressNotify {
-					sws.progress[id] = true
-				}
-				if creq.PrevKv {
-					sws.prevKV[id] = true
-				}
-				sws.mu.Unlock()
-			}
-			wr := &pb.WatchResponse{
-				Header:   sws.newResponseHeader(wsrev),
-				WatchId:  int64(id),
-				Created:  true,
-				Canceled: id == -1,
-			}
-			select {
-			case sws.ctrlStream <- wr:
-			case <-sws.closec:
-				return nil
-			}
-		case *pb.WatchRequest_CancelRequest:
-			if uv.CancelRequest != nil {
-				id := uv.CancelRequest.WatchId
-				err := sws.watchStream.Cancel(mvcc.WatchID(id))
-				if err == nil {
-					sws.ctrlStream <- &pb.WatchResponse{
-						Header:   sws.newResponseHeader(sws.watchStream.Rev()),
-						WatchId:  id,
-						Canceled: true,
-					}
-					sws.mu.Lock()
-					delete(sws.progress, mvcc.WatchID(id))
-					delete(sws.prevKV, mvcc.WatchID(id))
-					sws.mu.Unlock()
-				}
-			}
-		default:
-			// we probably should not shutdown the entire stream when
-			// receive an valid command.
-			// so just do nothing instead.
-			continue
-		}
-	}
-}
-
-func (sws *serverWatchStream) sendLoop() {
-	// watch ids that are currently active
-	ids := make(map[mvcc.WatchID]struct{})
-	// watch responses pending on a watch id creation message
-	pending := make(map[mvcc.WatchID][]*pb.WatchResponse)
-
-	interval := GetProgressReportInterval()
-	progressTicker := time.NewTicker(interval)
-
-	defer func() {
-		progressTicker.Stop()
-		// drain the chan to clean up pending events
-		for ws := range sws.watchStream.Chan() {
-			mvcc.ReportEventReceived(len(ws.Events))
-		}
-		for _, wrs := range pending {
-			for _, ws := range wrs {
-				mvcc.ReportEventReceived(len(ws.Events))
-			}
-		}
-	}()
-
-	for {
-		select {
-		case wresp, ok := <-sws.watchStream.Chan():
-			if !ok {
-				return
-			}
-
-			// TODO: evs is []mvccpb.Event type
-			// either return []*mvccpb.Event from the mvcc package
-			// or define protocol buffer with []mvccpb.Event.
-			evs := wresp.Events
-			events := make([]*mvccpb.Event, len(evs))
-			sws.mu.Lock()
-			needPrevKV := sws.prevKV[wresp.WatchID]
-			sws.mu.Unlock()
-			for i := range evs {
-				events[i] = &evs[i]
-
-				if needPrevKV {
-					opt := mvcc.RangeOptions{Rev: evs[i].Kv.ModRevision - 1}
-					r, err := sws.watchable.Range(evs[i].Kv.Key, nil, opt)
-					if err == nil && len(r.KVs) != 0 {
-						events[i].PrevKv = &(r.KVs[0])
-					}
-				}
-			}
-
-			canceled := wresp.CompactRevision != 0
-			wr := &pb.WatchResponse{
-				Header:          sws.newResponseHeader(wresp.Revision),
-				WatchId:         int64(wresp.WatchID),
-				Events:          events,
-				CompactRevision: wresp.CompactRevision,
-				Canceled:        canceled,
-			}
-
-			if _, hasId := ids[wresp.WatchID]; !hasId {
-				// buffer if id not yet announced
-				wrs := append(pending[wresp.WatchID], wr)
-				pending[wresp.WatchID] = wrs
-				continue
-			}
-
-			mvcc.ReportEventReceived(len(evs))
-			if err := sws.gRPCStream.Send(wr); err != nil {
-				if isClientCtxErr(sws.gRPCStream.Context().Err(), err) {
-					plog.Debugf("failed to send watch response to gRPC stream (%q)", err.Error())
-				} else {
-					plog.Warningf("failed to send watch response to gRPC stream (%q)", err.Error())
-				}
-				return
-			}
-
-			sws.mu.Lock()
-			if len(evs) > 0 && sws.progress[wresp.WatchID] {
-				// elide next progress update if sent a key update
-				sws.progress[wresp.WatchID] = false
-			}
-			sws.mu.Unlock()
-
-		case c, ok := <-sws.ctrlStream:
-			if !ok {
-				return
-			}
-
-			if err := sws.gRPCStream.Send(c); err != nil {
-				if isClientCtxErr(sws.gRPCStream.Context().Err(), err) {
-					plog.Debugf("failed to send watch control response to gRPC stream (%q)", err.Error())
-				} else {
-					plog.Warningf("failed to send watch control response to gRPC stream (%q)", err.Error())
-				}
-				return
-			}
-
-			// track id creation
-			wid := mvcc.WatchID(c.WatchId)
-			if c.Canceled {
-				delete(ids, wid)
-				continue
-			}
-			if c.Created {
-				// flush buffered events
-				ids[wid] = struct{}{}
-				for _, v := range pending[wid] {
-					mvcc.ReportEventReceived(len(v.Events))
-					if err := sws.gRPCStream.Send(v); err != nil {
-						if isClientCtxErr(sws.gRPCStream.Context().Err(), err) {
-							plog.Debugf("failed to send pending watch response to gRPC stream (%q)", err.Error())
-						} else {
-							plog.Warningf("failed to send pending watch response to gRPC stream (%q)", err.Error())
-						}
-						return
-					}
-				}
-				delete(pending, wid)
-			}
-		case <-progressTicker.C:
-			sws.mu.Lock()
-			for id, ok := range sws.progress {
-				if ok {
-					sws.watchStream.RequestProgress(id)
-				}
-				sws.progress[id] = true
-			}
-			sws.mu.Unlock()
-		case <-sws.closec:
-			return
-		}
-	}
-}
-
-func (sws *serverWatchStream) close() {
-	sws.watchStream.Close()
-	close(sws.closec)
-	sws.wg.Wait()
-}
-
-func (sws *serverWatchStream) newResponseHeader(rev int64) *pb.ResponseHeader {
-	return &pb.ResponseHeader{
-		ClusterId: uint64(sws.clusterID),
-		MemberId:  uint64(sws.memberID),
-		Revision:  rev,
-		RaftTerm:  sws.raftTimer.Term(),
-	}
-}
-
-func filterNoDelete(e mvccpb.Event) bool {
-	return e.Type == mvccpb.DELETE
-}
-
-func filterNoPut(e mvccpb.Event) bool {
-	return e.Type == mvccpb.PUT
-}
-
-func FiltersFromRequest(creq *pb.WatchCreateRequest) []mvcc.FilterFunc {
-	filters := make([]mvcc.FilterFunc, 0, len(creq.Filters))
-	for _, ft := range creq.Filters {
-		switch ft {
-		case pb.WatchCreateRequest_NOPUT:
-			filters = append(filters, filterNoPut)
-		case pb.WatchCreateRequest_NODELETE:
-			filters = append(filters, filterNoDelete)
-		default:
-		}
-	}
-	return filters
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/apply.go b/vendor/github.com/coreos/etcd/etcdserver/apply.go
deleted file mode 100644
index 93e78e3..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/apply.go
+++ /dev/null
@@ -1,972 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"bytes"
-	"context"
-	"sort"
-	"time"
-
-	"github.com/coreos/etcd/auth"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/mvcc"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-	"github.com/coreos/etcd/pkg/types"
-
-	"github.com/gogo/protobuf/proto"
-)
-
-const (
-	warnApplyDuration = 100 * time.Millisecond
-)
-
-type applyResult struct {
-	resp proto.Message
-	err  error
-	// physc signals the physical effect of the request has completed in addition
-	// to being logically reflected by the node. Currently only used for
-	// Compaction requests.
-	physc <-chan struct{}
-}
-
-// applierV3 is the interface for processing V3 raft messages
-type applierV3 interface {
-	Apply(r *pb.InternalRaftRequest) *applyResult
-
-	Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*pb.PutResponse, error)
-	Range(txn mvcc.TxnRead, r *pb.RangeRequest) (*pb.RangeResponse, error)
-	DeleteRange(txn mvcc.TxnWrite, dr *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error)
-	Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error)
-	Compaction(compaction *pb.CompactionRequest) (*pb.CompactionResponse, <-chan struct{}, error)
-
-	LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error)
-	LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error)
-
-	Alarm(*pb.AlarmRequest) (*pb.AlarmResponse, error)
-
-	Authenticate(r *pb.InternalAuthenticateRequest) (*pb.AuthenticateResponse, error)
-
-	AuthEnable() (*pb.AuthEnableResponse, error)
-	AuthDisable() (*pb.AuthDisableResponse, error)
-
-	UserAdd(ua *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
-	UserDelete(ua *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
-	UserChangePassword(ua *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error)
-	UserGrantRole(ua *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error)
-	UserGet(ua *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error)
-	UserRevokeRole(ua *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error)
-	RoleAdd(ua *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error)
-	RoleGrantPermission(ua *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error)
-	RoleGet(ua *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error)
-	RoleRevokePermission(ua *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error)
-	RoleDelete(ua *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error)
-	UserList(ua *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error)
-	RoleList(ua *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error)
-}
-
-type checkReqFunc func(mvcc.ReadView, *pb.RequestOp) error
-
-type applierV3backend struct {
-	s *EtcdServer
-
-	checkPut   checkReqFunc
-	checkRange checkReqFunc
-}
-
-func (s *EtcdServer) newApplierV3Backend() applierV3 {
-	base := &applierV3backend{s: s}
-	base.checkPut = func(rv mvcc.ReadView, req *pb.RequestOp) error {
-		return base.checkRequestPut(rv, req)
-	}
-	base.checkRange = func(rv mvcc.ReadView, req *pb.RequestOp) error {
-		return base.checkRequestRange(rv, req)
-	}
-	return base
-}
-
-func (s *EtcdServer) newApplierV3() applierV3 {
-	return newAuthApplierV3(
-		s.AuthStore(),
-		newQuotaApplierV3(s, s.newApplierV3Backend()),
-		s.lessor,
-	)
-}
-
-func (a *applierV3backend) Apply(r *pb.InternalRaftRequest) *applyResult {
-	ar := &applyResult{}
-	defer func(start time.Time) {
-		warnOfExpensiveRequest(start, &pb.InternalRaftStringer{Request: r}, ar.resp, ar.err)
-	}(time.Now())
-
-	// call into a.s.applyV3.F instead of a.F so upper appliers can check individual calls
-	switch {
-	case r.Range != nil:
-		ar.resp, ar.err = a.s.applyV3.Range(nil, r.Range)
-	case r.Put != nil:
-		ar.resp, ar.err = a.s.applyV3.Put(nil, r.Put)
-	case r.DeleteRange != nil:
-		ar.resp, ar.err = a.s.applyV3.DeleteRange(nil, r.DeleteRange)
-	case r.Txn != nil:
-		ar.resp, ar.err = a.s.applyV3.Txn(r.Txn)
-	case r.Compaction != nil:
-		ar.resp, ar.physc, ar.err = a.s.applyV3.Compaction(r.Compaction)
-	case r.LeaseGrant != nil:
-		ar.resp, ar.err = a.s.applyV3.LeaseGrant(r.LeaseGrant)
-	case r.LeaseRevoke != nil:
-		ar.resp, ar.err = a.s.applyV3.LeaseRevoke(r.LeaseRevoke)
-	case r.Alarm != nil:
-		ar.resp, ar.err = a.s.applyV3.Alarm(r.Alarm)
-	case r.Authenticate != nil:
-		ar.resp, ar.err = a.s.applyV3.Authenticate(r.Authenticate)
-	case r.AuthEnable != nil:
-		ar.resp, ar.err = a.s.applyV3.AuthEnable()
-	case r.AuthDisable != nil:
-		ar.resp, ar.err = a.s.applyV3.AuthDisable()
-	case r.AuthUserAdd != nil:
-		ar.resp, ar.err = a.s.applyV3.UserAdd(r.AuthUserAdd)
-	case r.AuthUserDelete != nil:
-		ar.resp, ar.err = a.s.applyV3.UserDelete(r.AuthUserDelete)
-	case r.AuthUserChangePassword != nil:
-		ar.resp, ar.err = a.s.applyV3.UserChangePassword(r.AuthUserChangePassword)
-	case r.AuthUserGrantRole != nil:
-		ar.resp, ar.err = a.s.applyV3.UserGrantRole(r.AuthUserGrantRole)
-	case r.AuthUserGet != nil:
-		ar.resp, ar.err = a.s.applyV3.UserGet(r.AuthUserGet)
-	case r.AuthUserRevokeRole != nil:
-		ar.resp, ar.err = a.s.applyV3.UserRevokeRole(r.AuthUserRevokeRole)
-	case r.AuthRoleAdd != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleAdd(r.AuthRoleAdd)
-	case r.AuthRoleGrantPermission != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleGrantPermission(r.AuthRoleGrantPermission)
-	case r.AuthRoleGet != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleGet(r.AuthRoleGet)
-	case r.AuthRoleRevokePermission != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleRevokePermission(r.AuthRoleRevokePermission)
-	case r.AuthRoleDelete != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleDelete(r.AuthRoleDelete)
-	case r.AuthUserList != nil:
-		ar.resp, ar.err = a.s.applyV3.UserList(r.AuthUserList)
-	case r.AuthRoleList != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleList(r.AuthRoleList)
-	default:
-		panic("not implemented")
-	}
-	return ar
-}
-
-func (a *applierV3backend) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (resp *pb.PutResponse, err error) {
-	resp = &pb.PutResponse{}
-	resp.Header = &pb.ResponseHeader{}
-
-	val, leaseID := p.Value, lease.LeaseID(p.Lease)
-	if txn == nil {
-		if leaseID != lease.NoLease {
-			if l := a.s.lessor.Lookup(leaseID); l == nil {
-				return nil, lease.ErrLeaseNotFound
-			}
-		}
-		txn = a.s.KV().Write()
-		defer txn.End()
-	}
-
-	var rr *mvcc.RangeResult
-	if p.IgnoreValue || p.IgnoreLease || p.PrevKv {
-		rr, err = txn.Range(p.Key, nil, mvcc.RangeOptions{})
-		if err != nil {
-			return nil, err
-		}
-	}
-	if p.IgnoreValue || p.IgnoreLease {
-		if rr == nil || len(rr.KVs) == 0 {
-			// ignore_{lease,value} flag expects previous key-value pair
-			return nil, ErrKeyNotFound
-		}
-	}
-	if p.IgnoreValue {
-		val = rr.KVs[0].Value
-	}
-	if p.IgnoreLease {
-		leaseID = lease.LeaseID(rr.KVs[0].Lease)
-	}
-	if p.PrevKv {
-		if rr != nil && len(rr.KVs) != 0 {
-			resp.PrevKv = &rr.KVs[0]
-		}
-	}
-
-	resp.Header.Revision = txn.Put(p.Key, val, leaseID)
-	return resp, nil
-}
-
-func (a *applierV3backend) DeleteRange(txn mvcc.TxnWrite, dr *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	resp := &pb.DeleteRangeResponse{}
-	resp.Header = &pb.ResponseHeader{}
-	end := mkGteRange(dr.RangeEnd)
-
-	if txn == nil {
-		txn = a.s.kv.Write()
-		defer txn.End()
-	}
-
-	if dr.PrevKv {
-		rr, err := txn.Range(dr.Key, end, mvcc.RangeOptions{})
-		if err != nil {
-			return nil, err
-		}
-		if rr != nil {
-			resp.PrevKvs = make([]*mvccpb.KeyValue, len(rr.KVs))
-			for i := range rr.KVs {
-				resp.PrevKvs[i] = &rr.KVs[i]
-			}
-		}
-	}
-
-	resp.Deleted, resp.Header.Revision = txn.DeleteRange(dr.Key, end)
-	return resp, nil
-}
-
-func (a *applierV3backend) Range(txn mvcc.TxnRead, r *pb.RangeRequest) (*pb.RangeResponse, error) {
-	resp := &pb.RangeResponse{}
-	resp.Header = &pb.ResponseHeader{}
-
-	if txn == nil {
-		txn = a.s.kv.Read()
-		defer txn.End()
-	}
-
-	limit := r.Limit
-	if r.SortOrder != pb.RangeRequest_NONE ||
-		r.MinModRevision != 0 || r.MaxModRevision != 0 ||
-		r.MinCreateRevision != 0 || r.MaxCreateRevision != 0 {
-		// fetch everything; sort and truncate afterwards
-		limit = 0
-	}
-	if limit > 0 {
-		// fetch one extra for 'more' flag
-		limit = limit + 1
-	}
-
-	ro := mvcc.RangeOptions{
-		Limit: limit,
-		Rev:   r.Revision,
-		Count: r.CountOnly,
-	}
-
-	rr, err := txn.Range(r.Key, mkGteRange(r.RangeEnd), ro)
-	if err != nil {
-		return nil, err
-	}
-
-	if r.MaxModRevision != 0 {
-		f := func(kv *mvccpb.KeyValue) bool { return kv.ModRevision > r.MaxModRevision }
-		pruneKVs(rr, f)
-	}
-	if r.MinModRevision != 0 {
-		f := func(kv *mvccpb.KeyValue) bool { return kv.ModRevision < r.MinModRevision }
-		pruneKVs(rr, f)
-	}
-	if r.MaxCreateRevision != 0 {
-		f := func(kv *mvccpb.KeyValue) bool { return kv.CreateRevision > r.MaxCreateRevision }
-		pruneKVs(rr, f)
-	}
-	if r.MinCreateRevision != 0 {
-		f := func(kv *mvccpb.KeyValue) bool { return kv.CreateRevision < r.MinCreateRevision }
-		pruneKVs(rr, f)
-	}
-
-	sortOrder := r.SortOrder
-	if r.SortTarget != pb.RangeRequest_KEY && sortOrder == pb.RangeRequest_NONE {
-		// Since current mvcc.Range implementation returns results
-		// sorted by keys in lexiographically ascending order,
-		// sort ASCEND by default only when target is not 'KEY'
-		sortOrder = pb.RangeRequest_ASCEND
-	}
-	if sortOrder != pb.RangeRequest_NONE {
-		var sorter sort.Interface
-		switch {
-		case r.SortTarget == pb.RangeRequest_KEY:
-			sorter = &kvSortByKey{&kvSort{rr.KVs}}
-		case r.SortTarget == pb.RangeRequest_VERSION:
-			sorter = &kvSortByVersion{&kvSort{rr.KVs}}
-		case r.SortTarget == pb.RangeRequest_CREATE:
-			sorter = &kvSortByCreate{&kvSort{rr.KVs}}
-		case r.SortTarget == pb.RangeRequest_MOD:
-			sorter = &kvSortByMod{&kvSort{rr.KVs}}
-		case r.SortTarget == pb.RangeRequest_VALUE:
-			sorter = &kvSortByValue{&kvSort{rr.KVs}}
-		}
-		switch {
-		case sortOrder == pb.RangeRequest_ASCEND:
-			sort.Sort(sorter)
-		case sortOrder == pb.RangeRequest_DESCEND:
-			sort.Sort(sort.Reverse(sorter))
-		}
-	}
-
-	if r.Limit > 0 && len(rr.KVs) > int(r.Limit) {
-		rr.KVs = rr.KVs[:r.Limit]
-		resp.More = true
-	}
-
-	resp.Header.Revision = rr.Rev
-	resp.Count = int64(rr.Count)
-	resp.Kvs = make([]*mvccpb.KeyValue, len(rr.KVs))
-	for i := range rr.KVs {
-		if r.KeysOnly {
-			rr.KVs[i].Value = nil
-		}
-		resp.Kvs[i] = &rr.KVs[i]
-	}
-	return resp, nil
-}
-
-func (a *applierV3backend) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) {
-	isWrite := !isTxnReadonly(rt)
-	txn := mvcc.NewReadOnlyTxnWrite(a.s.KV().Read())
-
-	txnPath := compareToPath(txn, rt)
-	if isWrite {
-		if _, err := checkRequests(txn, rt, txnPath, a.checkPut); err != nil {
-			txn.End()
-			return nil, err
-		}
-	}
-	if _, err := checkRequests(txn, rt, txnPath, a.checkRange); err != nil {
-		txn.End()
-		return nil, err
-	}
-
-	txnResp, _ := newTxnResp(rt, txnPath)
-
-	// When executing mutable txn ops, etcd must hold the txn lock so
-	// readers do not see any intermediate results. Since writes are
-	// serialized on the raft loop, the revision in the read view will
-	// be the revision of the write txn.
-	if isWrite {
-		txn.End()
-		txn = a.s.KV().Write()
-	}
-	a.applyTxn(txn, rt, txnPath, txnResp)
-	rev := txn.Rev()
-	if len(txn.Changes()) != 0 {
-		rev++
-	}
-	txn.End()
-
-	txnResp.Header.Revision = rev
-	return txnResp, nil
-}
-
-// newTxnResp allocates a txn response for a txn request given a path.
-func newTxnResp(rt *pb.TxnRequest, txnPath []bool) (txnResp *pb.TxnResponse, txnCount int) {
-	reqs := rt.Success
-	if !txnPath[0] {
-		reqs = rt.Failure
-	}
-	resps := make([]*pb.ResponseOp, len(reqs))
-	txnResp = &pb.TxnResponse{
-		Responses: resps,
-		Succeeded: txnPath[0],
-		Header:    &pb.ResponseHeader{},
-	}
-	for i, req := range reqs {
-		switch tv := req.Request.(type) {
-		case *pb.RequestOp_RequestRange:
-			resps[i] = &pb.ResponseOp{Response: &pb.ResponseOp_ResponseRange{}}
-		case *pb.RequestOp_RequestPut:
-			resps[i] = &pb.ResponseOp{Response: &pb.ResponseOp_ResponsePut{}}
-		case *pb.RequestOp_RequestDeleteRange:
-			resps[i] = &pb.ResponseOp{Response: &pb.ResponseOp_ResponseDeleteRange{}}
-		case *pb.RequestOp_RequestTxn:
-			resp, txns := newTxnResp(tv.RequestTxn, txnPath[1:])
-			resps[i] = &pb.ResponseOp{Response: &pb.ResponseOp_ResponseTxn{ResponseTxn: resp}}
-			txnPath = txnPath[1+txns:]
-			txnCount += txns + 1
-		default:
-		}
-	}
-	return txnResp, txnCount
-}
-
-func compareToPath(rv mvcc.ReadView, rt *pb.TxnRequest) []bool {
-	txnPath := make([]bool, 1)
-	ops := rt.Success
-	if txnPath[0] = applyCompares(rv, rt.Compare); !txnPath[0] {
-		ops = rt.Failure
-	}
-	for _, op := range ops {
-		tv, ok := op.Request.(*pb.RequestOp_RequestTxn)
-		if !ok || tv.RequestTxn == nil {
-			continue
-		}
-		txnPath = append(txnPath, compareToPath(rv, tv.RequestTxn)...)
-	}
-	return txnPath
-}
-
-func applyCompares(rv mvcc.ReadView, cmps []*pb.Compare) bool {
-	for _, c := range cmps {
-		if !applyCompare(rv, c) {
-			return false
-		}
-	}
-	return true
-}
-
-// applyCompare applies the compare request.
-// If the comparison succeeds, it returns true. Otherwise, returns false.
-func applyCompare(rv mvcc.ReadView, c *pb.Compare) bool {
-	// TODO: possible optimizations
-	// * chunk reads for large ranges to conserve memory
-	// * rewrite rules for common patterns:
-	//	ex. "[a, b) createrev > 0" => "limit 1 /\ kvs > 0"
-	// * caching
-	rr, err := rv.Range(c.Key, mkGteRange(c.RangeEnd), mvcc.RangeOptions{})
-	if err != nil {
-		return false
-	}
-	if len(rr.KVs) == 0 {
-		if c.Target == pb.Compare_VALUE {
-			// Always fail if comparing a value on a key/keys that doesn't exist;
-			// nil == empty string in grpc; no way to represent missing value
-			return false
-		}
-		return compareKV(c, mvccpb.KeyValue{})
-	}
-	for _, kv := range rr.KVs {
-		if !compareKV(c, kv) {
-			return false
-		}
-	}
-	return true
-}
-
-func compareKV(c *pb.Compare, ckv mvccpb.KeyValue) bool {
-	var result int
-	rev := int64(0)
-	switch c.Target {
-	case pb.Compare_VALUE:
-		v := []byte{}
-		if tv, _ := c.TargetUnion.(*pb.Compare_Value); tv != nil {
-			v = tv.Value
-		}
-		result = bytes.Compare(ckv.Value, v)
-	case pb.Compare_CREATE:
-		if tv, _ := c.TargetUnion.(*pb.Compare_CreateRevision); tv != nil {
-			rev = tv.CreateRevision
-		}
-		result = compareInt64(ckv.CreateRevision, rev)
-	case pb.Compare_MOD:
-		if tv, _ := c.TargetUnion.(*pb.Compare_ModRevision); tv != nil {
-			rev = tv.ModRevision
-		}
-		result = compareInt64(ckv.ModRevision, rev)
-	case pb.Compare_VERSION:
-		if tv, _ := c.TargetUnion.(*pb.Compare_Version); tv != nil {
-			rev = tv.Version
-		}
-		result = compareInt64(ckv.Version, rev)
-	case pb.Compare_LEASE:
-		if tv, _ := c.TargetUnion.(*pb.Compare_Lease); tv != nil {
-			rev = tv.Lease
-		}
-		result = compareInt64(ckv.Lease, rev)
-	}
-	switch c.Result {
-	case pb.Compare_EQUAL:
-		return result == 0
-	case pb.Compare_NOT_EQUAL:
-		return result != 0
-	case pb.Compare_GREATER:
-		return result > 0
-	case pb.Compare_LESS:
-		return result < 0
-	}
-	return true
-}
-
-func (a *applierV3backend) applyTxn(txn mvcc.TxnWrite, rt *pb.TxnRequest, txnPath []bool, tresp *pb.TxnResponse) (txns int) {
-	reqs := rt.Success
-	if !txnPath[0] {
-		reqs = rt.Failure
-	}
-	for i, req := range reqs {
-		respi := tresp.Responses[i].Response
-		switch tv := req.Request.(type) {
-		case *pb.RequestOp_RequestRange:
-			resp, err := a.Range(txn, tv.RequestRange)
-			if err != nil {
-				plog.Panicf("unexpected error during txn: %v", err)
-			}
-			respi.(*pb.ResponseOp_ResponseRange).ResponseRange = resp
-		case *pb.RequestOp_RequestPut:
-			resp, err := a.Put(txn, tv.RequestPut)
-			if err != nil {
-				plog.Panicf("unexpected error during txn: %v", err)
-			}
-			respi.(*pb.ResponseOp_ResponsePut).ResponsePut = resp
-		case *pb.RequestOp_RequestDeleteRange:
-			resp, err := a.DeleteRange(txn, tv.RequestDeleteRange)
-			if err != nil {
-				plog.Panicf("unexpected error during txn: %v", err)
-			}
-			respi.(*pb.ResponseOp_ResponseDeleteRange).ResponseDeleteRange = resp
-		case *pb.RequestOp_RequestTxn:
-			resp := respi.(*pb.ResponseOp_ResponseTxn).ResponseTxn
-			applyTxns := a.applyTxn(txn, tv.RequestTxn, txnPath[1:], resp)
-			txns += applyTxns + 1
-			txnPath = txnPath[applyTxns+1:]
-		default:
-			// empty union
-		}
-	}
-	return txns
-}
-
-func (a *applierV3backend) Compaction(compaction *pb.CompactionRequest) (*pb.CompactionResponse, <-chan struct{}, error) {
-	resp := &pb.CompactionResponse{}
-	resp.Header = &pb.ResponseHeader{}
-	ch, err := a.s.KV().Compact(compaction.Revision)
-	if err != nil {
-		return nil, ch, err
-	}
-	// get the current revision. which key to get is not important.
-	rr, _ := a.s.KV().Range([]byte("compaction"), nil, mvcc.RangeOptions{})
-	resp.Header.Revision = rr.Rev
-	return resp, ch, err
-}
-
-func (a *applierV3backend) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	l, err := a.s.lessor.Grant(lease.LeaseID(lc.ID), lc.TTL)
-	resp := &pb.LeaseGrantResponse{}
-	if err == nil {
-		resp.ID = int64(l.ID)
-		resp.TTL = l.TTL()
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	err := a.s.lessor.Revoke(lease.LeaseID(lc.ID))
-	return &pb.LeaseRevokeResponse{Header: newHeader(a.s)}, err
-}
-
-func (a *applierV3backend) Alarm(ar *pb.AlarmRequest) (*pb.AlarmResponse, error) {
-	resp := &pb.AlarmResponse{}
-	oldCount := len(a.s.alarmStore.Get(ar.Alarm))
-
-	switch ar.Action {
-	case pb.AlarmRequest_GET:
-		resp.Alarms = a.s.alarmStore.Get(ar.Alarm)
-	case pb.AlarmRequest_ACTIVATE:
-		m := a.s.alarmStore.Activate(types.ID(ar.MemberID), ar.Alarm)
-		if m == nil {
-			break
-		}
-		resp.Alarms = append(resp.Alarms, m)
-		activated := oldCount == 0 && len(a.s.alarmStore.Get(m.Alarm)) == 1
-		if !activated {
-			break
-		}
-
-		plog.Warningf("alarm %v raised by peer %s", m.Alarm, types.ID(m.MemberID))
-		switch m.Alarm {
-		case pb.AlarmType_CORRUPT:
-			a.s.applyV3 = newApplierV3Corrupt(a)
-		case pb.AlarmType_NOSPACE:
-			a.s.applyV3 = newApplierV3Capped(a)
-		default:
-			plog.Errorf("unimplemented alarm activation (%+v)", m)
-		}
-	case pb.AlarmRequest_DEACTIVATE:
-		m := a.s.alarmStore.Deactivate(types.ID(ar.MemberID), ar.Alarm)
-		if m == nil {
-			break
-		}
-		resp.Alarms = append(resp.Alarms, m)
-		deactivated := oldCount > 0 && len(a.s.alarmStore.Get(ar.Alarm)) == 0
-		if !deactivated {
-			break
-		}
-
-		switch m.Alarm {
-		case pb.AlarmType_NOSPACE, pb.AlarmType_CORRUPT:
-			// TODO: check kv hash before deactivating CORRUPT?
-			plog.Infof("alarm disarmed %+v", ar)
-			a.s.applyV3 = a.s.newApplierV3()
-		default:
-			plog.Errorf("unimplemented alarm deactivation (%+v)", m)
-		}
-	default:
-		return nil, nil
-	}
-	return resp, nil
-}
-
-type applierV3Capped struct {
-	applierV3
-	q backendQuota
-}
-
-// newApplierV3Capped creates an applyV3 that will reject Puts and transactions
-// with Puts so that the number of keys in the store is capped.
-func newApplierV3Capped(base applierV3) applierV3 { return &applierV3Capped{applierV3: base} }
-
-func (a *applierV3Capped) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*pb.PutResponse, error) {
-	return nil, ErrNoSpace
-}
-
-func (a *applierV3Capped) Txn(r *pb.TxnRequest) (*pb.TxnResponse, error) {
-	if a.q.Cost(r) > 0 {
-		return nil, ErrNoSpace
-	}
-	return a.applierV3.Txn(r)
-}
-
-func (a *applierV3Capped) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	return nil, ErrNoSpace
-}
-
-func (a *applierV3backend) AuthEnable() (*pb.AuthEnableResponse, error) {
-	err := a.s.AuthStore().AuthEnable()
-	if err != nil {
-		return nil, err
-	}
-	return &pb.AuthEnableResponse{Header: newHeader(a.s)}, nil
-}
-
-func (a *applierV3backend) AuthDisable() (*pb.AuthDisableResponse, error) {
-	a.s.AuthStore().AuthDisable()
-	return &pb.AuthDisableResponse{Header: newHeader(a.s)}, nil
-}
-
-func (a *applierV3backend) Authenticate(r *pb.InternalAuthenticateRequest) (*pb.AuthenticateResponse, error) {
-	ctx := context.WithValue(context.WithValue(a.s.ctx, auth.AuthenticateParamIndex{}, a.s.consistIndex.ConsistentIndex()), auth.AuthenticateParamSimpleTokenPrefix{}, r.SimpleToken)
-	resp, err := a.s.AuthStore().Authenticate(ctx, r.Name, r.Password)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
-	resp, err := a.s.AuthStore().UserAdd(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
-	resp, err := a.s.AuthStore().UserDelete(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
-	resp, err := a.s.AuthStore().UserChangePassword(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
-	resp, err := a.s.AuthStore().UserGrantRole(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	resp, err := a.s.AuthStore().UserGet(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
-	resp, err := a.s.AuthStore().UserRevokeRole(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
-	resp, err := a.s.AuthStore().RoleAdd(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
-	resp, err := a.s.AuthStore().RoleGrantPermission(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	resp, err := a.s.AuthStore().RoleGet(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
-	resp, err := a.s.AuthStore().RoleRevokePermission(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) {
-	resp, err := a.s.AuthStore().RoleDelete(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
-	resp, err := a.s.AuthStore().UserList(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
-	resp, err := a.s.AuthStore().RoleList(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-type quotaApplierV3 struct {
-	applierV3
-	q Quota
-}
-
-func newQuotaApplierV3(s *EtcdServer, app applierV3) applierV3 {
-	return &quotaApplierV3{app, NewBackendQuota(s)}
-}
-
-func (a *quotaApplierV3) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*pb.PutResponse, error) {
-	ok := a.q.Available(p)
-	resp, err := a.applierV3.Put(txn, p)
-	if err == nil && !ok {
-		err = ErrNoSpace
-	}
-	return resp, err
-}
-
-func (a *quotaApplierV3) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) {
-	ok := a.q.Available(rt)
-	resp, err := a.applierV3.Txn(rt)
-	if err == nil && !ok {
-		err = ErrNoSpace
-	}
-	return resp, err
-}
-
-func (a *quotaApplierV3) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	ok := a.q.Available(lc)
-	resp, err := a.applierV3.LeaseGrant(lc)
-	if err == nil && !ok {
-		err = ErrNoSpace
-	}
-	return resp, err
-}
-
-type kvSort struct{ kvs []mvccpb.KeyValue }
-
-func (s *kvSort) Swap(i, j int) {
-	t := s.kvs[i]
-	s.kvs[i] = s.kvs[j]
-	s.kvs[j] = t
-}
-func (s *kvSort) Len() int { return len(s.kvs) }
-
-type kvSortByKey struct{ *kvSort }
-
-func (s *kvSortByKey) Less(i, j int) bool {
-	return bytes.Compare(s.kvs[i].Key, s.kvs[j].Key) < 0
-}
-
-type kvSortByVersion struct{ *kvSort }
-
-func (s *kvSortByVersion) Less(i, j int) bool {
-	return (s.kvs[i].Version - s.kvs[j].Version) < 0
-}
-
-type kvSortByCreate struct{ *kvSort }
-
-func (s *kvSortByCreate) Less(i, j int) bool {
-	return (s.kvs[i].CreateRevision - s.kvs[j].CreateRevision) < 0
-}
-
-type kvSortByMod struct{ *kvSort }
-
-func (s *kvSortByMod) Less(i, j int) bool {
-	return (s.kvs[i].ModRevision - s.kvs[j].ModRevision) < 0
-}
-
-type kvSortByValue struct{ *kvSort }
-
-func (s *kvSortByValue) Less(i, j int) bool {
-	return bytes.Compare(s.kvs[i].Value, s.kvs[j].Value) < 0
-}
-
-func checkRequests(rv mvcc.ReadView, rt *pb.TxnRequest, txnPath []bool, f checkReqFunc) (int, error) {
-	txnCount := 0
-	reqs := rt.Success
-	if !txnPath[0] {
-		reqs = rt.Failure
-	}
-	for _, req := range reqs {
-		if tv, ok := req.Request.(*pb.RequestOp_RequestTxn); ok && tv.RequestTxn != nil {
-			txns, err := checkRequests(rv, tv.RequestTxn, txnPath[1:], f)
-			if err != nil {
-				return 0, err
-			}
-			txnCount += txns + 1
-			txnPath = txnPath[txns+1:]
-			continue
-		}
-		if err := f(rv, req); err != nil {
-			return 0, err
-		}
-	}
-	return txnCount, nil
-}
-
-func (a *applierV3backend) checkRequestPut(rv mvcc.ReadView, reqOp *pb.RequestOp) error {
-	tv, ok := reqOp.Request.(*pb.RequestOp_RequestPut)
-	if !ok || tv.RequestPut == nil {
-		return nil
-	}
-	req := tv.RequestPut
-	if req.IgnoreValue || req.IgnoreLease {
-		// expects previous key-value, error if not exist
-		rr, err := rv.Range(req.Key, nil, mvcc.RangeOptions{})
-		if err != nil {
-			return err
-		}
-		if rr == nil || len(rr.KVs) == 0 {
-			return ErrKeyNotFound
-		}
-	}
-	if lease.LeaseID(req.Lease) != lease.NoLease {
-		if l := a.s.lessor.Lookup(lease.LeaseID(req.Lease)); l == nil {
-			return lease.ErrLeaseNotFound
-		}
-	}
-	return nil
-}
-
-func (a *applierV3backend) checkRequestRange(rv mvcc.ReadView, reqOp *pb.RequestOp) error {
-	tv, ok := reqOp.Request.(*pb.RequestOp_RequestRange)
-	if !ok || tv.RequestRange == nil {
-		return nil
-	}
-	req := tv.RequestRange
-	switch {
-	case req.Revision == 0:
-		return nil
-	case req.Revision > rv.Rev():
-		return mvcc.ErrFutureRev
-	case req.Revision < rv.FirstRev():
-		return mvcc.ErrCompacted
-	}
-	return nil
-}
-
-func compareInt64(a, b int64) int {
-	switch {
-	case a < b:
-		return -1
-	case a > b:
-		return 1
-	default:
-		return 0
-	}
-}
-
-// mkGteRange determines if the range end is a >= range. This works around grpc
-// sending empty byte strings as nil; >= is encoded in the range end as '\0'.
-// If it is a GTE range, then []byte{} is returned to indicate the empty byte
-// string (vs nil being no byte string).
-func mkGteRange(rangeEnd []byte) []byte {
-	if len(rangeEnd) == 1 && rangeEnd[0] == 0 {
-		return []byte{}
-	}
-	return rangeEnd
-}
-
-func noSideEffect(r *pb.InternalRaftRequest) bool {
-	return r.Range != nil || r.AuthUserGet != nil || r.AuthRoleGet != nil
-}
-
-func removeNeedlessRangeReqs(txn *pb.TxnRequest) {
-	f := func(ops []*pb.RequestOp) []*pb.RequestOp {
-		j := 0
-		for i := 0; i < len(ops); i++ {
-			if _, ok := ops[i].Request.(*pb.RequestOp_RequestRange); ok {
-				continue
-			}
-			ops[j] = ops[i]
-			j++
-		}
-
-		return ops[:j]
-	}
-
-	txn.Success = f(txn.Success)
-	txn.Failure = f(txn.Failure)
-}
-
-func pruneKVs(rr *mvcc.RangeResult, isPrunable func(*mvccpb.KeyValue) bool) {
-	j := 0
-	for i := range rr.KVs {
-		rr.KVs[j] = rr.KVs[i]
-		if !isPrunable(&rr.KVs[i]) {
-			j++
-		}
-	}
-	rr.KVs = rr.KVs[:j]
-}
-
-func newHeader(s *EtcdServer) *pb.ResponseHeader {
-	return &pb.ResponseHeader{
-		ClusterId: uint64(s.Cluster().ID()),
-		MemberId:  uint64(s.ID()),
-		Revision:  s.KV().Rev(),
-		RaftTerm:  s.Term(),
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go b/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go
deleted file mode 100644
index ec93914..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/apply_auth.go
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"sync"
-
-	"github.com/coreos/etcd/auth"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/mvcc"
-)
-
-type authApplierV3 struct {
-	applierV3
-	as     auth.AuthStore
-	lessor lease.Lessor
-
-	// mu serializes Apply so that user isn't corrupted and so that
-	// serialized requests don't leak data from TOCTOU errors
-	mu sync.Mutex
-
-	authInfo auth.AuthInfo
-}
-
-func newAuthApplierV3(as auth.AuthStore, base applierV3, lessor lease.Lessor) *authApplierV3 {
-	return &authApplierV3{applierV3: base, as: as, lessor: lessor}
-}
-
-func (aa *authApplierV3) Apply(r *pb.InternalRaftRequest) *applyResult {
-	aa.mu.Lock()
-	defer aa.mu.Unlock()
-	if r.Header != nil {
-		// backward-compatible with pre-3.0 releases when internalRaftRequest
-		// does not have header field
-		aa.authInfo.Username = r.Header.Username
-		aa.authInfo.Revision = r.Header.AuthRevision
-	}
-	if needAdminPermission(r) {
-		if err := aa.as.IsAdminPermitted(&aa.authInfo); err != nil {
-			aa.authInfo.Username = ""
-			aa.authInfo.Revision = 0
-			return &applyResult{err: err}
-		}
-	}
-	ret := aa.applierV3.Apply(r)
-	aa.authInfo.Username = ""
-	aa.authInfo.Revision = 0
-	return ret
-}
-
-func (aa *authApplierV3) Put(txn mvcc.TxnWrite, r *pb.PutRequest) (*pb.PutResponse, error) {
-	if err := aa.as.IsPutPermitted(&aa.authInfo, r.Key); err != nil {
-		return nil, err
-	}
-
-	if err := aa.checkLeasePuts(lease.LeaseID(r.Lease)); err != nil {
-		// The specified lease is already attached with a key that cannot
-		// be written by this user. It means the user cannot revoke the
-		// lease so attaching the lease to the newly written key should
-		// be forbidden.
-		return nil, err
-	}
-
-	if r.PrevKv {
-		err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, nil)
-		if err != nil {
-			return nil, err
-		}
-	}
-	return aa.applierV3.Put(txn, r)
-}
-
-func (aa *authApplierV3) Range(txn mvcc.TxnRead, r *pb.RangeRequest) (*pb.RangeResponse, error) {
-	if err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, r.RangeEnd); err != nil {
-		return nil, err
-	}
-	return aa.applierV3.Range(txn, r)
-}
-
-func (aa *authApplierV3) DeleteRange(txn mvcc.TxnWrite, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	if err := aa.as.IsDeleteRangePermitted(&aa.authInfo, r.Key, r.RangeEnd); err != nil {
-		return nil, err
-	}
-	if r.PrevKv {
-		err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, r.RangeEnd)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	return aa.applierV3.DeleteRange(txn, r)
-}
-
-func checkTxnReqsPermission(as auth.AuthStore, ai *auth.AuthInfo, reqs []*pb.RequestOp) error {
-	for _, requ := range reqs {
-		switch tv := requ.Request.(type) {
-		case *pb.RequestOp_RequestRange:
-			if tv.RequestRange == nil {
-				continue
-			}
-
-			if err := as.IsRangePermitted(ai, tv.RequestRange.Key, tv.RequestRange.RangeEnd); err != nil {
-				return err
-			}
-
-		case *pb.RequestOp_RequestPut:
-			if tv.RequestPut == nil {
-				continue
-			}
-
-			if err := as.IsPutPermitted(ai, tv.RequestPut.Key); err != nil {
-				return err
-			}
-
-		case *pb.RequestOp_RequestDeleteRange:
-			if tv.RequestDeleteRange == nil {
-				continue
-			}
-
-			if tv.RequestDeleteRange.PrevKv {
-				err := as.IsRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd)
-				if err != nil {
-					return err
-				}
-			}
-
-			err := as.IsDeleteRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd)
-			if err != nil {
-				return err
-			}
-		}
-	}
-
-	return nil
-}
-
-func checkTxnAuth(as auth.AuthStore, ai *auth.AuthInfo, rt *pb.TxnRequest) error {
-	for _, c := range rt.Compare {
-		if err := as.IsRangePermitted(ai, c.Key, c.RangeEnd); err != nil {
-			return err
-		}
-	}
-	if err := checkTxnReqsPermission(as, ai, rt.Success); err != nil {
-		return err
-	}
-	if err := checkTxnReqsPermission(as, ai, rt.Failure); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (aa *authApplierV3) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) {
-	if err := checkTxnAuth(aa.as, &aa.authInfo, rt); err != nil {
-		return nil, err
-	}
-	return aa.applierV3.Txn(rt)
-}
-
-func (aa *authApplierV3) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	if err := aa.checkLeasePuts(lease.LeaseID(lc.ID)); err != nil {
-		return nil, err
-	}
-	return aa.applierV3.LeaseRevoke(lc)
-}
-
-func (aa *authApplierV3) checkLeasePuts(leaseID lease.LeaseID) error {
-	lease := aa.lessor.Lookup(leaseID)
-	if lease != nil {
-		for _, key := range lease.Keys() {
-			if err := aa.as.IsPutPermitted(&aa.authInfo, []byte(key)); err != nil {
-				return err
-			}
-		}
-	}
-
-	return nil
-}
-
-func (aa *authApplierV3) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	err := aa.as.IsAdminPermitted(&aa.authInfo)
-	if err != nil && r.Name != aa.authInfo.Username {
-		aa.authInfo.Username = ""
-		aa.authInfo.Revision = 0
-		return &pb.AuthUserGetResponse{}, err
-	}
-
-	return aa.applierV3.UserGet(r)
-}
-
-func (aa *authApplierV3) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	err := aa.as.IsAdminPermitted(&aa.authInfo)
-	if err != nil && !aa.as.HasRole(aa.authInfo.Username, r.Role) {
-		aa.authInfo.Username = ""
-		aa.authInfo.Revision = 0
-		return &pb.AuthRoleGetResponse{}, err
-	}
-
-	return aa.applierV3.RoleGet(r)
-}
-
-func needAdminPermission(r *pb.InternalRaftRequest) bool {
-	switch {
-	case r.AuthEnable != nil:
-		return true
-	case r.AuthDisable != nil:
-		return true
-	case r.AuthUserAdd != nil:
-		return true
-	case r.AuthUserDelete != nil:
-		return true
-	case r.AuthUserChangePassword != nil:
-		return true
-	case r.AuthUserGrantRole != nil:
-		return true
-	case r.AuthUserRevokeRole != nil:
-		return true
-	case r.AuthRoleAdd != nil:
-		return true
-	case r.AuthRoleGrantPermission != nil:
-		return true
-	case r.AuthRoleRevokePermission != nil:
-		return true
-	case r.AuthRoleDelete != nil:
-		return true
-	case r.AuthUserList != nil:
-		return true
-	case r.AuthRoleList != nil:
-		return true
-	default:
-		return false
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/apply_v2.go b/vendor/github.com/coreos/etcd/etcdserver/apply_v2.go
deleted file mode 100644
index a49b682..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/apply_v2.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"encoding/json"
-	"path"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver/api"
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/pkg/pbutil"
-	"github.com/coreos/etcd/store"
-	"github.com/coreos/go-semver/semver"
-)
-
-// ApplierV2 is the interface for processing V2 raft messages
-type ApplierV2 interface {
-	Delete(r *RequestV2) Response
-	Post(r *RequestV2) Response
-	Put(r *RequestV2) Response
-	QGet(r *RequestV2) Response
-	Sync(r *RequestV2) Response
-}
-
-func NewApplierV2(s store.Store, c *membership.RaftCluster) ApplierV2 {
-	return &applierV2store{store: s, cluster: c}
-}
-
-type applierV2store struct {
-	store   store.Store
-	cluster *membership.RaftCluster
-}
-
-func (a *applierV2store) Delete(r *RequestV2) Response {
-	switch {
-	case r.PrevIndex > 0 || r.PrevValue != "":
-		return toResponse(a.store.CompareAndDelete(r.Path, r.PrevValue, r.PrevIndex))
-	default:
-		return toResponse(a.store.Delete(r.Path, r.Dir, r.Recursive))
-	}
-}
-
-func (a *applierV2store) Post(r *RequestV2) Response {
-	return toResponse(a.store.Create(r.Path, r.Dir, r.Val, true, r.TTLOptions()))
-}
-
-func (a *applierV2store) Put(r *RequestV2) Response {
-	ttlOptions := r.TTLOptions()
-	exists, existsSet := pbutil.GetBool(r.PrevExist)
-	switch {
-	case existsSet:
-		if exists {
-			if r.PrevIndex == 0 && r.PrevValue == "" {
-				return toResponse(a.store.Update(r.Path, r.Val, ttlOptions))
-			}
-			return toResponse(a.store.CompareAndSwap(r.Path, r.PrevValue, r.PrevIndex, r.Val, ttlOptions))
-		}
-		return toResponse(a.store.Create(r.Path, r.Dir, r.Val, false, ttlOptions))
-	case r.PrevIndex > 0 || r.PrevValue != "":
-		return toResponse(a.store.CompareAndSwap(r.Path, r.PrevValue, r.PrevIndex, r.Val, ttlOptions))
-	default:
-		if storeMemberAttributeRegexp.MatchString(r.Path) {
-			id := membership.MustParseMemberIDFromKey(path.Dir(r.Path))
-			var attr membership.Attributes
-			if err := json.Unmarshal([]byte(r.Val), &attr); err != nil {
-				plog.Panicf("unmarshal %s should never fail: %v", r.Val, err)
-			}
-			if a.cluster != nil {
-				a.cluster.UpdateAttributes(id, attr)
-			}
-			// return an empty response since there is no consumer.
-			return Response{}
-		}
-		if r.Path == membership.StoreClusterVersionKey() {
-			if a.cluster != nil {
-				a.cluster.SetVersion(semver.Must(semver.NewVersion(r.Val)), api.UpdateCapability)
-			}
-			// return an empty response since there is no consumer.
-			return Response{}
-		}
-		return toResponse(a.store.Set(r.Path, r.Dir, r.Val, ttlOptions))
-	}
-}
-
-func (a *applierV2store) QGet(r *RequestV2) Response {
-	return toResponse(a.store.Get(r.Path, r.Recursive, r.Sorted))
-}
-
-func (a *applierV2store) Sync(r *RequestV2) Response {
-	a.store.DeleteExpiredKeys(time.Unix(0, r.Time))
-	return Response{}
-}
-
-// applyV2Request interprets r as a call to store.X and returns a Response interpreted
-// from store.Event
-func (s *EtcdServer) applyV2Request(r *RequestV2) Response {
-	defer warnOfExpensiveRequest(time.Now(), r, nil, nil)
-
-	switch r.Method {
-	case "POST":
-		return s.applyV2.Post(r)
-	case "PUT":
-		return s.applyV2.Put(r)
-	case "DELETE":
-		return s.applyV2.Delete(r)
-	case "QGET":
-		return s.applyV2.QGet(r)
-	case "SYNC":
-		return s.applyV2.Sync(r)
-	default:
-		// This should never be reached, but just in case:
-		return Response{Err: ErrUnknownMethod}
-	}
-}
-
-func (r *RequestV2) TTLOptions() store.TTLOptionSet {
-	refresh, _ := pbutil.GetBool(r.Refresh)
-	ttlOptions := store.TTLOptionSet{Refresh: refresh}
-	if r.Expiration != 0 {
-		ttlOptions.ExpireTime = time.Unix(0, r.Expiration)
-	}
-	return ttlOptions
-}
-
-func toResponse(ev *store.Event, err error) Response {
-	return Response{Event: ev, Err: err}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go b/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go
deleted file mode 100644
index 8991675..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/auth/auth.go
+++ /dev/null
@@ -1,648 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package auth implements etcd authentication.
-package auth
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"path"
-	"reflect"
-	"sort"
-	"strings"
-	"time"
-
-	etcderr "github.com/coreos/etcd/error"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/pkg/capnslog"
-
-	"golang.org/x/crypto/bcrypt"
-)
-
-const (
-	// StorePermsPrefix is the internal prefix of the storage layer dedicated to storing user data.
-	StorePermsPrefix = "/2"
-
-	// RootRoleName is the name of the ROOT role, with privileges to manage the cluster.
-	RootRoleName = "root"
-
-	// GuestRoleName is the name of the role that defines the privileges of an unauthenticated user.
-	GuestRoleName = "guest"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/auth")
-)
-
-var rootRole = Role{
-	Role: RootRoleName,
-	Permissions: Permissions{
-		KV: RWPermission{
-			Read:  []string{"/*"},
-			Write: []string{"/*"},
-		},
-	},
-}
-
-var guestRole = Role{
-	Role: GuestRoleName,
-	Permissions: Permissions{
-		KV: RWPermission{
-			Read:  []string{"/*"},
-			Write: []string{"/*"},
-		},
-	},
-}
-
-type doer interface {
-	Do(context.Context, etcdserverpb.Request) (etcdserver.Response, error)
-}
-
-type Store interface {
-	AllUsers() ([]string, error)
-	GetUser(name string) (User, error)
-	CreateOrUpdateUser(user User) (out User, created bool, err error)
-	CreateUser(user User) (User, error)
-	DeleteUser(name string) error
-	UpdateUser(user User) (User, error)
-	AllRoles() ([]string, error)
-	GetRole(name string) (Role, error)
-	CreateRole(role Role) error
-	DeleteRole(name string) error
-	UpdateRole(role Role) (Role, error)
-	AuthEnabled() bool
-	EnableAuth() error
-	DisableAuth() error
-	PasswordStore
-}
-
-type PasswordStore interface {
-	CheckPassword(user User, password string) bool
-	HashPassword(password string) (string, error)
-}
-
-type store struct {
-	server      doer
-	timeout     time.Duration
-	ensuredOnce bool
-
-	PasswordStore
-}
-
-type User struct {
-	User     string   `json:"user"`
-	Password string   `json:"password,omitempty"`
-	Roles    []string `json:"roles"`
-	Grant    []string `json:"grant,omitempty"`
-	Revoke   []string `json:"revoke,omitempty"`
-}
-
-type Role struct {
-	Role        string       `json:"role"`
-	Permissions Permissions  `json:"permissions"`
-	Grant       *Permissions `json:"grant,omitempty"`
-	Revoke      *Permissions `json:"revoke,omitempty"`
-}
-
-type Permissions struct {
-	KV RWPermission `json:"kv"`
-}
-
-func (p *Permissions) IsEmpty() bool {
-	return p == nil || (len(p.KV.Read) == 0 && len(p.KV.Write) == 0)
-}
-
-type RWPermission struct {
-	Read  []string `json:"read"`
-	Write []string `json:"write"`
-}
-
-type Error struct {
-	Status int
-	Errmsg string
-}
-
-func (ae Error) Error() string   { return ae.Errmsg }
-func (ae Error) HTTPStatus() int { return ae.Status }
-
-func authErr(hs int, s string, v ...interface{}) Error {
-	return Error{Status: hs, Errmsg: fmt.Sprintf("auth: "+s, v...)}
-}
-
-func NewStore(server doer, timeout time.Duration) Store {
-	s := &store{
-		server:        server,
-		timeout:       timeout,
-		PasswordStore: passwordStore{},
-	}
-	return s
-}
-
-// passwordStore implements PasswordStore using bcrypt to hash user passwords
-type passwordStore struct{}
-
-func (_ passwordStore) CheckPassword(user User, password string) bool {
-	err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
-	return err == nil
-}
-
-func (_ passwordStore) HashPassword(password string) (string, error) {
-	hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
-	return string(hash), err
-}
-
-func (s *store) AllUsers() ([]string, error) {
-	resp, err := s.requestResource("/users/", false, false)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeKeyNotFound {
-				return []string{}, nil
-			}
-		}
-		return nil, err
-	}
-	var nodes []string
-	for _, n := range resp.Event.Node.Nodes {
-		_, user := path.Split(n.Key)
-		nodes = append(nodes, user)
-	}
-	sort.Strings(nodes)
-	return nodes, nil
-}
-
-func (s *store) GetUser(name string) (User, error) { return s.getUser(name, false) }
-
-// CreateOrUpdateUser should be only used for creating the new user or when you are not
-// sure if it is a create or update. (When only password is passed in, we are not sure
-// if it is a update or create)
-func (s *store) CreateOrUpdateUser(user User) (out User, created bool, err error) {
-	_, err = s.getUser(user.User, true)
-	if err == nil {
-		out, err = s.UpdateUser(user)
-		return out, false, err
-	}
-	u, err := s.CreateUser(user)
-	return u, true, err
-}
-
-func (s *store) CreateUser(user User) (User, error) {
-	// Attach root role to root user.
-	if user.User == "root" {
-		user = attachRootRole(user)
-	}
-	u, err := s.createUserInternal(user)
-	if err == nil {
-		plog.Noticef("created user %s", user.User)
-	}
-	return u, err
-}
-
-func (s *store) createUserInternal(user User) (User, error) {
-	if user.Password == "" {
-		return user, authErr(http.StatusBadRequest, "Cannot create user %s with an empty password", user.User)
-	}
-	hash, err := s.HashPassword(user.Password)
-	if err != nil {
-		return user, err
-	}
-	user.Password = hash
-
-	_, err = s.createResource("/users/"+user.User, user)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeNodeExist {
-				return user, authErr(http.StatusConflict, "User %s already exists.", user.User)
-			}
-		}
-	}
-	return user, err
-}
-
-func (s *store) DeleteUser(name string) error {
-	if s.AuthEnabled() && name == "root" {
-		return authErr(http.StatusForbidden, "Cannot delete root user while auth is enabled.")
-	}
-	_, err := s.deleteResource("/users/" + name)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeKeyNotFound {
-				return authErr(http.StatusNotFound, "User %s does not exist", name)
-			}
-		}
-		return err
-	}
-	plog.Noticef("deleted user %s", name)
-	return nil
-}
-
-func (s *store) UpdateUser(user User) (User, error) {
-	old, err := s.getUser(user.User, true)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeKeyNotFound {
-				return user, authErr(http.StatusNotFound, "User %s doesn't exist.", user.User)
-			}
-		}
-		return old, err
-	}
-
-	newUser, err := old.merge(user, s.PasswordStore)
-	if err != nil {
-		return old, err
-	}
-	if reflect.DeepEqual(old, newUser) {
-		return old, authErr(http.StatusBadRequest, "User not updated. Use grant/revoke/password to update the user.")
-	}
-	_, err = s.updateResource("/users/"+user.User, newUser)
-	if err == nil {
-		plog.Noticef("updated user %s", user.User)
-	}
-	return newUser, err
-}
-
-func (s *store) AllRoles() ([]string, error) {
-	nodes := []string{RootRoleName}
-	resp, err := s.requestResource("/roles/", false, false)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeKeyNotFound {
-				return nodes, nil
-			}
-		}
-		return nil, err
-	}
-	for _, n := range resp.Event.Node.Nodes {
-		_, role := path.Split(n.Key)
-		nodes = append(nodes, role)
-	}
-	sort.Strings(nodes)
-	return nodes, nil
-}
-
-func (s *store) GetRole(name string) (Role, error) { return s.getRole(name, false) }
-
-func (s *store) CreateRole(role Role) error {
-	if role.Role == RootRoleName {
-		return authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", role.Role)
-	}
-	_, err := s.createResource("/roles/"+role.Role, role)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeNodeExist {
-				return authErr(http.StatusConflict, "Role %s already exists.", role.Role)
-			}
-		}
-	}
-	if err == nil {
-		plog.Noticef("created new role %s", role.Role)
-	}
-	return err
-}
-
-func (s *store) DeleteRole(name string) error {
-	if name == RootRoleName {
-		return authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", name)
-	}
-	_, err := s.deleteResource("/roles/" + name)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeKeyNotFound {
-				return authErr(http.StatusNotFound, "Role %s doesn't exist.", name)
-			}
-		}
-	}
-	if err == nil {
-		plog.Noticef("deleted role %s", name)
-	}
-	return err
-}
-
-func (s *store) UpdateRole(role Role) (Role, error) {
-	if role.Role == RootRoleName {
-		return Role{}, authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", role.Role)
-	}
-	old, err := s.getRole(role.Role, true)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeKeyNotFound {
-				return role, authErr(http.StatusNotFound, "Role %s doesn't exist.", role.Role)
-			}
-		}
-		return old, err
-	}
-	newRole, err := old.merge(role)
-	if err != nil {
-		return old, err
-	}
-	if reflect.DeepEqual(old, newRole) {
-		return old, authErr(http.StatusBadRequest, "Role not updated. Use grant/revoke to update the role.")
-	}
-	_, err = s.updateResource("/roles/"+role.Role, newRole)
-	if err == nil {
-		plog.Noticef("updated role %s", role.Role)
-	}
-	return newRole, err
-}
-
-func (s *store) AuthEnabled() bool {
-	return s.detectAuth()
-}
-
-func (s *store) EnableAuth() error {
-	if s.AuthEnabled() {
-		return authErr(http.StatusConflict, "already enabled")
-	}
-
-	if _, err := s.getUser("root", true); err != nil {
-		return authErr(http.StatusConflict, "No root user available, please create one")
-	}
-	if _, err := s.getRole(GuestRoleName, true); err != nil {
-		plog.Printf("no guest role access found, creating default")
-		if err := s.CreateRole(guestRole); err != nil {
-			plog.Errorf("error creating guest role. aborting auth enable.")
-			return err
-		}
-	}
-
-	if err := s.enableAuth(); err != nil {
-		plog.Errorf("error enabling auth (%v)", err)
-		return err
-	}
-
-	plog.Noticef("auth: enabled auth")
-	return nil
-}
-
-func (s *store) DisableAuth() error {
-	if !s.AuthEnabled() {
-		return authErr(http.StatusConflict, "already disabled")
-	}
-
-	err := s.disableAuth()
-	if err == nil {
-		plog.Noticef("auth: disabled auth")
-	} else {
-		plog.Errorf("error disabling auth (%v)", err)
-	}
-	return err
-}
-
-// merge applies the properties of the passed-in User to the User on which it
-// is called and returns a new User with these modifications applied. Think of
-// all Users as immutable sets of data. Merge allows you to perform the set
-// operations (desired grants and revokes) atomically
-func (ou User) merge(nu User, s PasswordStore) (User, error) {
-	var out User
-	if ou.User != nu.User {
-		return out, authErr(http.StatusConflict, "Merging user data with conflicting usernames: %s %s", ou.User, nu.User)
-	}
-	out.User = ou.User
-	if nu.Password != "" {
-		hash, err := s.HashPassword(nu.Password)
-		if err != nil {
-			return ou, err
-		}
-		out.Password = hash
-	} else {
-		out.Password = ou.Password
-	}
-	currentRoles := types.NewUnsafeSet(ou.Roles...)
-	for _, g := range nu.Grant {
-		if currentRoles.Contains(g) {
-			plog.Noticef("granting duplicate role %s for user %s", g, nu.User)
-			return User{}, authErr(http.StatusConflict, fmt.Sprintf("Granting duplicate role %s for user %s", g, nu.User))
-		}
-		currentRoles.Add(g)
-	}
-	for _, r := range nu.Revoke {
-		if !currentRoles.Contains(r) {
-			plog.Noticef("revoking ungranted role %s for user %s", r, nu.User)
-			return User{}, authErr(http.StatusConflict, fmt.Sprintf("Revoking ungranted role %s for user %s", r, nu.User))
-		}
-		currentRoles.Remove(r)
-	}
-	out.Roles = currentRoles.Values()
-	sort.Strings(out.Roles)
-	return out, nil
-}
-
-// merge for a role works the same as User above -- atomic Role application to
-// each of the substructures.
-func (r Role) merge(n Role) (Role, error) {
-	var out Role
-	var err error
-	if r.Role != n.Role {
-		return out, authErr(http.StatusConflict, "Merging role with conflicting names: %s %s", r.Role, n.Role)
-	}
-	out.Role = r.Role
-	out.Permissions, err = r.Permissions.Grant(n.Grant)
-	if err != nil {
-		return out, err
-	}
-	out.Permissions, err = out.Permissions.Revoke(n.Revoke)
-	return out, err
-}
-
-func (r Role) HasKeyAccess(key string, write bool) bool {
-	if r.Role == RootRoleName {
-		return true
-	}
-	return r.Permissions.KV.HasAccess(key, write)
-}
-
-func (r Role) HasRecursiveAccess(key string, write bool) bool {
-	if r.Role == RootRoleName {
-		return true
-	}
-	return r.Permissions.KV.HasRecursiveAccess(key, write)
-}
-
-// Grant adds a set of permissions to the permission object on which it is called,
-// returning a new permission object.
-func (p Permissions) Grant(n *Permissions) (Permissions, error) {
-	var out Permissions
-	var err error
-	if n == nil {
-		return p, nil
-	}
-	out.KV, err = p.KV.Grant(n.KV)
-	return out, err
-}
-
-// Revoke removes a set of permissions to the permission object on which it is called,
-// returning a new permission object.
-func (p Permissions) Revoke(n *Permissions) (Permissions, error) {
-	var out Permissions
-	var err error
-	if n == nil {
-		return p, nil
-	}
-	out.KV, err = p.KV.Revoke(n.KV)
-	return out, err
-}
-
-// Grant adds a set of permissions to the permission object on which it is called,
-// returning a new permission object.
-func (rw RWPermission) Grant(n RWPermission) (RWPermission, error) {
-	var out RWPermission
-	currentRead := types.NewUnsafeSet(rw.Read...)
-	for _, r := range n.Read {
-		if currentRead.Contains(r) {
-			return out, authErr(http.StatusConflict, "Granting duplicate read permission %s", r)
-		}
-		currentRead.Add(r)
-	}
-	currentWrite := types.NewUnsafeSet(rw.Write...)
-	for _, w := range n.Write {
-		if currentWrite.Contains(w) {
-			return out, authErr(http.StatusConflict, "Granting duplicate write permission %s", w)
-		}
-		currentWrite.Add(w)
-	}
-	out.Read = currentRead.Values()
-	out.Write = currentWrite.Values()
-	sort.Strings(out.Read)
-	sort.Strings(out.Write)
-	return out, nil
-}
-
-// Revoke removes a set of permissions to the permission object on which it is called,
-// returning a new permission object.
-func (rw RWPermission) Revoke(n RWPermission) (RWPermission, error) {
-	var out RWPermission
-	currentRead := types.NewUnsafeSet(rw.Read...)
-	for _, r := range n.Read {
-		if !currentRead.Contains(r) {
-			plog.Noticef("revoking ungranted read permission %s", r)
-			continue
-		}
-		currentRead.Remove(r)
-	}
-	currentWrite := types.NewUnsafeSet(rw.Write...)
-	for _, w := range n.Write {
-		if !currentWrite.Contains(w) {
-			plog.Noticef("revoking ungranted write permission %s", w)
-			continue
-		}
-		currentWrite.Remove(w)
-	}
-	out.Read = currentRead.Values()
-	out.Write = currentWrite.Values()
-	sort.Strings(out.Read)
-	sort.Strings(out.Write)
-	return out, nil
-}
-
-func (rw RWPermission) HasAccess(key string, write bool) bool {
-	var list []string
-	if write {
-		list = rw.Write
-	} else {
-		list = rw.Read
-	}
-	for _, pat := range list {
-		match, err := simpleMatch(pat, key)
-		if err == nil && match {
-			return true
-		}
-	}
-	return false
-}
-
-func (rw RWPermission) HasRecursiveAccess(key string, write bool) bool {
-	list := rw.Read
-	if write {
-		list = rw.Write
-	}
-	for _, pat := range list {
-		match, err := prefixMatch(pat, key)
-		if err == nil && match {
-			return true
-		}
-	}
-	return false
-}
-
-func simpleMatch(pattern string, key string) (match bool, err error) {
-	if pattern[len(pattern)-1] == '*' {
-		return strings.HasPrefix(key, pattern[:len(pattern)-1]), nil
-	}
-	return key == pattern, nil
-}
-
-func prefixMatch(pattern string, key string) (match bool, err error) {
-	if pattern[len(pattern)-1] != '*' {
-		return false, nil
-	}
-	return strings.HasPrefix(key, pattern[:len(pattern)-1]), nil
-}
-
-func attachRootRole(u User) User {
-	inRoles := false
-	for _, r := range u.Roles {
-		if r == RootRoleName {
-			inRoles = true
-			break
-		}
-	}
-	if !inRoles {
-		u.Roles = append(u.Roles, RootRoleName)
-	}
-	return u
-}
-
-func (s *store) getUser(name string, quorum bool) (User, error) {
-	resp, err := s.requestResource("/users/"+name, false, quorum)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeKeyNotFound {
-				return User{}, authErr(http.StatusNotFound, "User %s does not exist.", name)
-			}
-		}
-		return User{}, err
-	}
-	var u User
-	err = json.Unmarshal([]byte(*resp.Event.Node.Value), &u)
-	if err != nil {
-		return u, err
-	}
-	// Attach root role to root user.
-	if u.User == "root" {
-		u = attachRootRole(u)
-	}
-	return u, nil
-}
-
-func (s *store) getRole(name string, quorum bool) (Role, error) {
-	if name == RootRoleName {
-		return rootRole, nil
-	}
-	resp, err := s.requestResource("/roles/"+name, false, quorum)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeKeyNotFound {
-				return Role{}, authErr(http.StatusNotFound, "Role %s does not exist.", name)
-			}
-		}
-		return Role{}, err
-	}
-	var r Role
-	err = json.Unmarshal([]byte(*resp.Event.Node.Value), &r)
-	return r, err
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/auth/auth_requests.go b/vendor/github.com/coreos/etcd/etcdserver/auth/auth_requests.go
deleted file mode 100644
index 2464828..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/auth/auth_requests.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package auth
-
-import (
-	"context"
-	"encoding/json"
-	"path"
-
-	etcderr "github.com/coreos/etcd/error"
-	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-func (s *store) ensureAuthDirectories() error {
-	if s.ensuredOnce {
-		return nil
-	}
-	for _, res := range []string{StorePermsPrefix, StorePermsPrefix + "/users/", StorePermsPrefix + "/roles/"} {
-		ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
-		defer cancel()
-		pe := false
-		rr := etcdserverpb.Request{
-			Method:    "PUT",
-			Path:      res,
-			Dir:       true,
-			PrevExist: &pe,
-		}
-		_, err := s.server.Do(ctx, rr)
-		if err != nil {
-			if e, ok := err.(*etcderr.Error); ok {
-				if e.ErrorCode == etcderr.EcodeNodeExist {
-					continue
-				}
-			}
-			plog.Errorf("failed to create auth directories in the store (%v)", err)
-			return err
-		}
-	}
-	ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
-	defer cancel()
-	pe := false
-	rr := etcdserverpb.Request{
-		Method:    "PUT",
-		Path:      StorePermsPrefix + "/enabled",
-		Val:       "false",
-		PrevExist: &pe,
-	}
-	_, err := s.server.Do(ctx, rr)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeNodeExist {
-				s.ensuredOnce = true
-				return nil
-			}
-		}
-		return err
-	}
-	s.ensuredOnce = true
-	return nil
-}
-
-func (s *store) enableAuth() error {
-	_, err := s.updateResource("/enabled", true)
-	return err
-}
-func (s *store) disableAuth() error {
-	_, err := s.updateResource("/enabled", false)
-	return err
-}
-
-func (s *store) detectAuth() bool {
-	if s.server == nil {
-		return false
-	}
-	value, err := s.requestResource("/enabled", false, false)
-	if err != nil {
-		if e, ok := err.(*etcderr.Error); ok {
-			if e.ErrorCode == etcderr.EcodeKeyNotFound {
-				return false
-			}
-		}
-		plog.Errorf("failed to detect auth settings (%s)", err)
-		return false
-	}
-
-	var u bool
-	err = json.Unmarshal([]byte(*value.Event.Node.Value), &u)
-	if err != nil {
-		plog.Errorf("internal bookkeeping value for enabled isn't valid JSON (%v)", err)
-		return false
-	}
-	return u
-}
-
-func (s *store) requestResource(res string, dir, quorum bool) (etcdserver.Response, error) {
-	ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
-	defer cancel()
-	p := path.Join(StorePermsPrefix, res)
-	method := "GET"
-	if quorum {
-		method = "QGET"
-	}
-	rr := etcdserverpb.Request{
-		Method: method,
-		Path:   p,
-		Dir:    dir,
-	}
-	return s.server.Do(ctx, rr)
-}
-
-func (s *store) updateResource(res string, value interface{}) (etcdserver.Response, error) {
-	return s.setResource(res, value, true)
-}
-func (s *store) createResource(res string, value interface{}) (etcdserver.Response, error) {
-	return s.setResource(res, value, false)
-}
-func (s *store) setResource(res string, value interface{}, prevexist bool) (etcdserver.Response, error) {
-	err := s.ensureAuthDirectories()
-	if err != nil {
-		return etcdserver.Response{}, err
-	}
-	ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
-	defer cancel()
-	data, err := json.Marshal(value)
-	if err != nil {
-		return etcdserver.Response{}, err
-	}
-	p := path.Join(StorePermsPrefix, res)
-	rr := etcdserverpb.Request{
-		Method:    "PUT",
-		Path:      p,
-		Val:       string(data),
-		PrevExist: &prevexist,
-	}
-	return s.server.Do(ctx, rr)
-}
-
-func (s *store) deleteResource(res string) (etcdserver.Response, error) {
-	err := s.ensureAuthDirectories()
-	if err != nil {
-		return etcdserver.Response{}, err
-	}
-	ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
-	defer cancel()
-	pex := true
-	p := path.Join(StorePermsPrefix, res)
-	rr := etcdserverpb.Request{
-		Method:    "DELETE",
-		Path:      p,
-		PrevExist: &pex,
-	}
-	return s.server.Do(ctx, rr)
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/backend.go b/vendor/github.com/coreos/etcd/etcdserver/backend.go
deleted file mode 100644
index 647773d..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/backend.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"fmt"
-	"os"
-	"time"
-
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/mvcc"
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/snap"
-)
-
-func newBackend(cfg ServerConfig) backend.Backend {
-	bcfg := backend.DefaultBackendConfig()
-	bcfg.Path = cfg.backendPath()
-	if cfg.QuotaBackendBytes > 0 && cfg.QuotaBackendBytes != DefaultQuotaBytes {
-		// permit 10% excess over quota for disarm
-		bcfg.MmapSize = uint64(cfg.QuotaBackendBytes + cfg.QuotaBackendBytes/10)
-	}
-	return backend.New(bcfg)
-}
-
-// openSnapshotBackend renames a snapshot db to the current etcd db and opens it.
-func openSnapshotBackend(cfg ServerConfig, ss *snap.Snapshotter, snapshot raftpb.Snapshot) (backend.Backend, error) {
-	snapPath, err := ss.DBFilePath(snapshot.Metadata.Index)
-	if err != nil {
-		return nil, fmt.Errorf("database snapshot file path error: %v", err)
-	}
-	if err := os.Rename(snapPath, cfg.backendPath()); err != nil {
-		return nil, fmt.Errorf("rename snapshot file error: %v", err)
-	}
-	return openBackend(cfg), nil
-}
-
-// openBackend returns a backend using the current etcd db.
-func openBackend(cfg ServerConfig) backend.Backend {
-	fn := cfg.backendPath()
-	beOpened := make(chan backend.Backend)
-	go func() {
-		beOpened <- newBackend(cfg)
-	}()
-	select {
-	case be := <-beOpened:
-		return be
-	case <-time.After(10 * time.Second):
-		plog.Warningf("another etcd process is using %q and holds the file lock, or loading backend file is taking >10 seconds", fn)
-		plog.Warningf("waiting for it to exit before starting...")
-	}
-	return <-beOpened
-}
-
-// recoverBackendSnapshot recovers the DB from a snapshot in case etcd crashes
-// before updating the backend db after persisting raft snapshot to disk,
-// violating the invariant snapshot.Metadata.Index < db.consistentIndex. In this
-// case, replace the db with the snapshot db sent by the leader.
-func recoverSnapshotBackend(cfg ServerConfig, oldbe backend.Backend, snapshot raftpb.Snapshot) (backend.Backend, error) {
-	var cIndex consistentIndex
-	kv := mvcc.New(oldbe, &lease.FakeLessor{}, &cIndex)
-	defer kv.Close()
-	if snapshot.Metadata.Index <= kv.ConsistentIndex() {
-		return oldbe, nil
-	}
-	oldbe.Close()
-	return openSnapshotBackend(cfg, snap.New(cfg.SnapDir()), snapshot)
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go b/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go
deleted file mode 100644
index f44862a..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/cluster_util.go
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"sort"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/version"
-	"github.com/coreos/go-semver/semver"
-)
-
-// isMemberBootstrapped tries to check if the given member has been bootstrapped
-// in the given cluster.
-func isMemberBootstrapped(cl *membership.RaftCluster, member string, rt http.RoundTripper, timeout time.Duration) bool {
-	rcl, err := getClusterFromRemotePeers(getRemotePeerURLs(cl, member), timeout, false, rt)
-	if err != nil {
-		return false
-	}
-	id := cl.MemberByName(member).ID
-	m := rcl.Member(id)
-	if m == nil {
-		return false
-	}
-	if len(m.ClientURLs) > 0 {
-		return true
-	}
-	return false
-}
-
-// GetClusterFromRemotePeers takes a set of URLs representing etcd peers, and
-// attempts to construct a Cluster by accessing the members endpoint on one of
-// these URLs. The first URL to provide a response is used. If no URLs provide
-// a response, or a Cluster cannot be successfully created from a received
-// response, an error is returned.
-// Each request has a 10-second timeout. Because the upper limit of TTL is 5s,
-// 10 second is enough for building connection and finishing request.
-func GetClusterFromRemotePeers(urls []string, rt http.RoundTripper) (*membership.RaftCluster, error) {
-	return getClusterFromRemotePeers(urls, 10*time.Second, true, rt)
-}
-
-// If logerr is true, it prints out more error messages.
-func getClusterFromRemotePeers(urls []string, timeout time.Duration, logerr bool, rt http.RoundTripper) (*membership.RaftCluster, error) {
-	cc := &http.Client{
-		Transport: rt,
-		Timeout:   timeout,
-	}
-	for _, u := range urls {
-		resp, err := cc.Get(u + "/members")
-		if err != nil {
-			if logerr {
-				plog.Warningf("could not get cluster response from %s: %v", u, err)
-			}
-			continue
-		}
-		b, err := ioutil.ReadAll(resp.Body)
-		resp.Body.Close()
-		if err != nil {
-			if logerr {
-				plog.Warningf("could not read the body of cluster response: %v", err)
-			}
-			continue
-		}
-		var membs []*membership.Member
-		if err = json.Unmarshal(b, &membs); err != nil {
-			if logerr {
-				plog.Warningf("could not unmarshal cluster response: %v", err)
-			}
-			continue
-		}
-		id, err := types.IDFromString(resp.Header.Get("X-Etcd-Cluster-ID"))
-		if err != nil {
-			if logerr {
-				plog.Warningf("could not parse the cluster ID from cluster res: %v", err)
-			}
-			continue
-		}
-
-		// check the length of membership members
-		// if the membership members are present then prepare and return raft cluster
-		// if membership members are not present then the raft cluster formed will be
-		// an invalid empty cluster hence return failed to get raft cluster member(s) from the given urls error
-		if len(membs) > 0 {
-			return membership.NewClusterFromMembers("", id, membs), nil
-		}
-
-		return nil, fmt.Errorf("failed to get raft cluster member(s) from the given urls.")
-	}
-	return nil, fmt.Errorf("could not retrieve cluster information from the given urls")
-}
-
-// getRemotePeerURLs returns peer urls of remote members in the cluster. The
-// returned list is sorted in ascending lexicographical order.
-func getRemotePeerURLs(cl *membership.RaftCluster, local string) []string {
-	us := make([]string, 0)
-	for _, m := range cl.Members() {
-		if m.Name == local {
-			continue
-		}
-		us = append(us, m.PeerURLs...)
-	}
-	sort.Strings(us)
-	return us
-}
-
-// getVersions returns the versions of the members in the given cluster.
-// The key of the returned map is the member's ID. The value of the returned map
-// is the semver versions string, including server and cluster.
-// If it fails to get the version of a member, the key will be nil.
-func getVersions(cl *membership.RaftCluster, local types.ID, rt http.RoundTripper) map[string]*version.Versions {
-	members := cl.Members()
-	vers := make(map[string]*version.Versions)
-	for _, m := range members {
-		if m.ID == local {
-			cv := "not_decided"
-			if cl.Version() != nil {
-				cv = cl.Version().String()
-			}
-			vers[m.ID.String()] = &version.Versions{Server: version.Version, Cluster: cv}
-			continue
-		}
-		ver, err := getVersion(m, rt)
-		if err != nil {
-			plog.Warningf("cannot get the version of member %s (%v)", m.ID, err)
-			vers[m.ID.String()] = nil
-		} else {
-			vers[m.ID.String()] = ver
-		}
-	}
-	return vers
-}
-
-// decideClusterVersion decides the cluster version based on the versions map.
-// The returned version is the min server version in the map, or nil if the min
-// version in unknown.
-func decideClusterVersion(vers map[string]*version.Versions) *semver.Version {
-	var cv *semver.Version
-	lv := semver.Must(semver.NewVersion(version.Version))
-
-	for mid, ver := range vers {
-		if ver == nil {
-			return nil
-		}
-		v, err := semver.NewVersion(ver.Server)
-		if err != nil {
-			plog.Errorf("cannot understand the version of member %s (%v)", mid, err)
-			return nil
-		}
-		if lv.LessThan(*v) {
-			plog.Warningf("the local etcd version %s is not up-to-date", lv.String())
-			plog.Warningf("member %s has a higher version %s", mid, ver.Server)
-		}
-		if cv == nil {
-			cv = v
-		} else if v.LessThan(*cv) {
-			cv = v
-		}
-	}
-	return cv
-}
-
-// isCompatibleWithCluster return true if the local member has a compatible version with
-// the current running cluster.
-// The version is considered as compatible when at least one of the other members in the cluster has a
-// cluster version in the range of [MinClusterVersion, Version] and no known members has a cluster version
-// out of the range.
-// We set this rule since when the local member joins, another member might be offline.
-func isCompatibleWithCluster(cl *membership.RaftCluster, local types.ID, rt http.RoundTripper) bool {
-	vers := getVersions(cl, local, rt)
-	minV := semver.Must(semver.NewVersion(version.MinClusterVersion))
-	maxV := semver.Must(semver.NewVersion(version.Version))
-	maxV = &semver.Version{
-		Major: maxV.Major,
-		Minor: maxV.Minor,
-	}
-
-	return isCompatibleWithVers(vers, local, minV, maxV)
-}
-
-func isCompatibleWithVers(vers map[string]*version.Versions, local types.ID, minV, maxV *semver.Version) bool {
-	var ok bool
-	for id, v := range vers {
-		// ignore comparison with local version
-		if id == local.String() {
-			continue
-		}
-		if v == nil {
-			continue
-		}
-		clusterv, err := semver.NewVersion(v.Cluster)
-		if err != nil {
-			plog.Errorf("cannot understand the cluster version of member %s (%v)", id, err)
-			continue
-		}
-		if clusterv.LessThan(*minV) {
-			plog.Warningf("the running cluster version(%v) is lower than the minimal cluster version(%v) supported", clusterv.String(), minV.String())
-			return false
-		}
-		if maxV.LessThan(*clusterv) {
-			plog.Warningf("the running cluster version(%v) is higher than the maximum cluster version(%v) supported", clusterv.String(), maxV.String())
-			return false
-		}
-		ok = true
-	}
-	return ok
-}
-
-// getVersion returns the Versions of the given member via its
-// peerURLs. Returns the last error if it fails to get the version.
-func getVersion(m *membership.Member, rt http.RoundTripper) (*version.Versions, error) {
-	cc := &http.Client{
-		Transport: rt,
-	}
-	var (
-		err  error
-		resp *http.Response
-	)
-
-	for _, u := range m.PeerURLs {
-		resp, err = cc.Get(u + "/version")
-		if err != nil {
-			plog.Warningf("failed to reach the peerURL(%s) of member %s (%v)", u, m.ID, err)
-			continue
-		}
-		var b []byte
-		b, err = ioutil.ReadAll(resp.Body)
-		resp.Body.Close()
-		if err != nil {
-			plog.Warningf("failed to read out the response body from the peerURL(%s) of member %s (%v)", u, m.ID, err)
-			continue
-		}
-		var vers version.Versions
-		if err = json.Unmarshal(b, &vers); err != nil {
-			plog.Warningf("failed to unmarshal the response body got from the peerURL(%s) of member %s (%v)", u, m.ID, err)
-			continue
-		}
-		return &vers, nil
-	}
-	return nil, err
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/config.go b/vendor/github.com/coreos/etcd/etcdserver/config.go
deleted file mode 100644
index 295d952..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/config.go
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"context"
-	"fmt"
-	"path/filepath"
-	"sort"
-	"strings"
-	"time"
-
-	"github.com/coreos/etcd/pkg/netutil"
-	"github.com/coreos/etcd/pkg/transport"
-	"github.com/coreos/etcd/pkg/types"
-)
-
-// ServerConfig holds the configuration of etcd as taken from the command line or discovery.
-type ServerConfig struct {
-	Name           string
-	DiscoveryURL   string
-	DiscoveryProxy string
-	ClientURLs     types.URLs
-	PeerURLs       types.URLs
-	DataDir        string
-	// DedicatedWALDir config will make the etcd to write the WAL to the WALDir
-	// rather than the dataDir/member/wal.
-	DedicatedWALDir     string
-	SnapCount           uint64
-	MaxSnapFiles        uint
-	MaxWALFiles         uint
-	InitialPeerURLsMap  types.URLsMap
-	InitialClusterToken string
-	NewCluster          bool
-	ForceNewCluster     bool
-	PeerTLSInfo         transport.TLSInfo
-
-	TickMs        uint
-	ElectionTicks int
-
-	// InitialElectionTickAdvance is true, then local member fast-forwards
-	// election ticks to speed up "initial" leader election trigger. This
-	// benefits the case of larger election ticks. For instance, cross
-	// datacenter deployment may require longer election timeout of 10-second.
-	// If true, local node does not need wait up to 10-second. Instead,
-	// forwards its election ticks to 8-second, and have only 2-second left
-	// before leader election.
-	//
-	// Major assumptions are that:
-	//  - cluster has no active leader thus advancing ticks enables faster
-	//    leader election, or
-	//  - cluster already has an established leader, and rejoining follower
-	//    is likely to receive heartbeats from the leader after tick advance
-	//    and before election timeout.
-	//
-	// However, when network from leader to rejoining follower is congested,
-	// and the follower does not receive leader heartbeat within left election
-	// ticks, disruptive election has to happen thus affecting cluster
-	// availabilities.
-	//
-	// Disabling this would slow down initial bootstrap process for cross
-	// datacenter deployments. Make your own tradeoffs by configuring
-	// --initial-election-tick-advance at the cost of slow initial bootstrap.
-	//
-	// If single-node, it advances ticks regardless.
-	//
-	// See https://github.com/coreos/etcd/issues/9333 for more detail.
-	InitialElectionTickAdvance bool
-
-	BootstrapTimeout time.Duration
-
-	AutoCompactionRetention time.Duration
-	AutoCompactionMode      string
-	QuotaBackendBytes       int64
-	MaxTxnOps               uint
-
-	// MaxRequestBytes is the maximum request size to send over raft.
-	MaxRequestBytes uint
-
-	StrictReconfigCheck bool
-
-	// ClientCertAuthEnabled is true when cert has been signed by the client CA.
-	ClientCertAuthEnabled bool
-
-	AuthToken string
-
-	// InitialCorruptCheck is true to check data corruption on boot
-	// before serving any peer/client traffic.
-	InitialCorruptCheck bool
-	CorruptCheckTime    time.Duration
-
-	Debug bool
-}
-
-// VerifyBootstrap sanity-checks the initial config for bootstrap case
-// and returns an error for things that should never happen.
-func (c *ServerConfig) VerifyBootstrap() error {
-	if err := c.hasLocalMember(); err != nil {
-		return err
-	}
-	if err := c.advertiseMatchesCluster(); err != nil {
-		return err
-	}
-	if checkDuplicateURL(c.InitialPeerURLsMap) {
-		return fmt.Errorf("initial cluster %s has duplicate url", c.InitialPeerURLsMap)
-	}
-	if c.InitialPeerURLsMap.String() == "" && c.DiscoveryURL == "" {
-		return fmt.Errorf("initial cluster unset and no discovery URL found")
-	}
-	return nil
-}
-
-// VerifyJoinExisting sanity-checks the initial config for join existing cluster
-// case and returns an error for things that should never happen.
-func (c *ServerConfig) VerifyJoinExisting() error {
-	// The member has announced its peer urls to the cluster before starting; no need to
-	// set the configuration again.
-	if err := c.hasLocalMember(); err != nil {
-		return err
-	}
-	if checkDuplicateURL(c.InitialPeerURLsMap) {
-		return fmt.Errorf("initial cluster %s has duplicate url", c.InitialPeerURLsMap)
-	}
-	if c.DiscoveryURL != "" {
-		return fmt.Errorf("discovery URL should not be set when joining existing initial cluster")
-	}
-	return nil
-}
-
-// hasLocalMember checks that the cluster at least contains the local server.
-func (c *ServerConfig) hasLocalMember() error {
-	if urls := c.InitialPeerURLsMap[c.Name]; urls == nil {
-		return fmt.Errorf("couldn't find local name %q in the initial cluster configuration", c.Name)
-	}
-	return nil
-}
-
-// advertiseMatchesCluster confirms peer URLs match those in the cluster peer list.
-func (c *ServerConfig) advertiseMatchesCluster() error {
-	urls, apurls := c.InitialPeerURLsMap[c.Name], c.PeerURLs.StringSlice()
-	urls.Sort()
-	sort.Strings(apurls)
-	ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second)
-	defer cancel()
-	ok, err := netutil.URLStringsEqual(ctx, apurls, urls.StringSlice())
-	if ok {
-		return nil
-	}
-
-	initMap, apMap := make(map[string]struct{}), make(map[string]struct{})
-	for _, url := range c.PeerURLs {
-		apMap[url.String()] = struct{}{}
-	}
-	for _, url := range c.InitialPeerURLsMap[c.Name] {
-		initMap[url.String()] = struct{}{}
-	}
-
-	missing := []string{}
-	for url := range initMap {
-		if _, ok := apMap[url]; !ok {
-			missing = append(missing, url)
-		}
-	}
-	if len(missing) > 0 {
-		for i := range missing {
-			missing[i] = c.Name + "=" + missing[i]
-		}
-		mstr := strings.Join(missing, ",")
-		apStr := strings.Join(apurls, ",")
-		return fmt.Errorf("--initial-cluster has %s but missing from --initial-advertise-peer-urls=%s (%v)", mstr, apStr, err)
-	}
-
-	for url := range apMap {
-		if _, ok := initMap[url]; !ok {
-			missing = append(missing, url)
-		}
-	}
-	if len(missing) > 0 {
-		mstr := strings.Join(missing, ",")
-		umap := types.URLsMap(map[string]types.URLs{c.Name: c.PeerURLs})
-		return fmt.Errorf("--initial-advertise-peer-urls has %s but missing from --initial-cluster=%s", mstr, umap.String())
-	}
-
-	// resolved URLs from "--initial-advertise-peer-urls" and "--initial-cluster" did not match or failed
-	apStr := strings.Join(apurls, ",")
-	umap := types.URLsMap(map[string]types.URLs{c.Name: c.PeerURLs})
-	return fmt.Errorf("failed to resolve %s to match --initial-cluster=%s (%v)", apStr, umap.String(), err)
-}
-
-func (c *ServerConfig) MemberDir() string { return filepath.Join(c.DataDir, "member") }
-
-func (c *ServerConfig) WALDir() string {
-	if c.DedicatedWALDir != "" {
-		return c.DedicatedWALDir
-	}
-	return filepath.Join(c.MemberDir(), "wal")
-}
-
-func (c *ServerConfig) SnapDir() string { return filepath.Join(c.MemberDir(), "snap") }
-
-func (c *ServerConfig) ShouldDiscover() bool { return c.DiscoveryURL != "" }
-
-// ReqTimeout returns timeout for request to finish.
-func (c *ServerConfig) ReqTimeout() time.Duration {
-	// 5s for queue waiting, computation and disk IO delay
-	// + 2 * election timeout for possible leader election
-	return 5*time.Second + 2*time.Duration(c.ElectionTicks*int(c.TickMs))*time.Millisecond
-}
-
-func (c *ServerConfig) electionTimeout() time.Duration {
-	return time.Duration(c.ElectionTicks*int(c.TickMs)) * time.Millisecond
-}
-
-func (c *ServerConfig) peerDialTimeout() time.Duration {
-	// 1s for queue wait and election timeout
-	return time.Second + time.Duration(c.ElectionTicks*int(c.TickMs))*time.Millisecond
-}
-
-func (c *ServerConfig) PrintWithInitial() { c.print(true) }
-
-func (c *ServerConfig) Print() { c.print(false) }
-
-func (c *ServerConfig) print(initial bool) {
-	plog.Infof("name = %s", c.Name)
-	if c.ForceNewCluster {
-		plog.Infof("force new cluster")
-	}
-	plog.Infof("data dir = %s", c.DataDir)
-	plog.Infof("member dir = %s", c.MemberDir())
-	if c.DedicatedWALDir != "" {
-		plog.Infof("dedicated WAL dir = %s", c.DedicatedWALDir)
-	}
-	plog.Infof("heartbeat = %dms", c.TickMs)
-	plog.Infof("election = %dms", c.ElectionTicks*int(c.TickMs))
-	plog.Infof("snapshot count = %d", c.SnapCount)
-	if len(c.DiscoveryURL) != 0 {
-		plog.Infof("discovery URL= %s", c.DiscoveryURL)
-		if len(c.DiscoveryProxy) != 0 {
-			plog.Infof("discovery proxy = %s", c.DiscoveryProxy)
-		}
-	}
-	plog.Infof("advertise client URLs = %s", c.ClientURLs)
-	if initial {
-		plog.Infof("initial advertise peer URLs = %s", c.PeerURLs)
-		plog.Infof("initial cluster = %s", c.InitialPeerURLsMap)
-	}
-}
-
-func checkDuplicateURL(urlsmap types.URLsMap) bool {
-	um := make(map[string]bool)
-	for _, urls := range urlsmap {
-		for _, url := range urls {
-			u := url.String()
-			if um[u] {
-				return true
-			}
-			um[u] = true
-		}
-	}
-	return false
-}
-
-func (c *ServerConfig) bootstrapTimeout() time.Duration {
-	if c.BootstrapTimeout != 0 {
-		return c.BootstrapTimeout
-	}
-	return time.Second
-}
-
-func (c *ServerConfig) backendPath() string { return filepath.Join(c.SnapDir(), "db") }
diff --git a/vendor/github.com/coreos/etcd/etcdserver/consistent_index.go b/vendor/github.com/coreos/etcd/etcdserver/consistent_index.go
deleted file mode 100644
index d513f67..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/consistent_index.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"sync/atomic"
-)
-
-// consistentIndex represents the offset of an entry in a consistent replica log.
-// It implements the mvcc.ConsistentIndexGetter interface.
-// It is always set to the offset of current entry before executing the entry,
-// so ConsistentWatchableKV could get the consistent index from it.
-type consistentIndex uint64
-
-func (i *consistentIndex) setConsistentIndex(v uint64) {
-	atomic.StoreUint64((*uint64)(i), v)
-}
-
-func (i *consistentIndex) ConsistentIndex() uint64 {
-	return atomic.LoadUint64((*uint64)(i))
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/corrupt.go b/vendor/github.com/coreos/etcd/etcdserver/corrupt.go
deleted file mode 100644
index d998ec5..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/corrupt.go
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"context"
-	"fmt"
-	"time"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc"
-	"github.com/coreos/etcd/pkg/types"
-)
-
-// CheckInitialHashKV compares initial hash values with its peers
-// before serving any peer/client traffic. Only mismatch when hashes
-// are different at requested revision, with same compact revision.
-func (s *EtcdServer) CheckInitialHashKV() error {
-	if !s.Cfg.InitialCorruptCheck {
-		return nil
-	}
-
-	plog.Infof("%s starting initial corruption check with timeout %v...", s.ID(), s.Cfg.ReqTimeout())
-	h, rev, crev, err := s.kv.HashByRev(0)
-	if err != nil {
-		return fmt.Errorf("%s failed to fetch hash (%v)", s.ID(), err)
-	}
-	peers := s.getPeerHashKVs(rev)
-	mismatch := 0
-	for _, p := range peers {
-		if p.resp != nil {
-			peerID := types.ID(p.resp.Header.MemberId)
-			if h != p.resp.Hash {
-				if crev == p.resp.CompactRevision {
-					plog.Errorf("%s's hash %d != %s's hash %d (revision %d, peer revision %d, compact revision %d)", s.ID(), h, peerID, p.resp.Hash, rev, p.resp.Header.Revision, crev)
-					mismatch++
-				} else {
-					plog.Warningf("%s cannot check hash of peer(%s): peer has a different compact revision %d (revision:%d)", s.ID(), peerID, p.resp.CompactRevision, rev)
-				}
-			}
-			continue
-		}
-		if p.err != nil {
-			switch p.err {
-			case rpctypes.ErrFutureRev:
-				plog.Warningf("%s cannot check the hash of peer(%q) at revision %d: peer is lagging behind(%q)", s.ID(), p.eps, rev, p.err.Error())
-			case rpctypes.ErrCompacted:
-				plog.Warningf("%s cannot check the hash of peer(%q) at revision %d: local node is lagging behind(%q)", s.ID(), p.eps, rev, p.err.Error())
-			}
-		}
-	}
-	if mismatch > 0 {
-		return fmt.Errorf("%s found data inconsistency with peers", s.ID())
-	}
-
-	plog.Infof("%s succeeded on initial corruption checking: no corruption", s.ID())
-	return nil
-}
-
-func (s *EtcdServer) monitorKVHash() {
-	t := s.Cfg.CorruptCheckTime
-	if t == 0 {
-		return
-	}
-	plog.Infof("enabled corruption checking with %s interval", t)
-	for {
-		select {
-		case <-s.stopping:
-			return
-		case <-time.After(t):
-		}
-		if !s.isLeader() {
-			continue
-		}
-		if err := s.checkHashKV(); err != nil {
-			plog.Debugf("check hash kv failed %v", err)
-		}
-	}
-}
-
-func (s *EtcdServer) checkHashKV() error {
-	h, rev, crev, err := s.kv.HashByRev(0)
-	if err != nil {
-		plog.Fatalf("failed to hash kv store (%v)", err)
-	}
-	peers := s.getPeerHashKVs(rev)
-
-	ctx, cancel := context.WithTimeout(context.Background(), s.Cfg.ReqTimeout())
-	err = s.linearizableReadNotify(ctx)
-	cancel()
-	if err != nil {
-		return err
-	}
-
-	h2, rev2, crev2, err := s.kv.HashByRev(0)
-	if err != nil {
-		plog.Warningf("failed to hash kv store (%v)", err)
-		return err
-	}
-
-	alarmed := false
-	mismatch := func(id uint64) {
-		if alarmed {
-			return
-		}
-		alarmed = true
-		a := &pb.AlarmRequest{
-			MemberID: uint64(id),
-			Action:   pb.AlarmRequest_ACTIVATE,
-			Alarm:    pb.AlarmType_CORRUPT,
-		}
-		s.goAttach(func() {
-			s.raftRequest(s.ctx, pb.InternalRaftRequest{Alarm: a})
-		})
-	}
-
-	if h2 != h && rev2 == rev && crev == crev2 {
-		plog.Warningf("mismatched hashes %d and %d for revision %d", h, h2, rev)
-		mismatch(uint64(s.ID()))
-	}
-
-	for _, p := range peers {
-		if p.resp == nil {
-			continue
-		}
-		id := p.resp.Header.MemberId
-
-		// leader expects follower's latest revision less than or equal to leader's
-		if p.resp.Header.Revision > rev2 {
-			plog.Warningf(
-				"revision %d from member %v, expected at most %d",
-				p.resp.Header.Revision,
-				types.ID(id),
-				rev2)
-			mismatch(id)
-		}
-
-		// leader expects follower's latest compact revision less than or equal to leader's
-		if p.resp.CompactRevision > crev2 {
-			plog.Warningf(
-				"compact revision %d from member %v, expected at most %d",
-				p.resp.CompactRevision,
-				types.ID(id),
-				crev2,
-			)
-			mismatch(id)
-		}
-
-		// follower's compact revision is leader's old one, then hashes must match
-		if p.resp.CompactRevision == crev && p.resp.Hash != h {
-			plog.Warningf(
-				"hash %d at revision %d from member %v, expected hash %d",
-				p.resp.Hash,
-				rev,
-				types.ID(id),
-				h,
-			)
-			mismatch(id)
-		}
-	}
-	return nil
-}
-
-type peerHashKVResp struct {
-	resp *clientv3.HashKVResponse
-	err  error
-	eps  []string
-}
-
-func (s *EtcdServer) getPeerHashKVs(rev int64) (resps []*peerHashKVResp) {
-	// TODO: handle the case when "s.cluster.Members" have not
-	// been populated (e.g. no snapshot to load from disk)
-	mbs := s.cluster.Members()
-	pURLs := make([][]string, len(mbs))
-	for _, m := range mbs {
-		if m.ID == s.ID() {
-			continue
-		}
-		pURLs = append(pURLs, m.PeerURLs)
-	}
-
-	for _, purls := range pURLs {
-		if len(purls) == 0 {
-			continue
-		}
-		cli, cerr := clientv3.New(clientv3.Config{
-			DialTimeout: s.Cfg.ReqTimeout(),
-			Endpoints:   purls,
-		})
-		if cerr != nil {
-			plog.Warningf("%s failed to create client to peer %q for hash checking (%q)", s.ID(), purls, cerr.Error())
-			continue
-		}
-
-		respsLen := len(resps)
-		for _, c := range cli.Endpoints() {
-			ctx, cancel := context.WithTimeout(context.Background(), s.Cfg.ReqTimeout())
-			var resp *clientv3.HashKVResponse
-			resp, cerr = cli.HashKV(ctx, c, rev)
-			cancel()
-			if cerr == nil {
-				resps = append(resps, &peerHashKVResp{resp: resp})
-				break
-			}
-			plog.Warningf("%s hash-kv error %q on peer %q with revision %d", s.ID(), cerr.Error(), c, rev)
-		}
-		cli.Close()
-
-		if respsLen == len(resps) {
-			resps = append(resps, &peerHashKVResp{err: cerr, eps: purls})
-		}
-	}
-	return resps
-}
-
-type applierV3Corrupt struct {
-	applierV3
-}
-
-func newApplierV3Corrupt(a applierV3) *applierV3Corrupt { return &applierV3Corrupt{a} }
-
-func (a *applierV3Corrupt) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*pb.PutResponse, error) {
-	return nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) Range(txn mvcc.TxnRead, p *pb.RangeRequest) (*pb.RangeResponse, error) {
-	return nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) DeleteRange(txn mvcc.TxnWrite, p *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	return nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) {
-	return nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) Compaction(compaction *pb.CompactionRequest) (*pb.CompactionResponse, <-chan struct{}, error) {
-	return nil, nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	return nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	return nil, ErrCorrupt
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/doc.go b/vendor/github.com/coreos/etcd/etcdserver/doc.go
deleted file mode 100644
index b195d2d..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package etcdserver defines how etcd servers interact and store their states.
-package etcdserver
diff --git a/vendor/github.com/coreos/etcd/etcdserver/errors.go b/vendor/github.com/coreos/etcd/etcdserver/errors.go
deleted file mode 100644
index fb93c4b..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/errors.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"errors"
-	"fmt"
-)
-
-var (
-	ErrUnknownMethod              = errors.New("etcdserver: unknown method")
-	ErrStopped                    = errors.New("etcdserver: server stopped")
-	ErrCanceled                   = errors.New("etcdserver: request cancelled")
-	ErrTimeout                    = errors.New("etcdserver: request timed out")
-	ErrTimeoutDueToLeaderFail     = errors.New("etcdserver: request timed out, possibly due to previous leader failure")
-	ErrTimeoutDueToConnectionLost = errors.New("etcdserver: request timed out, possibly due to connection lost")
-	ErrTimeoutLeaderTransfer      = errors.New("etcdserver: request timed out, leader transfer took too long")
-	ErrNotEnoughStartedMembers    = errors.New("etcdserver: re-configuration failed due to not enough started members")
-	ErrNoLeader                   = errors.New("etcdserver: no leader")
-	ErrNotLeader                  = errors.New("etcdserver: not leader")
-	ErrRequestTooLarge            = errors.New("etcdserver: request is too large")
-	ErrNoSpace                    = errors.New("etcdserver: no space")
-	ErrTooManyRequests            = errors.New("etcdserver: too many requests")
-	ErrUnhealthy                  = errors.New("etcdserver: unhealthy cluster")
-	ErrKeyNotFound                = errors.New("etcdserver: key not found")
-	ErrCorrupt                    = errors.New("etcdserver: corrupt cluster")
-)
-
-type DiscoveryError struct {
-	Op  string
-	Err error
-}
-
-func (e DiscoveryError) Error() string {
-	return fmt.Sprintf("failed to %s discovery cluster (%v)", e.Op, e.Err)
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/gw/rpc.pb.gw.go b/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/gw/rpc.pb.gw.go
deleted file mode 100644
index c50525b..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/gw/rpc.pb.gw.go
+++ /dev/null
@@ -1,2134 +0,0 @@
-// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
-// source: etcdserver/etcdserverpb/rpc.proto
-
-/*
-Package etcdserverpb is a reverse proxy.
-
-It translates gRPC into RESTful JSON APIs.
-*/
-package gw
-
-import (
-	"github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"io"
-	"net/http"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/grpc-ecosystem/grpc-gateway/runtime"
-	"github.com/grpc-ecosystem/grpc-gateway/utilities"
-	"golang.org/x/net/context"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/grpclog"
-	"google.golang.org/grpc/status"
-)
-
-var _ codes.Code
-var _ io.Reader
-var _ status.Status
-var _ = runtime.String
-var _ = utilities.NewDoubleArray
-
-func request_KV_Range_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.RangeRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Range(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_KV_Put_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.PutRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Put(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_KV_DeleteRange_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.DeleteRangeRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.DeleteRange(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_KV_Txn_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.TxnRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Txn(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_KV_Compact_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.CompactionRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Compact(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.WatchClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Watch_WatchClient, runtime.ServerMetadata, error) {
-	var metadata runtime.ServerMetadata
-	stream, err := client.Watch(ctx)
-	if err != nil {
-		grpclog.Printf("Failed to start streaming: %v", err)
-		return nil, metadata, err
-	}
-	dec := marshaler.NewDecoder(req.Body)
-	handleSend := func() error {
-		var protoReq etcdserverpb.WatchRequest
-		err = dec.Decode(&protoReq)
-		if err == io.EOF {
-			return err
-		}
-		if err != nil {
-			grpclog.Printf("Failed to decode request: %v", err)
-			return err
-		}
-		if err = stream.Send(&protoReq); err != nil {
-			grpclog.Printf("Failed to send request: %v", err)
-			return err
-		}
-		return nil
-	}
-	if err := handleSend(); err != nil {
-		if cerr := stream.CloseSend(); cerr != nil {
-			grpclog.Printf("Failed to terminate client stream: %v", cerr)
-		}
-		if err == io.EOF {
-			return stream, metadata, nil
-		}
-		return nil, metadata, err
-	}
-	go func() {
-		for {
-			if err := handleSend(); err != nil {
-				break
-			}
-		}
-		if err := stream.CloseSend(); err != nil {
-			grpclog.Printf("Failed to terminate client stream: %v", err)
-		}
-	}()
-	header, err := stream.Header()
-	if err != nil {
-		grpclog.Printf("Failed to get header from client: %v", err)
-		return nil, metadata, err
-	}
-	metadata.HeaderMD = header
-	return stream, metadata, nil
-}
-
-func request_Lease_LeaseGrant_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseGrantRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.LeaseGrant(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lease_LeaseRevoke_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseRevokeRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.LeaseRevoke(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Lease_LeaseKeepAliveClient, runtime.ServerMetadata, error) {
-	var metadata runtime.ServerMetadata
-	stream, err := client.LeaseKeepAlive(ctx)
-	if err != nil {
-		grpclog.Printf("Failed to start streaming: %v", err)
-		return nil, metadata, err
-	}
-	dec := marshaler.NewDecoder(req.Body)
-	handleSend := func() error {
-		var protoReq etcdserverpb.LeaseKeepAliveRequest
-		err = dec.Decode(&protoReq)
-		if err == io.EOF {
-			return err
-		}
-		if err != nil {
-			grpclog.Printf("Failed to decode request: %v", err)
-			return err
-		}
-		if err = stream.Send(&protoReq); err != nil {
-			grpclog.Printf("Failed to send request: %v", err)
-			return err
-		}
-		return nil
-	}
-	if err := handleSend(); err != nil {
-		if cerr := stream.CloseSend(); cerr != nil {
-			grpclog.Printf("Failed to terminate client stream: %v", cerr)
-		}
-		if err == io.EOF {
-			return stream, metadata, nil
-		}
-		return nil, metadata, err
-	}
-	go func() {
-		for {
-			if err := handleSend(); err != nil {
-				break
-			}
-		}
-		if err := stream.CloseSend(); err != nil {
-			grpclog.Printf("Failed to terminate client stream: %v", err)
-		}
-	}()
-	header, err := stream.Header()
-	if err != nil {
-		grpclog.Printf("Failed to get header from client: %v", err)
-		return nil, metadata, err
-	}
-	metadata.HeaderMD = header
-	return stream, metadata, nil
-}
-
-func request_Lease_LeaseTimeToLive_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseTimeToLiveRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.LeaseTimeToLive(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lease_LeaseLeases_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseLeasesRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.LeaseLeases(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Cluster_MemberAdd_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MemberAddRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.MemberAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Cluster_MemberRemove_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MemberRemoveRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.MemberRemove(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Cluster_MemberUpdate_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MemberUpdateRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.MemberUpdate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Cluster_MemberList_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MemberListRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.MemberList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_Alarm_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AlarmRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Alarm(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_Status_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.StatusRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Status(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_Defragment_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.DefragmentRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Defragment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_Hash_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.HashRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Hash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_HashKV_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.HashKVRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.HashKV(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_Snapshot_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Maintenance_SnapshotClient, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.SnapshotRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	stream, err := client.Snapshot(ctx, &protoReq)
-	if err != nil {
-		return nil, metadata, err
-	}
-	header, err := stream.Header()
-	if err != nil {
-		return nil, metadata, err
-	}
-	metadata.HeaderMD = header
-	return stream, metadata, nil
-
-}
-
-func request_Maintenance_MoveLeader_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MoveLeaderRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.MoveLeader(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_AuthEnable_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthEnableRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.AuthEnable(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_AuthDisable_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthDisableRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.AuthDisable(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_Authenticate_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthenticateRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Authenticate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserAdd_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserAddRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.UserAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserGet_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserGetRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.UserGet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserList_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserListRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.UserList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserDelete_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserDeleteRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.UserDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserChangePassword_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserChangePasswordRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.UserChangePassword(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserGrantRole_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserGrantRoleRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.UserGrantRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserRevokeRole_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserRevokeRoleRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.UserRevokeRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleAdd_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleAddRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.RoleAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleGet_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleGetRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.RoleGet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleList_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleListRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.RoleList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleDelete_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleDeleteRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.RoleDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleGrantPermission_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleGrantPermissionRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.RoleGrantPermission(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleRevokePermission_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleRevokePermissionRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.RoleRevokePermission(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-// RegisterKVHandlerFromEndpoint is same as RegisterKVHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterKVHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if err != nil {
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-			return
-		}
-		go func() {
-			<-ctx.Done()
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-		}()
-	}()
-
-	return RegisterKVHandler(ctx, mux, conn)
-}
-
-// RegisterKVHandler registers the http handlers for service KV to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterKVHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterKVHandlerClient(ctx, mux, etcdserverpb.NewKVClient(conn))
-}
-
-// RegisterKVHandler registers the http handlers for service KV to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "KVClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "KVClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "KVClient" to call the correct interceptors.
-func RegisterKVHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.KVClient) error {
-
-	mux.Handle("POST", pattern_KV_Range_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_KV_Range_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_KV_Range_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_KV_Put_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_KV_Put_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_KV_Put_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_KV_DeleteRange_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_KV_DeleteRange_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_KV_DeleteRange_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_KV_Txn_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_KV_Txn_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_KV_Txn_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_KV_Compact_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_KV_Compact_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_KV_Compact_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_KV_Range_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "kv", "range"}, ""))
-
-	pattern_KV_Put_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "kv", "put"}, ""))
-
-	pattern_KV_DeleteRange_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "kv", "deleterange"}, ""))
-
-	pattern_KV_Txn_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "kv", "txn"}, ""))
-
-	pattern_KV_Compact_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "kv", "compaction"}, ""))
-)
-
-var (
-	forward_KV_Range_0 = runtime.ForwardResponseMessage
-
-	forward_KV_Put_0 = runtime.ForwardResponseMessage
-
-	forward_KV_DeleteRange_0 = runtime.ForwardResponseMessage
-
-	forward_KV_Txn_0 = runtime.ForwardResponseMessage
-
-	forward_KV_Compact_0 = runtime.ForwardResponseMessage
-)
-
-// RegisterWatchHandlerFromEndpoint is same as RegisterWatchHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterWatchHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if err != nil {
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-			return
-		}
-		go func() {
-			<-ctx.Done()
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-		}()
-	}()
-
-	return RegisterWatchHandler(ctx, mux, conn)
-}
-
-// RegisterWatchHandler registers the http handlers for service Watch to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterWatchHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterWatchHandlerClient(ctx, mux, etcdserverpb.NewWatchClient(conn))
-}
-
-// RegisterWatchHandler registers the http handlers for service Watch to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "WatchClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "WatchClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "WatchClient" to call the correct interceptors.
-func RegisterWatchHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.WatchClient) error {
-
-	mux.Handle("POST", pattern_Watch_Watch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Watch_Watch_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Watch_Watch_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Watch_Watch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v3beta", "watch"}, ""))
-)
-
-var (
-	forward_Watch_Watch_0 = runtime.ForwardResponseStream
-)
-
-// RegisterLeaseHandlerFromEndpoint is same as RegisterLeaseHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterLeaseHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if err != nil {
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-			return
-		}
-		go func() {
-			<-ctx.Done()
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-		}()
-	}()
-
-	return RegisterLeaseHandler(ctx, mux, conn)
-}
-
-// RegisterLeaseHandler registers the http handlers for service Lease to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterLeaseHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterLeaseHandlerClient(ctx, mux, etcdserverpb.NewLeaseClient(conn))
-}
-
-// RegisterLeaseHandler registers the http handlers for service Lease to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "LeaseClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "LeaseClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "LeaseClient" to call the correct interceptors.
-func RegisterLeaseHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.LeaseClient) error {
-
-	mux.Handle("POST", pattern_Lease_LeaseGrant_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Lease_LeaseGrant_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseGrant_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseRevoke_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Lease_LeaseRevoke_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseRevoke_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseKeepAlive_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Lease_LeaseKeepAlive_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseKeepAlive_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseTimeToLive_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Lease_LeaseTimeToLive_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseTimeToLive_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseLeases_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Lease_LeaseLeases_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseLeases_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Lease_LeaseGrant_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "lease", "grant"}, ""))
-
-	pattern_Lease_LeaseRevoke_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "kv", "lease", "revoke"}, ""))
-
-	pattern_Lease_LeaseKeepAlive_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "lease", "keepalive"}, ""))
-
-	pattern_Lease_LeaseTimeToLive_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "kv", "lease", "timetolive"}, ""))
-
-	pattern_Lease_LeaseLeases_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "kv", "lease", "leases"}, ""))
-)
-
-var (
-	forward_Lease_LeaseGrant_0 = runtime.ForwardResponseMessage
-
-	forward_Lease_LeaseRevoke_0 = runtime.ForwardResponseMessage
-
-	forward_Lease_LeaseKeepAlive_0 = runtime.ForwardResponseStream
-
-	forward_Lease_LeaseTimeToLive_0 = runtime.ForwardResponseMessage
-
-	forward_Lease_LeaseLeases_0 = runtime.ForwardResponseMessage
-)
-
-// RegisterClusterHandlerFromEndpoint is same as RegisterClusterHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterClusterHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if err != nil {
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-			return
-		}
-		go func() {
-			<-ctx.Done()
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-		}()
-	}()
-
-	return RegisterClusterHandler(ctx, mux, conn)
-}
-
-// RegisterClusterHandler registers the http handlers for service Cluster to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterClusterHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterClusterHandlerClient(ctx, mux, etcdserverpb.NewClusterClient(conn))
-}
-
-// RegisterClusterHandler registers the http handlers for service Cluster to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "ClusterClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ClusterClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "ClusterClient" to call the correct interceptors.
-func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.ClusterClient) error {
-
-	mux.Handle("POST", pattern_Cluster_MemberAdd_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Cluster_MemberAdd_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Cluster_MemberAdd_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Cluster_MemberRemove_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Cluster_MemberRemove_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Cluster_MemberRemove_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Cluster_MemberUpdate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Cluster_MemberUpdate_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Cluster_MemberUpdate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Cluster_MemberList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Cluster_MemberList_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Cluster_MemberList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Cluster_MemberAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "cluster", "member", "add"}, ""))
-
-	pattern_Cluster_MemberRemove_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "cluster", "member", "remove"}, ""))
-
-	pattern_Cluster_MemberUpdate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "cluster", "member", "update"}, ""))
-
-	pattern_Cluster_MemberList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "cluster", "member", "list"}, ""))
-)
-
-var (
-	forward_Cluster_MemberAdd_0 = runtime.ForwardResponseMessage
-
-	forward_Cluster_MemberRemove_0 = runtime.ForwardResponseMessage
-
-	forward_Cluster_MemberUpdate_0 = runtime.ForwardResponseMessage
-
-	forward_Cluster_MemberList_0 = runtime.ForwardResponseMessage
-)
-
-// RegisterMaintenanceHandlerFromEndpoint is same as RegisterMaintenanceHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterMaintenanceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if err != nil {
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-			return
-		}
-		go func() {
-			<-ctx.Done()
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-		}()
-	}()
-
-	return RegisterMaintenanceHandler(ctx, mux, conn)
-}
-
-// RegisterMaintenanceHandler registers the http handlers for service Maintenance to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterMaintenanceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterMaintenanceHandlerClient(ctx, mux, etcdserverpb.NewMaintenanceClient(conn))
-}
-
-// RegisterMaintenanceHandler registers the http handlers for service Maintenance to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "MaintenanceClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MaintenanceClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "MaintenanceClient" to call the correct interceptors.
-func RegisterMaintenanceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.MaintenanceClient) error {
-
-	mux.Handle("POST", pattern_Maintenance_Alarm_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Maintenance_Alarm_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_Alarm_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_Status_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Maintenance_Status_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_Status_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_Defragment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Maintenance_Defragment_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_Defragment_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_Hash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Maintenance_Hash_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_Hash_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_HashKV_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Maintenance_HashKV_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_HashKV_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_Snapshot_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Maintenance_Snapshot_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_Snapshot_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_MoveLeader_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Maintenance_MoveLeader_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_MoveLeader_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Maintenance_Alarm_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "maintenance", "alarm"}, ""))
-
-	pattern_Maintenance_Status_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "maintenance", "status"}, ""))
-
-	pattern_Maintenance_Defragment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "maintenance", "defragment"}, ""))
-
-	pattern_Maintenance_Hash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "maintenance", "hash"}, ""))
-
-	pattern_Maintenance_HashKV_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "maintenance", "hash"}, ""))
-
-	pattern_Maintenance_Snapshot_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "maintenance", "snapshot"}, ""))
-
-	pattern_Maintenance_MoveLeader_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "maintenance", "transfer-leadership"}, ""))
-)
-
-var (
-	forward_Maintenance_Alarm_0 = runtime.ForwardResponseMessage
-
-	forward_Maintenance_Status_0 = runtime.ForwardResponseMessage
-
-	forward_Maintenance_Defragment_0 = runtime.ForwardResponseMessage
-
-	forward_Maintenance_Hash_0 = runtime.ForwardResponseMessage
-
-	forward_Maintenance_HashKV_0 = runtime.ForwardResponseMessage
-
-	forward_Maintenance_Snapshot_0 = runtime.ForwardResponseStream
-
-	forward_Maintenance_MoveLeader_0 = runtime.ForwardResponseMessage
-)
-
-// RegisterAuthHandlerFromEndpoint is same as RegisterAuthHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterAuthHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if err != nil {
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-			return
-		}
-		go func() {
-			<-ctx.Done()
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-		}()
-	}()
-
-	return RegisterAuthHandler(ctx, mux, conn)
-}
-
-// RegisterAuthHandler registers the http handlers for service Auth to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterAuthHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterAuthHandlerClient(ctx, mux, etcdserverpb.NewAuthClient(conn))
-}
-
-// RegisterAuthHandler registers the http handlers for service Auth to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "AuthClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "AuthClient" to call the correct interceptors.
-func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.AuthClient) error {
-
-	mux.Handle("POST", pattern_Auth_AuthEnable_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_AuthEnable_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_AuthEnable_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_AuthDisable_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_AuthDisable_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_AuthDisable_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_Authenticate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_Authenticate_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_Authenticate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserAdd_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_UserAdd_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserAdd_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserGet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_UserGet_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserGet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_UserList_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserDelete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_UserDelete_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserDelete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserChangePassword_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_UserChangePassword_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserChangePassword_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserGrantRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_UserGrantRole_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserGrantRole_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserRevokeRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_UserRevokeRole_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserRevokeRole_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleAdd_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_RoleAdd_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleAdd_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleGet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_RoleGet_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleGet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_RoleList_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleDelete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_RoleDelete_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleDelete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleGrantPermission_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_RoleGrantPermission_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleGrantPermission_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleRevokePermission_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Auth_RoleRevokePermission_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleRevokePermission_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Auth_AuthEnable_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "auth", "enable"}, ""))
-
-	pattern_Auth_AuthDisable_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "auth", "disable"}, ""))
-
-	pattern_Auth_Authenticate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3beta", "auth", "authenticate"}, ""))
-
-	pattern_Auth_UserAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "user", "add"}, ""))
-
-	pattern_Auth_UserGet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "user", "get"}, ""))
-
-	pattern_Auth_UserList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "user", "list"}, ""))
-
-	pattern_Auth_UserDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "user", "delete"}, ""))
-
-	pattern_Auth_UserChangePassword_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "user", "changepw"}, ""))
-
-	pattern_Auth_UserGrantRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "user", "grant"}, ""))
-
-	pattern_Auth_UserRevokeRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "user", "revoke"}, ""))
-
-	pattern_Auth_RoleAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "role", "add"}, ""))
-
-	pattern_Auth_RoleGet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "role", "get"}, ""))
-
-	pattern_Auth_RoleList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "role", "list"}, ""))
-
-	pattern_Auth_RoleDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "role", "delete"}, ""))
-
-	pattern_Auth_RoleGrantPermission_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "role", "grant"}, ""))
-
-	pattern_Auth_RoleRevokePermission_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3beta", "auth", "role", "revoke"}, ""))
-)
-
-var (
-	forward_Auth_AuthEnable_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_AuthDisable_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_Authenticate_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserAdd_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserGet_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserList_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserDelete_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserChangePassword_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserGrantRole_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserRevokeRole_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleAdd_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleGet_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleList_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleDelete_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleGrantPermission_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleRevokePermission_0 = runtime.ForwardResponseMessage
-)
diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go b/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go
deleted file mode 100644
index 4f0b157..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/membership/cluster.go
+++ /dev/null
@@ -1,512 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package membership
-
-import (
-	"bytes"
-	"context"
-	"crypto/sha1"
-	"encoding/binary"
-	"encoding/json"
-	"fmt"
-	"path"
-	"sort"
-	"strings"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/pkg/netutil"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/store"
-	"github.com/coreos/etcd/version"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-// RaftCluster is a list of Members that belong to the same raft cluster
-type RaftCluster struct {
-	id    types.ID
-	token string
-
-	store store.Store
-	be    backend.Backend
-
-	sync.Mutex // guards the fields below
-	version    *semver.Version
-	members    map[types.ID]*Member
-	// removed contains the ids of removed members in the cluster.
-	// removed id cannot be reused.
-	removed map[types.ID]bool
-}
-
-func NewClusterFromURLsMap(token string, urlsmap types.URLsMap) (*RaftCluster, error) {
-	c := NewCluster(token)
-	for name, urls := range urlsmap {
-		m := NewMember(name, urls, token, nil)
-		if _, ok := c.members[m.ID]; ok {
-			return nil, fmt.Errorf("member exists with identical ID %v", m)
-		}
-		if uint64(m.ID) == raft.None {
-			return nil, fmt.Errorf("cannot use %x as member id", raft.None)
-		}
-		c.members[m.ID] = m
-	}
-	c.genID()
-	return c, nil
-}
-
-func NewClusterFromMembers(token string, id types.ID, membs []*Member) *RaftCluster {
-	c := NewCluster(token)
-	c.id = id
-	for _, m := range membs {
-		c.members[m.ID] = m
-	}
-	return c
-}
-
-func NewCluster(token string) *RaftCluster {
-	return &RaftCluster{
-		token:   token,
-		members: make(map[types.ID]*Member),
-		removed: make(map[types.ID]bool),
-	}
-}
-
-func (c *RaftCluster) ID() types.ID { return c.id }
-
-func (c *RaftCluster) Members() []*Member {
-	c.Lock()
-	defer c.Unlock()
-	var ms MembersByID
-	for _, m := range c.members {
-		ms = append(ms, m.Clone())
-	}
-	sort.Sort(ms)
-	return []*Member(ms)
-}
-
-func (c *RaftCluster) Member(id types.ID) *Member {
-	c.Lock()
-	defer c.Unlock()
-	return c.members[id].Clone()
-}
-
-// MemberByName returns a Member with the given name if exists.
-// If more than one member has the given name, it will panic.
-func (c *RaftCluster) MemberByName(name string) *Member {
-	c.Lock()
-	defer c.Unlock()
-	var memb *Member
-	for _, m := range c.members {
-		if m.Name == name {
-			if memb != nil {
-				plog.Panicf("two members with the given name %q exist", name)
-			}
-			memb = m
-		}
-	}
-	return memb.Clone()
-}
-
-func (c *RaftCluster) MemberIDs() []types.ID {
-	c.Lock()
-	defer c.Unlock()
-	var ids []types.ID
-	for _, m := range c.members {
-		ids = append(ids, m.ID)
-	}
-	sort.Sort(types.IDSlice(ids))
-	return ids
-}
-
-func (c *RaftCluster) IsIDRemoved(id types.ID) bool {
-	c.Lock()
-	defer c.Unlock()
-	return c.removed[id]
-}
-
-// PeerURLs returns a list of all peer addresses.
-// The returned list is sorted in ascending lexicographical order.
-func (c *RaftCluster) PeerURLs() []string {
-	c.Lock()
-	defer c.Unlock()
-	urls := make([]string, 0)
-	for _, p := range c.members {
-		urls = append(urls, p.PeerURLs...)
-	}
-	sort.Strings(urls)
-	return urls
-}
-
-// ClientURLs returns a list of all client addresses.
-// The returned list is sorted in ascending lexicographical order.
-func (c *RaftCluster) ClientURLs() []string {
-	c.Lock()
-	defer c.Unlock()
-	urls := make([]string, 0)
-	for _, p := range c.members {
-		urls = append(urls, p.ClientURLs...)
-	}
-	sort.Strings(urls)
-	return urls
-}
-
-func (c *RaftCluster) String() string {
-	c.Lock()
-	defer c.Unlock()
-	b := &bytes.Buffer{}
-	fmt.Fprintf(b, "{ClusterID:%s ", c.id)
-	var ms []string
-	for _, m := range c.members {
-		ms = append(ms, fmt.Sprintf("%+v", m))
-	}
-	fmt.Fprintf(b, "Members:[%s] ", strings.Join(ms, " "))
-	var ids []string
-	for id := range c.removed {
-		ids = append(ids, id.String())
-	}
-	fmt.Fprintf(b, "RemovedMemberIDs:[%s]}", strings.Join(ids, " "))
-	return b.String()
-}
-
-func (c *RaftCluster) genID() {
-	mIDs := c.MemberIDs()
-	b := make([]byte, 8*len(mIDs))
-	for i, id := range mIDs {
-		binary.BigEndian.PutUint64(b[8*i:], uint64(id))
-	}
-	hash := sha1.Sum(b)
-	c.id = types.ID(binary.BigEndian.Uint64(hash[:8]))
-}
-
-func (c *RaftCluster) SetID(id types.ID) { c.id = id }
-
-func (c *RaftCluster) SetStore(st store.Store) { c.store = st }
-
-func (c *RaftCluster) SetBackend(be backend.Backend) {
-	c.be = be
-	mustCreateBackendBuckets(c.be)
-}
-
-func (c *RaftCluster) Recover(onSet func(*semver.Version)) {
-	c.Lock()
-	defer c.Unlock()
-
-	c.members, c.removed = membersFromStore(c.store)
-	c.version = clusterVersionFromStore(c.store)
-	mustDetectDowngrade(c.version)
-	onSet(c.version)
-
-	for _, m := range c.members {
-		plog.Infof("added member %s %v to cluster %s from store", m.ID, m.PeerURLs, c.id)
-	}
-	if c.version != nil {
-		plog.Infof("set the cluster version to %v from store", version.Cluster(c.version.String()))
-	}
-}
-
-// ValidateConfigurationChange takes a proposed ConfChange and
-// ensures that it is still valid.
-func (c *RaftCluster) ValidateConfigurationChange(cc raftpb.ConfChange) error {
-	members, removed := membersFromStore(c.store)
-	id := types.ID(cc.NodeID)
-	if removed[id] {
-		return ErrIDRemoved
-	}
-	switch cc.Type {
-	case raftpb.ConfChangeAddNode:
-		if members[id] != nil {
-			return ErrIDExists
-		}
-		urls := make(map[string]bool)
-		for _, m := range members {
-			for _, u := range m.PeerURLs {
-				urls[u] = true
-			}
-		}
-		m := new(Member)
-		if err := json.Unmarshal(cc.Context, m); err != nil {
-			plog.Panicf("unmarshal member should never fail: %v", err)
-		}
-		for _, u := range m.PeerURLs {
-			if urls[u] {
-				return ErrPeerURLexists
-			}
-		}
-	case raftpb.ConfChangeRemoveNode:
-		if members[id] == nil {
-			return ErrIDNotFound
-		}
-	case raftpb.ConfChangeUpdateNode:
-		if members[id] == nil {
-			return ErrIDNotFound
-		}
-		urls := make(map[string]bool)
-		for _, m := range members {
-			if m.ID == id {
-				continue
-			}
-			for _, u := range m.PeerURLs {
-				urls[u] = true
-			}
-		}
-		m := new(Member)
-		if err := json.Unmarshal(cc.Context, m); err != nil {
-			plog.Panicf("unmarshal member should never fail: %v", err)
-		}
-		for _, u := range m.PeerURLs {
-			if urls[u] {
-				return ErrPeerURLexists
-			}
-		}
-	default:
-		plog.Panicf("ConfChange type should be either AddNode, RemoveNode or UpdateNode")
-	}
-	return nil
-}
-
-// AddMember adds a new Member into the cluster, and saves the given member's
-// raftAttributes into the store. The given member should have empty attributes.
-// A Member with a matching id must not exist.
-func (c *RaftCluster) AddMember(m *Member) {
-	c.Lock()
-	defer c.Unlock()
-	if c.store != nil {
-		mustSaveMemberToStore(c.store, m)
-	}
-	if c.be != nil {
-		mustSaveMemberToBackend(c.be, m)
-	}
-
-	c.members[m.ID] = m
-
-	plog.Infof("added member %s %v to cluster %s", m.ID, m.PeerURLs, c.id)
-}
-
-// RemoveMember removes a member from the store.
-// The given id MUST exist, or the function panics.
-func (c *RaftCluster) RemoveMember(id types.ID) {
-	c.Lock()
-	defer c.Unlock()
-	if c.store != nil {
-		mustDeleteMemberFromStore(c.store, id)
-	}
-	if c.be != nil {
-		mustDeleteMemberFromBackend(c.be, id)
-	}
-
-	delete(c.members, id)
-	c.removed[id] = true
-
-	plog.Infof("removed member %s from cluster %s", id, c.id)
-}
-
-func (c *RaftCluster) UpdateAttributes(id types.ID, attr Attributes) {
-	c.Lock()
-	defer c.Unlock()
-	if m, ok := c.members[id]; ok {
-		m.Attributes = attr
-		if c.store != nil {
-			mustUpdateMemberAttrInStore(c.store, m)
-		}
-		if c.be != nil {
-			mustSaveMemberToBackend(c.be, m)
-		}
-		return
-	}
-	_, ok := c.removed[id]
-	if !ok {
-		plog.Panicf("error updating attributes of unknown member %s", id)
-	}
-	plog.Warningf("skipped updating attributes of removed member %s", id)
-}
-
-func (c *RaftCluster) UpdateRaftAttributes(id types.ID, raftAttr RaftAttributes) {
-	c.Lock()
-	defer c.Unlock()
-
-	c.members[id].RaftAttributes = raftAttr
-	if c.store != nil {
-		mustUpdateMemberInStore(c.store, c.members[id])
-	}
-	if c.be != nil {
-		mustSaveMemberToBackend(c.be, c.members[id])
-	}
-
-	plog.Noticef("updated member %s %v in cluster %s", id, raftAttr.PeerURLs, c.id)
-}
-
-func (c *RaftCluster) Version() *semver.Version {
-	c.Lock()
-	defer c.Unlock()
-	if c.version == nil {
-		return nil
-	}
-	return semver.Must(semver.NewVersion(c.version.String()))
-}
-
-func (c *RaftCluster) SetVersion(ver *semver.Version, onSet func(*semver.Version)) {
-	c.Lock()
-	defer c.Unlock()
-	if c.version != nil {
-		plog.Noticef("updated the cluster version from %v to %v", version.Cluster(c.version.String()), version.Cluster(ver.String()))
-	} else {
-		plog.Noticef("set the initial cluster version to %v", version.Cluster(ver.String()))
-	}
-	c.version = ver
-	mustDetectDowngrade(c.version)
-	if c.store != nil {
-		mustSaveClusterVersionToStore(c.store, ver)
-	}
-	if c.be != nil {
-		mustSaveClusterVersionToBackend(c.be, ver)
-	}
-	onSet(ver)
-}
-
-func (c *RaftCluster) IsReadyToAddNewMember() bool {
-	nmembers := 1
-	nstarted := 0
-
-	for _, member := range c.members {
-		if member.IsStarted() {
-			nstarted++
-		}
-		nmembers++
-	}
-
-	if nstarted == 1 && nmembers == 2 {
-		// a case of adding a new node to 1-member cluster for restoring cluster data
-		// https://github.com/coreos/etcd/blob/master/Documentation/v2/admin_guide.md#restoring-the-cluster
-
-		plog.Debugf("The number of started member is 1. This cluster can accept add member request.")
-		return true
-	}
-
-	nquorum := nmembers/2 + 1
-	if nstarted < nquorum {
-		plog.Warningf("Reject add member request: the number of started member (%d) will be less than the quorum number of the cluster (%d)", nstarted, nquorum)
-		return false
-	}
-
-	return true
-}
-
-func (c *RaftCluster) IsReadyToRemoveMember(id uint64) bool {
-	nmembers := 0
-	nstarted := 0
-
-	for _, member := range c.members {
-		if uint64(member.ID) == id {
-			continue
-		}
-
-		if member.IsStarted() {
-			nstarted++
-		}
-		nmembers++
-	}
-
-	nquorum := nmembers/2 + 1
-	if nstarted < nquorum {
-		plog.Warningf("Reject remove member request: the number of started member (%d) will be less than the quorum number of the cluster (%d)", nstarted, nquorum)
-		return false
-	}
-
-	return true
-}
-
-func membersFromStore(st store.Store) (map[types.ID]*Member, map[types.ID]bool) {
-	members := make(map[types.ID]*Member)
-	removed := make(map[types.ID]bool)
-	e, err := st.Get(StoreMembersPrefix, true, true)
-	if err != nil {
-		if isKeyNotFound(err) {
-			return members, removed
-		}
-		plog.Panicf("get storeMembers should never fail: %v", err)
-	}
-	for _, n := range e.Node.Nodes {
-		var m *Member
-		m, err = nodeToMember(n)
-		if err != nil {
-			plog.Panicf("nodeToMember should never fail: %v", err)
-		}
-		members[m.ID] = m
-	}
-
-	e, err = st.Get(storeRemovedMembersPrefix, true, true)
-	if err != nil {
-		if isKeyNotFound(err) {
-			return members, removed
-		}
-		plog.Panicf("get storeRemovedMembers should never fail: %v", err)
-	}
-	for _, n := range e.Node.Nodes {
-		removed[MustParseMemberIDFromKey(n.Key)] = true
-	}
-	return members, removed
-}
-
-func clusterVersionFromStore(st store.Store) *semver.Version {
-	e, err := st.Get(path.Join(storePrefix, "version"), false, false)
-	if err != nil {
-		if isKeyNotFound(err) {
-			return nil
-		}
-		plog.Panicf("unexpected error (%v) when getting cluster version from store", err)
-	}
-	return semver.Must(semver.NewVersion(*e.Node.Value))
-}
-
-// ValidateClusterAndAssignIDs validates the local cluster by matching the PeerURLs
-// with the existing cluster. If the validation succeeds, it assigns the IDs
-// from the existing cluster to the local cluster.
-// If the validation fails, an error will be returned.
-func ValidateClusterAndAssignIDs(local *RaftCluster, existing *RaftCluster) error {
-	ems := existing.Members()
-	lms := local.Members()
-	if len(ems) != len(lms) {
-		return fmt.Errorf("member count is unequal")
-	}
-	sort.Sort(MembersByPeerURLs(ems))
-	sort.Sort(MembersByPeerURLs(lms))
-
-	ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second)
-	defer cancel()
-	for i := range ems {
-		if ok, err := netutil.URLStringsEqual(ctx, ems[i].PeerURLs, lms[i].PeerURLs); !ok {
-			return fmt.Errorf("unmatched member while checking PeerURLs (%v)", err)
-		}
-		lms[i].ID = ems[i].ID
-	}
-	local.members = make(map[types.ID]*Member)
-	for _, m := range lms {
-		local.members[m.ID] = m
-	}
-	return nil
-}
-
-func mustDetectDowngrade(cv *semver.Version) {
-	lv := semver.Must(semver.NewVersion(version.Version))
-	// only keep major.minor version for comparison against cluster version
-	lv = &semver.Version{Major: lv.Major, Minor: lv.Minor}
-	if cv != nil && lv.LessThan(*cv) {
-		plog.Fatalf("cluster cannot be downgraded (current version: %s is lower than determined cluster version: %s).", version.Version, version.Cluster(cv.String()))
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/doc.go b/vendor/github.com/coreos/etcd/etcdserver/membership/doc.go
deleted file mode 100644
index b07fb2d..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/membership/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package membership describes individual etcd members and clusters of members.
-package membership
diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/errors.go b/vendor/github.com/coreos/etcd/etcdserver/membership/errors.go
deleted file mode 100644
index e4d36af..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/membership/errors.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package membership
-
-import (
-	"errors"
-
-	etcdErr "github.com/coreos/etcd/error"
-)
-
-var (
-	ErrIDRemoved     = errors.New("membership: ID removed")
-	ErrIDExists      = errors.New("membership: ID exists")
-	ErrIDNotFound    = errors.New("membership: ID not found")
-	ErrPeerURLexists = errors.New("membership: peerURL exists")
-)
-
-func isKeyNotFound(err error) bool {
-	e, ok := err.(*etcdErr.Error)
-	return ok && e.ErrorCode == etcdErr.EcodeKeyNotFound
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/member.go b/vendor/github.com/coreos/etcd/etcdserver/membership/member.go
deleted file mode 100644
index 6de74d2..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/membership/member.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package membership
-
-import (
-	"crypto/sha1"
-	"encoding/binary"
-	"fmt"
-	"math/rand"
-	"sort"
-	"time"
-
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/membership")
-)
-
-// RaftAttributes represents the raft related attributes of an etcd member.
-type RaftAttributes struct {
-	// PeerURLs is the list of peers in the raft cluster.
-	// TODO(philips): ensure these are URLs
-	PeerURLs []string `json:"peerURLs"`
-}
-
-// Attributes represents all the non-raft related attributes of an etcd member.
-type Attributes struct {
-	Name       string   `json:"name,omitempty"`
-	ClientURLs []string `json:"clientURLs,omitempty"`
-}
-
-type Member struct {
-	ID types.ID `json:"id"`
-	RaftAttributes
-	Attributes
-}
-
-// NewMember creates a Member without an ID and generates one based on the
-// cluster name, peer URLs, and time. This is used for bootstrapping/adding new member.
-func NewMember(name string, peerURLs types.URLs, clusterName string, now *time.Time) *Member {
-	m := &Member{
-		RaftAttributes: RaftAttributes{PeerURLs: peerURLs.StringSlice()},
-		Attributes:     Attributes{Name: name},
-	}
-
-	var b []byte
-	sort.Strings(m.PeerURLs)
-	for _, p := range m.PeerURLs {
-		b = append(b, []byte(p)...)
-	}
-
-	b = append(b, []byte(clusterName)...)
-	if now != nil {
-		b = append(b, []byte(fmt.Sprintf("%d", now.Unix()))...)
-	}
-
-	hash := sha1.Sum(b)
-	m.ID = types.ID(binary.BigEndian.Uint64(hash[:8]))
-	return m
-}
-
-// PickPeerURL chooses a random address from a given Member's PeerURLs.
-// It will panic if there is no PeerURLs available in Member.
-func (m *Member) PickPeerURL() string {
-	if len(m.PeerURLs) == 0 {
-		plog.Panicf("member should always have some peer url")
-	}
-	return m.PeerURLs[rand.Intn(len(m.PeerURLs))]
-}
-
-func (m *Member) Clone() *Member {
-	if m == nil {
-		return nil
-	}
-	mm := &Member{
-		ID: m.ID,
-		Attributes: Attributes{
-			Name: m.Name,
-		},
-	}
-	if m.PeerURLs != nil {
-		mm.PeerURLs = make([]string, len(m.PeerURLs))
-		copy(mm.PeerURLs, m.PeerURLs)
-	}
-	if m.ClientURLs != nil {
-		mm.ClientURLs = make([]string, len(m.ClientURLs))
-		copy(mm.ClientURLs, m.ClientURLs)
-	}
-	return mm
-}
-
-func (m *Member) IsStarted() bool {
-	return len(m.Name) != 0
-}
-
-// MembersByID implements sort by ID interface
-type MembersByID []*Member
-
-func (ms MembersByID) Len() int           { return len(ms) }
-func (ms MembersByID) Less(i, j int) bool { return ms[i].ID < ms[j].ID }
-func (ms MembersByID) Swap(i, j int)      { ms[i], ms[j] = ms[j], ms[i] }
-
-// MembersByPeerURLs implements sort by peer urls interface
-type MembersByPeerURLs []*Member
-
-func (ms MembersByPeerURLs) Len() int { return len(ms) }
-func (ms MembersByPeerURLs) Less(i, j int) bool {
-	return ms[i].PeerURLs[0] < ms[j].PeerURLs[0]
-}
-func (ms MembersByPeerURLs) Swap(i, j int) { ms[i], ms[j] = ms[j], ms[i] }
diff --git a/vendor/github.com/coreos/etcd/etcdserver/membership/store.go b/vendor/github.com/coreos/etcd/etcdserver/membership/store.go
deleted file mode 100644
index d3f8f24..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/membership/store.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package membership
-
-import (
-	"encoding/json"
-	"fmt"
-	"path"
-
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/store"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-const (
-	attributesSuffix     = "attributes"
-	raftAttributesSuffix = "raftAttributes"
-
-	// the prefix for stroing membership related information in store provided by store pkg.
-	storePrefix = "/0"
-)
-
-var (
-	membersBucketName        = []byte("members")
-	membersRemovedBucketName = []byte("members_removed")
-	clusterBucketName        = []byte("cluster")
-
-	StoreMembersPrefix        = path.Join(storePrefix, "members")
-	storeRemovedMembersPrefix = path.Join(storePrefix, "removed_members")
-)
-
-func mustSaveMemberToBackend(be backend.Backend, m *Member) {
-	mkey := backendMemberKey(m.ID)
-	mvalue, err := json.Marshal(m)
-	if err != nil {
-		plog.Panicf("marshal raftAttributes should never fail: %v", err)
-	}
-
-	tx := be.BatchTx()
-	tx.Lock()
-	tx.UnsafePut(membersBucketName, mkey, mvalue)
-	tx.Unlock()
-}
-
-func mustDeleteMemberFromBackend(be backend.Backend, id types.ID) {
-	mkey := backendMemberKey(id)
-
-	tx := be.BatchTx()
-	tx.Lock()
-	tx.UnsafeDelete(membersBucketName, mkey)
-	tx.UnsafePut(membersRemovedBucketName, mkey, []byte("removed"))
-	tx.Unlock()
-}
-
-func mustSaveClusterVersionToBackend(be backend.Backend, ver *semver.Version) {
-	ckey := backendClusterVersionKey()
-
-	tx := be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-	tx.UnsafePut(clusterBucketName, ckey, []byte(ver.String()))
-}
-
-func mustSaveMemberToStore(s store.Store, m *Member) {
-	b, err := json.Marshal(m.RaftAttributes)
-	if err != nil {
-		plog.Panicf("marshal raftAttributes should never fail: %v", err)
-	}
-	p := path.Join(MemberStoreKey(m.ID), raftAttributesSuffix)
-	if _, err := s.Create(p, false, string(b), false, store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil {
-		plog.Panicf("create raftAttributes should never fail: %v", err)
-	}
-}
-
-func mustDeleteMemberFromStore(s store.Store, id types.ID) {
-	if _, err := s.Delete(MemberStoreKey(id), true, true); err != nil {
-		plog.Panicf("delete member should never fail: %v", err)
-	}
-	if _, err := s.Create(RemovedMemberStoreKey(id), false, "", false, store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil {
-		plog.Panicf("create removedMember should never fail: %v", err)
-	}
-}
-
-func mustUpdateMemberInStore(s store.Store, m *Member) {
-	b, err := json.Marshal(m.RaftAttributes)
-	if err != nil {
-		plog.Panicf("marshal raftAttributes should never fail: %v", err)
-	}
-	p := path.Join(MemberStoreKey(m.ID), raftAttributesSuffix)
-	if _, err := s.Update(p, string(b), store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil {
-		plog.Panicf("update raftAttributes should never fail: %v", err)
-	}
-}
-
-func mustUpdateMemberAttrInStore(s store.Store, m *Member) {
-	b, err := json.Marshal(m.Attributes)
-	if err != nil {
-		plog.Panicf("marshal raftAttributes should never fail: %v", err)
-	}
-	p := path.Join(MemberStoreKey(m.ID), attributesSuffix)
-	if _, err := s.Set(p, false, string(b), store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil {
-		plog.Panicf("update raftAttributes should never fail: %v", err)
-	}
-}
-
-func mustSaveClusterVersionToStore(s store.Store, ver *semver.Version) {
-	if _, err := s.Set(StoreClusterVersionKey(), false, ver.String(), store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil {
-		plog.Panicf("save cluster version should never fail: %v", err)
-	}
-}
-
-// nodeToMember builds member from a key value node.
-// the child nodes of the given node MUST be sorted by key.
-func nodeToMember(n *store.NodeExtern) (*Member, error) {
-	m := &Member{ID: MustParseMemberIDFromKey(n.Key)}
-	attrs := make(map[string][]byte)
-	raftAttrKey := path.Join(n.Key, raftAttributesSuffix)
-	attrKey := path.Join(n.Key, attributesSuffix)
-	for _, nn := range n.Nodes {
-		if nn.Key != raftAttrKey && nn.Key != attrKey {
-			return nil, fmt.Errorf("unknown key %q", nn.Key)
-		}
-		attrs[nn.Key] = []byte(*nn.Value)
-	}
-	if data := attrs[raftAttrKey]; data != nil {
-		if err := json.Unmarshal(data, &m.RaftAttributes); err != nil {
-			return nil, fmt.Errorf("unmarshal raftAttributes error: %v", err)
-		}
-	} else {
-		return nil, fmt.Errorf("raftAttributes key doesn't exist")
-	}
-	if data := attrs[attrKey]; data != nil {
-		if err := json.Unmarshal(data, &m.Attributes); err != nil {
-			return m, fmt.Errorf("unmarshal attributes error: %v", err)
-		}
-	}
-	return m, nil
-}
-
-func backendMemberKey(id types.ID) []byte {
-	return []byte(id.String())
-}
-
-func backendClusterVersionKey() []byte {
-	return []byte("clusterVersion")
-}
-
-func mustCreateBackendBuckets(be backend.Backend) {
-	tx := be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-	tx.UnsafeCreateBucket(membersBucketName)
-	tx.UnsafeCreateBucket(membersRemovedBucketName)
-	tx.UnsafeCreateBucket(clusterBucketName)
-}
-
-func MemberStoreKey(id types.ID) string {
-	return path.Join(StoreMembersPrefix, id.String())
-}
-
-func StoreClusterVersionKey() string {
-	return path.Join(storePrefix, "version")
-}
-
-func MemberAttributesStorePath(id types.ID) string {
-	return path.Join(MemberStoreKey(id), attributesSuffix)
-}
-
-func MustParseMemberIDFromKey(key string) types.ID {
-	id, err := types.IDFromString(path.Base(key))
-	if err != nil {
-		plog.Panicf("unexpected parse member id error: %v", err)
-	}
-	return id
-}
-
-func RemovedMemberStoreKey(id types.ID) string {
-	return path.Join(storeRemovedMembersPrefix, id.String())
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/metrics.go b/vendor/github.com/coreos/etcd/etcdserver/metrics.go
deleted file mode 100644
index 10f8a47..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/metrics.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	goruntime "runtime"
-	"time"
-
-	"github.com/coreos/etcd/pkg/runtime"
-	"github.com/coreos/etcd/version"
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-var (
-	hasLeader = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "has_leader",
-		Help:      "Whether or not a leader exists. 1 is existence, 0 is not.",
-	})
-	isLeader = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "is_leader",
-		Help:      "Whether or not this member is a leader. 1 if is, 0 otherwise.",
-	})
-	leaderChanges = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "leader_changes_seen_total",
-		Help:      "The number of leader changes seen.",
-	})
-	heartbeatSendFailures = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "heartbeat_send_failures_total",
-		Help:      "The total number of leader heartbeat send failures (likely overloaded from slow disk).",
-	})
-	slowApplies = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "slow_apply_total",
-		Help:      "The total number of slow apply requests (likely overloaded from slow disk).",
-	})
-	proposalsCommitted = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "proposals_committed_total",
-		Help:      "The total number of consensus proposals committed.",
-	})
-	proposalsApplied = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "proposals_applied_total",
-		Help:      "The total number of consensus proposals applied.",
-	})
-	proposalsPending = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "proposals_pending",
-		Help:      "The current number of pending proposals to commit.",
-	})
-	proposalsFailed = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "proposals_failed_total",
-		Help:      "The total number of failed proposals seen.",
-	})
-	leaseExpired = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "server",
-		Name:      "lease_expired_total",
-		Help:      "The total number of expired leases.",
-	})
-	slowReadIndex = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "slow_read_indexes_total",
-		Help:      "The total number of pending read indexes not in sync with leader's or timed out read index requests.",
-	})
-	readIndexFailed = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "read_indexes_failed_total",
-		Help:      "The total number of failed read indexes seen.",
-	})
-	quotaBackendBytes = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "quota_backend_bytes",
-		Help:      "Current backend storage quota size in bytes.",
-	})
-	currentVersion = prometheus.NewGaugeVec(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "version",
-		Help:      "Which version is running. 1 for 'server_version' label with current version.",
-	},
-		[]string{"server_version"})
-	currentGoVersion = prometheus.NewGaugeVec(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "go_version",
-		Help:      "Which Go version server is running with. 1 for 'server_go_version' label with current version.",
-	},
-		[]string{"server_go_version"})
-	serverID = prometheus.NewGaugeVec(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "id",
-		Help:      "Server or member ID in hexadecimal format. 1 for 'server_id' label with current ID.",
-	},
-		[]string{"server_id"})
-)
-
-func init() {
-	prometheus.MustRegister(hasLeader)
-	prometheus.MustRegister(isLeader)
-	prometheus.MustRegister(leaderChanges)
-	prometheus.MustRegister(heartbeatSendFailures)
-	prometheus.MustRegister(slowApplies)
-	prometheus.MustRegister(proposalsCommitted)
-	prometheus.MustRegister(proposalsApplied)
-	prometheus.MustRegister(proposalsPending)
-	prometheus.MustRegister(proposalsFailed)
-	prometheus.MustRegister(leaseExpired)
-	prometheus.MustRegister(slowReadIndex)
-	prometheus.MustRegister(readIndexFailed)
-	prometheus.MustRegister(quotaBackendBytes)
-	prometheus.MustRegister(currentVersion)
-	prometheus.MustRegister(currentGoVersion)
-	prometheus.MustRegister(serverID)
-
-	currentVersion.With(prometheus.Labels{
-		"server_version": version.Version,
-	}).Set(1)
-	currentGoVersion.With(prometheus.Labels{
-		"server_go_version": goruntime.Version(),
-	}).Set(1)
-}
-
-func monitorFileDescriptor(done <-chan struct{}) {
-	ticker := time.NewTicker(5 * time.Second)
-	defer ticker.Stop()
-	for {
-		used, err := runtime.FDUsage()
-		if err != nil {
-			plog.Errorf("cannot monitor file descriptor usage (%v)", err)
-			return
-		}
-		limit, err := runtime.FDLimit()
-		if err != nil {
-			plog.Errorf("cannot monitor file descriptor usage (%v)", err)
-			return
-		}
-		if used >= limit/5*4 {
-			plog.Warningf("80%% of the file descriptor limit is used [used = %d, limit = %d]", used, limit)
-		}
-		select {
-		case <-ticker.C:
-		case <-done:
-			return
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/quota.go b/vendor/github.com/coreos/etcd/etcdserver/quota.go
deleted file mode 100644
index 882eb76..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/quota.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-const (
-	// DefaultQuotaBytes is the number of bytes the backend Size may
-	// consume before exceeding the space quota.
-	DefaultQuotaBytes = int64(2 * 1024 * 1024 * 1024) // 2GB
-	// MaxQuotaBytes is the maximum number of bytes suggested for a backend
-	// quota. A larger quota may lead to degraded performance.
-	MaxQuotaBytes = int64(8 * 1024 * 1024 * 1024) // 8GB
-)
-
-// Quota represents an arbitrary quota against arbitrary requests. Each request
-// costs some charge; if there is not enough remaining charge, then there are
-// too few resources available within the quota to apply the request.
-type Quota interface {
-	// Available judges whether the given request fits within the quota.
-	Available(req interface{}) bool
-	// Cost computes the charge against the quota for a given request.
-	Cost(req interface{}) int
-	// Remaining is the amount of charge left for the quota.
-	Remaining() int64
-}
-
-type passthroughQuota struct{}
-
-func (*passthroughQuota) Available(interface{}) bool { return true }
-func (*passthroughQuota) Cost(interface{}) int       { return 0 }
-func (*passthroughQuota) Remaining() int64           { return 1 }
-
-type backendQuota struct {
-	s               *EtcdServer
-	maxBackendBytes int64
-}
-
-const (
-	// leaseOverhead is an estimate for the cost of storing a lease
-	leaseOverhead = 64
-	// kvOverhead is an estimate for the cost of storing a key's metadata
-	kvOverhead = 256
-)
-
-func NewBackendQuota(s *EtcdServer) Quota {
-	quotaBackendBytes.Set(float64(s.Cfg.QuotaBackendBytes))
-
-	if s.Cfg.QuotaBackendBytes < 0 {
-		// disable quotas if negative
-		plog.Warningf("disabling backend quota")
-		return &passthroughQuota{}
-	}
-
-	if s.Cfg.QuotaBackendBytes == 0 {
-		// use default size if no quota size given
-		quotaBackendBytes.Set(float64(DefaultQuotaBytes))
-		return &backendQuota{s, DefaultQuotaBytes}
-	}
-
-	if s.Cfg.QuotaBackendBytes > MaxQuotaBytes {
-		plog.Warningf("backend quota %v exceeds maximum recommended quota %v", s.Cfg.QuotaBackendBytes, MaxQuotaBytes)
-	}
-	return &backendQuota{s, s.Cfg.QuotaBackendBytes}
-}
-
-func (b *backendQuota) Available(v interface{}) bool {
-	// TODO: maybe optimize backend.Size()
-	return b.s.Backend().Size()+int64(b.Cost(v)) < b.maxBackendBytes
-}
-
-func (b *backendQuota) Cost(v interface{}) int {
-	switch r := v.(type) {
-	case *pb.PutRequest:
-		return costPut(r)
-	case *pb.TxnRequest:
-		return costTxn(r)
-	case *pb.LeaseGrantRequest:
-		return leaseOverhead
-	default:
-		panic("unexpected cost")
-	}
-}
-
-func costPut(r *pb.PutRequest) int { return kvOverhead + len(r.Key) + len(r.Value) }
-
-func costTxnReq(u *pb.RequestOp) int {
-	r := u.GetRequestPut()
-	if r == nil {
-		return 0
-	}
-	return costPut(r)
-}
-
-func costTxn(r *pb.TxnRequest) int {
-	sizeSuccess := 0
-	for _, u := range r.Success {
-		sizeSuccess += costTxnReq(u)
-	}
-	sizeFailure := 0
-	for _, u := range r.Failure {
-		sizeFailure += costTxnReq(u)
-	}
-	if sizeFailure > sizeSuccess {
-		return sizeFailure
-	}
-	return sizeSuccess
-}
-
-func (b *backendQuota) Remaining() int64 {
-	return b.maxBackendBytes - b.s.Backend().Size()
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/raft.go b/vendor/github.com/coreos/etcd/etcdserver/raft.go
deleted file mode 100644
index 1080633..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/raft.go
+++ /dev/null
@@ -1,608 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"encoding/json"
-	"expvar"
-	"sort"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/pkg/contention"
-	"github.com/coreos/etcd/pkg/pbutil"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/rafthttp"
-	"github.com/coreos/etcd/wal"
-	"github.com/coreos/etcd/wal/walpb"
-	"github.com/coreos/pkg/capnslog"
-)
-
-const (
-	// Number of entries for slow follower to catch-up after compacting
-	// the raft storage entries.
-	// We expect the follower has a millisecond level latency with the leader.
-	// The max throughput is around 10K. Keep a 5K entries is enough for helping
-	// follower to catch up.
-	numberOfCatchUpEntries = 5000
-
-	// The max throughput of etcd will not exceed 100MB/s (100K * 1KB value).
-	// Assuming the RTT is around 10ms, 1MB max size is large enough.
-	maxSizePerMsg = 1 * 1024 * 1024
-	// Never overflow the rafthttp buffer, which is 4096.
-	// TODO: a better const?
-	maxInflightMsgs = 4096 / 8
-)
-
-var (
-	// protects raftStatus
-	raftStatusMu sync.Mutex
-	// indirection for expvar func interface
-	// expvar panics when publishing duplicate name
-	// expvar does not support remove a registered name
-	// so only register a func that calls raftStatus
-	// and change raftStatus as we need.
-	raftStatus func() raft.Status
-)
-
-func init() {
-	raft.SetLogger(capnslog.NewPackageLogger("github.com/coreos/etcd", "raft"))
-	expvar.Publish("raft.status", expvar.Func(func() interface{} {
-		raftStatusMu.Lock()
-		defer raftStatusMu.Unlock()
-		return raftStatus()
-	}))
-}
-
-type RaftTimer interface {
-	Index() uint64
-	Term() uint64
-}
-
-// apply contains entries, snapshot to be applied. Once
-// an apply is consumed, the entries will be persisted to
-// to raft storage concurrently; the application must read
-// raftDone before assuming the raft messages are stable.
-type apply struct {
-	entries  []raftpb.Entry
-	snapshot raftpb.Snapshot
-	// notifyc synchronizes etcd server applies with the raft node
-	notifyc chan struct{}
-}
-
-type raftNode struct {
-	// Cache of the latest raft index and raft term the server has seen.
-	// These three unit64 fields must be the first elements to keep 64-bit
-	// alignment for atomic access to the fields.
-	index uint64
-	term  uint64
-	lead  uint64
-
-	tickMu *sync.Mutex
-	raftNodeConfig
-
-	// a chan to send/receive snapshot
-	msgSnapC chan raftpb.Message
-
-	// a chan to send out apply
-	applyc chan apply
-
-	// a chan to send out readState
-	readStateC chan raft.ReadState
-
-	// utility
-	ticker *time.Ticker
-	// contention detectors for raft heartbeat message
-	td *contention.TimeoutDetector
-
-	stopped chan struct{}
-	done    chan struct{}
-}
-
-type raftNodeConfig struct {
-	// to check if msg receiver is removed from cluster
-	isIDRemoved func(id uint64) bool
-	raft.Node
-	raftStorage *raft.MemoryStorage
-	storage     Storage
-	heartbeat   time.Duration // for logging
-	// transport specifies the transport to send and receive msgs to members.
-	// Sending messages MUST NOT block. It is okay to drop messages, since
-	// clients should timeout and reissue their messages.
-	// If transport is nil, server will panic.
-	transport rafthttp.Transporter
-}
-
-func newRaftNode(cfg raftNodeConfig) *raftNode {
-	r := &raftNode{
-		tickMu:         new(sync.Mutex),
-		raftNodeConfig: cfg,
-		// set up contention detectors for raft heartbeat message.
-		// expect to send a heartbeat within 2 heartbeat intervals.
-		td:         contention.NewTimeoutDetector(2 * cfg.heartbeat),
-		readStateC: make(chan raft.ReadState, 1),
-		msgSnapC:   make(chan raftpb.Message, maxInFlightMsgSnap),
-		applyc:     make(chan apply),
-		stopped:    make(chan struct{}),
-		done:       make(chan struct{}),
-	}
-	if r.heartbeat == 0 {
-		r.ticker = &time.Ticker{}
-	} else {
-		r.ticker = time.NewTicker(r.heartbeat)
-	}
-	return r
-}
-
-// raft.Node does not have locks in Raft package
-func (r *raftNode) tick() {
-	r.tickMu.Lock()
-	r.Tick()
-	r.tickMu.Unlock()
-}
-
-// start prepares and starts raftNode in a new goroutine. It is no longer safe
-// to modify the fields after it has been started.
-func (r *raftNode) start(rh *raftReadyHandler) {
-	internalTimeout := time.Second
-
-	go func() {
-		defer r.onStop()
-		islead := false
-
-		for {
-			select {
-			case <-r.ticker.C:
-				r.tick()
-			case rd := <-r.Ready():
-				if rd.SoftState != nil {
-					newLeader := rd.SoftState.Lead != raft.None && atomic.LoadUint64(&r.lead) != rd.SoftState.Lead
-					if newLeader {
-						leaderChanges.Inc()
-					}
-
-					if rd.SoftState.Lead == raft.None {
-						hasLeader.Set(0)
-					} else {
-						hasLeader.Set(1)
-					}
-
-					atomic.StoreUint64(&r.lead, rd.SoftState.Lead)
-					islead = rd.RaftState == raft.StateLeader
-					if islead {
-						isLeader.Set(1)
-					} else {
-						isLeader.Set(0)
-					}
-					rh.updateLeadership(newLeader)
-					r.td.Reset()
-				}
-
-				if len(rd.ReadStates) != 0 {
-					select {
-					case r.readStateC <- rd.ReadStates[len(rd.ReadStates)-1]:
-					case <-time.After(internalTimeout):
-						plog.Warningf("timed out sending read state")
-					case <-r.stopped:
-						return
-					}
-				}
-
-				notifyc := make(chan struct{}, 1)
-				ap := apply{
-					entries:  rd.CommittedEntries,
-					snapshot: rd.Snapshot,
-					notifyc:  notifyc,
-				}
-
-				updateCommittedIndex(&ap, rh)
-
-				select {
-				case r.applyc <- ap:
-				case <-r.stopped:
-					return
-				}
-
-				// the leader can write to its disk in parallel with replicating to the followers and them
-				// writing to their disks.
-				// For more details, check raft thesis 10.2.1
-				if islead {
-					// gofail: var raftBeforeLeaderSend struct{}
-					r.transport.Send(r.processMessages(rd.Messages))
-				}
-
-				// gofail: var raftBeforeSave struct{}
-				if err := r.storage.Save(rd.HardState, rd.Entries); err != nil {
-					plog.Fatalf("raft save state and entries error: %v", err)
-				}
-				if !raft.IsEmptyHardState(rd.HardState) {
-					proposalsCommitted.Set(float64(rd.HardState.Commit))
-				}
-				// gofail: var raftAfterSave struct{}
-
-				if !raft.IsEmptySnap(rd.Snapshot) {
-					// gofail: var raftBeforeSaveSnap struct{}
-					if err := r.storage.SaveSnap(rd.Snapshot); err != nil {
-						plog.Fatalf("raft save snapshot error: %v", err)
-					}
-					// etcdserver now claim the snapshot has been persisted onto the disk
-					notifyc <- struct{}{}
-
-					// gofail: var raftAfterSaveSnap struct{}
-					r.raftStorage.ApplySnapshot(rd.Snapshot)
-					plog.Infof("raft applied incoming snapshot at index %d", rd.Snapshot.Metadata.Index)
-					// gofail: var raftAfterApplySnap struct{}
-				}
-
-				r.raftStorage.Append(rd.Entries)
-
-				if !islead {
-					// finish processing incoming messages before we signal raftdone chan
-					msgs := r.processMessages(rd.Messages)
-
-					// now unblocks 'applyAll' that waits on Raft log disk writes before triggering snapshots
-					notifyc <- struct{}{}
-
-					// Candidate or follower needs to wait for all pending configuration
-					// changes to be applied before sending messages.
-					// Otherwise we might incorrectly count votes (e.g. votes from removed members).
-					// Also slow machine's follower raft-layer could proceed to become the leader
-					// on its own single-node cluster, before apply-layer applies the config change.
-					// We simply wait for ALL pending entries to be applied for now.
-					// We might improve this later on if it causes unnecessary long blocking issues.
-					waitApply := false
-					for _, ent := range rd.CommittedEntries {
-						if ent.Type == raftpb.EntryConfChange {
-							waitApply = true
-							break
-						}
-					}
-					if waitApply {
-						// blocks until 'applyAll' calls 'applyWait.Trigger'
-						// to be in sync with scheduled config-change job
-						// (assume notifyc has cap of 1)
-						select {
-						case notifyc <- struct{}{}:
-						case <-r.stopped:
-							return
-						}
-					}
-
-					// gofail: var raftBeforeFollowerSend struct{}
-					r.transport.Send(msgs)
-				} else {
-					// leader already processed 'MsgSnap' and signaled
-					notifyc <- struct{}{}
-				}
-
-				r.Advance()
-			case <-r.stopped:
-				return
-			}
-		}
-	}()
-}
-
-func updateCommittedIndex(ap *apply, rh *raftReadyHandler) {
-	var ci uint64
-	if len(ap.entries) != 0 {
-		ci = ap.entries[len(ap.entries)-1].Index
-	}
-	if ap.snapshot.Metadata.Index > ci {
-		ci = ap.snapshot.Metadata.Index
-	}
-	if ci != 0 {
-		rh.updateCommittedIndex(ci)
-	}
-}
-
-func (r *raftNode) processMessages(ms []raftpb.Message) []raftpb.Message {
-	sentAppResp := false
-	for i := len(ms) - 1; i >= 0; i-- {
-		if r.isIDRemoved(ms[i].To) {
-			ms[i].To = 0
-		}
-
-		if ms[i].Type == raftpb.MsgAppResp {
-			if sentAppResp {
-				ms[i].To = 0
-			} else {
-				sentAppResp = true
-			}
-		}
-
-		if ms[i].Type == raftpb.MsgSnap {
-			// There are two separate data store: the store for v2, and the KV for v3.
-			// The msgSnap only contains the most recent snapshot of store without KV.
-			// So we need to redirect the msgSnap to etcd server main loop for merging in the
-			// current store snapshot and KV snapshot.
-			select {
-			case r.msgSnapC <- ms[i]:
-			default:
-				// drop msgSnap if the inflight chan if full.
-			}
-			ms[i].To = 0
-		}
-		if ms[i].Type == raftpb.MsgHeartbeat {
-			ok, exceed := r.td.Observe(ms[i].To)
-			if !ok {
-				// TODO: limit request rate.
-				plog.Warningf("failed to send out heartbeat on time (exceeded the %v timeout for %v)", r.heartbeat, exceed)
-				plog.Warningf("server is likely overloaded")
-				heartbeatSendFailures.Inc()
-			}
-		}
-	}
-	return ms
-}
-
-func (r *raftNode) apply() chan apply {
-	return r.applyc
-}
-
-func (r *raftNode) stop() {
-	r.stopped <- struct{}{}
-	<-r.done
-}
-
-func (r *raftNode) onStop() {
-	r.Stop()
-	r.ticker.Stop()
-	r.transport.Stop()
-	if err := r.storage.Close(); err != nil {
-		plog.Panicf("raft close storage error: %v", err)
-	}
-	close(r.done)
-}
-
-// for testing
-func (r *raftNode) pauseSending() {
-	p := r.transport.(rafthttp.Pausable)
-	p.Pause()
-}
-
-func (r *raftNode) resumeSending() {
-	p := r.transport.(rafthttp.Pausable)
-	p.Resume()
-}
-
-// advanceTicks advances ticks of Raft node.
-// This can be used for fast-forwarding election
-// ticks in multi data-center deployments, thus
-// speeding up election process.
-func (r *raftNode) advanceTicks(ticks int) {
-	for i := 0; i < ticks; i++ {
-		r.tick()
-	}
-}
-
-func startNode(cfg ServerConfig, cl *membership.RaftCluster, ids []types.ID) (id types.ID, n raft.Node, s *raft.MemoryStorage, w *wal.WAL) {
-	var err error
-	member := cl.MemberByName(cfg.Name)
-	metadata := pbutil.MustMarshal(
-		&pb.Metadata{
-			NodeID:    uint64(member.ID),
-			ClusterID: uint64(cl.ID()),
-		},
-	)
-	if w, err = wal.Create(cfg.WALDir(), metadata); err != nil {
-		plog.Fatalf("create wal error: %v", err)
-	}
-	peers := make([]raft.Peer, len(ids))
-	for i, id := range ids {
-		ctx, err := json.Marshal((*cl).Member(id))
-		if err != nil {
-			plog.Panicf("marshal member should never fail: %v", err)
-		}
-		peers[i] = raft.Peer{ID: uint64(id), Context: ctx}
-	}
-	id = member.ID
-	plog.Infof("starting member %s in cluster %s", id, cl.ID())
-	s = raft.NewMemoryStorage()
-	c := &raft.Config{
-		ID:              uint64(id),
-		ElectionTick:    cfg.ElectionTicks,
-		HeartbeatTick:   1,
-		Storage:         s,
-		MaxSizePerMsg:   maxSizePerMsg,
-		MaxInflightMsgs: maxInflightMsgs,
-		CheckQuorum:     true,
-	}
-
-	n = raft.StartNode(c, peers)
-	raftStatusMu.Lock()
-	raftStatus = n.Status
-	raftStatusMu.Unlock()
-	return id, n, s, w
-}
-
-func restartNode(cfg ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *membership.RaftCluster, raft.Node, *raft.MemoryStorage, *wal.WAL) {
-	var walsnap walpb.Snapshot
-	if snapshot != nil {
-		walsnap.Index, walsnap.Term = snapshot.Metadata.Index, snapshot.Metadata.Term
-	}
-	w, id, cid, st, ents := readWAL(cfg.WALDir(), walsnap)
-
-	plog.Infof("restarting member %s in cluster %s at commit index %d", id, cid, st.Commit)
-	cl := membership.NewCluster("")
-	cl.SetID(cid)
-	s := raft.NewMemoryStorage()
-	if snapshot != nil {
-		s.ApplySnapshot(*snapshot)
-	}
-	s.SetHardState(st)
-	s.Append(ents)
-	c := &raft.Config{
-		ID:              uint64(id),
-		ElectionTick:    cfg.ElectionTicks,
-		HeartbeatTick:   1,
-		Storage:         s,
-		MaxSizePerMsg:   maxSizePerMsg,
-		MaxInflightMsgs: maxInflightMsgs,
-		CheckQuorum:     true,
-	}
-
-	n := raft.RestartNode(c)
-	raftStatusMu.Lock()
-	raftStatus = n.Status
-	raftStatusMu.Unlock()
-	return id, cl, n, s, w
-}
-
-func restartAsStandaloneNode(cfg ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *membership.RaftCluster, raft.Node, *raft.MemoryStorage, *wal.WAL) {
-	var walsnap walpb.Snapshot
-	if snapshot != nil {
-		walsnap.Index, walsnap.Term = snapshot.Metadata.Index, snapshot.Metadata.Term
-	}
-	w, id, cid, st, ents := readWAL(cfg.WALDir(), walsnap)
-
-	// discard the previously uncommitted entries
-	for i, ent := range ents {
-		if ent.Index > st.Commit {
-			plog.Infof("discarding %d uncommitted WAL entries ", len(ents)-i)
-			ents = ents[:i]
-			break
-		}
-	}
-
-	// force append the configuration change entries
-	toAppEnts := createConfigChangeEnts(getIDs(snapshot, ents), uint64(id), st.Term, st.Commit)
-	ents = append(ents, toAppEnts...)
-
-	// force commit newly appended entries
-	err := w.Save(raftpb.HardState{}, toAppEnts)
-	if err != nil {
-		plog.Fatalf("%v", err)
-	}
-	if len(ents) != 0 {
-		st.Commit = ents[len(ents)-1].Index
-	}
-
-	plog.Printf("forcing restart of member %s in cluster %s at commit index %d", id, cid, st.Commit)
-	cl := membership.NewCluster("")
-	cl.SetID(cid)
-	s := raft.NewMemoryStorage()
-	if snapshot != nil {
-		s.ApplySnapshot(*snapshot)
-	}
-	s.SetHardState(st)
-	s.Append(ents)
-	c := &raft.Config{
-		ID:              uint64(id),
-		ElectionTick:    cfg.ElectionTicks,
-		HeartbeatTick:   1,
-		Storage:         s,
-		MaxSizePerMsg:   maxSizePerMsg,
-		MaxInflightMsgs: maxInflightMsgs,
-		CheckQuorum:     true,
-	}
-	n := raft.RestartNode(c)
-	raftStatus = n.Status
-	return id, cl, n, s, w
-}
-
-// getIDs returns an ordered set of IDs included in the given snapshot and
-// the entries. The given snapshot/entries can contain two kinds of
-// ID-related entry:
-// - ConfChangeAddNode, in which case the contained ID will be added into the set.
-// - ConfChangeRemoveNode, in which case the contained ID will be removed from the set.
-func getIDs(snap *raftpb.Snapshot, ents []raftpb.Entry) []uint64 {
-	ids := make(map[uint64]bool)
-	if snap != nil {
-		for _, id := range snap.Metadata.ConfState.Nodes {
-			ids[id] = true
-		}
-	}
-	for _, e := range ents {
-		if e.Type != raftpb.EntryConfChange {
-			continue
-		}
-		var cc raftpb.ConfChange
-		pbutil.MustUnmarshal(&cc, e.Data)
-		switch cc.Type {
-		case raftpb.ConfChangeAddNode:
-			ids[cc.NodeID] = true
-		case raftpb.ConfChangeRemoveNode:
-			delete(ids, cc.NodeID)
-		case raftpb.ConfChangeUpdateNode:
-			// do nothing
-		default:
-			plog.Panicf("ConfChange Type should be either ConfChangeAddNode or ConfChangeRemoveNode!")
-		}
-	}
-	sids := make(types.Uint64Slice, 0, len(ids))
-	for id := range ids {
-		sids = append(sids, id)
-	}
-	sort.Sort(sids)
-	return []uint64(sids)
-}
-
-// createConfigChangeEnts creates a series of Raft entries (i.e.
-// EntryConfChange) to remove the set of given IDs from the cluster. The ID
-// `self` is _not_ removed, even if present in the set.
-// If `self` is not inside the given ids, it creates a Raft entry to add a
-// default member with the given `self`.
-func createConfigChangeEnts(ids []uint64, self uint64, term, index uint64) []raftpb.Entry {
-	ents := make([]raftpb.Entry, 0)
-	next := index + 1
-	found := false
-	for _, id := range ids {
-		if id == self {
-			found = true
-			continue
-		}
-		cc := &raftpb.ConfChange{
-			Type:   raftpb.ConfChangeRemoveNode,
-			NodeID: id,
-		}
-		e := raftpb.Entry{
-			Type:  raftpb.EntryConfChange,
-			Data:  pbutil.MustMarshal(cc),
-			Term:  term,
-			Index: next,
-		}
-		ents = append(ents, e)
-		next++
-	}
-	if !found {
-		m := membership.Member{
-			ID:             types.ID(self),
-			RaftAttributes: membership.RaftAttributes{PeerURLs: []string{"http://localhost:2380"}},
-		}
-		ctx, err := json.Marshal(m)
-		if err != nil {
-			plog.Panicf("marshal member should never fail: %v", err)
-		}
-		cc := &raftpb.ConfChange{
-			Type:    raftpb.ConfChangeAddNode,
-			NodeID:  self,
-			Context: ctx,
-		}
-		e := raftpb.Entry{
-			Type:  raftpb.EntryConfChange,
-			Data:  pbutil.MustMarshal(cc),
-			Term:  term,
-			Index: next,
-		}
-		ents = append(ents, e)
-	}
-	return ents
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/server.go b/vendor/github.com/coreos/etcd/etcdserver/server.go
deleted file mode 100644
index 71e2bcf..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/server.go
+++ /dev/null
@@ -1,1745 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"context"
-	"encoding/json"
-	"expvar"
-	"fmt"
-	"math"
-	"math/rand"
-	"net/http"
-	"os"
-	"path"
-	"regexp"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	"github.com/coreos/etcd/alarm"
-	"github.com/coreos/etcd/auth"
-	"github.com/coreos/etcd/compactor"
-	"github.com/coreos/etcd/discovery"
-	"github.com/coreos/etcd/etcdserver/api"
-	"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/etcdserver/stats"
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/lease/leasehttp"
-	"github.com/coreos/etcd/mvcc"
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/pkg/fileutil"
-	"github.com/coreos/etcd/pkg/idutil"
-	"github.com/coreos/etcd/pkg/pbutil"
-	"github.com/coreos/etcd/pkg/runtime"
-	"github.com/coreos/etcd/pkg/schedule"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/pkg/wait"
-	"github.com/coreos/etcd/raft"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/rafthttp"
-	"github.com/coreos/etcd/snap"
-	"github.com/coreos/etcd/store"
-	"github.com/coreos/etcd/version"
-	"github.com/coreos/etcd/wal"
-
-	"github.com/coreos/go-semver/semver"
-	"github.com/coreos/pkg/capnslog"
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-const (
-	DefaultSnapCount = 100000
-
-	StoreClusterPrefix = "/0"
-	StoreKeysPrefix    = "/1"
-
-	// HealthInterval is the minimum time the cluster should be healthy
-	// before accepting add member requests.
-	HealthInterval = 5 * time.Second
-
-	purgeFileInterval = 30 * time.Second
-	// monitorVersionInterval should be smaller than the timeout
-	// on the connection. Or we will not be able to reuse the connection
-	// (since it will timeout).
-	monitorVersionInterval = rafthttp.ConnWriteTimeout - time.Second
-
-	// max number of in-flight snapshot messages etcdserver allows to have
-	// This number is more than enough for most clusters with 5 machines.
-	maxInFlightMsgSnap = 16
-
-	releaseDelayAfterSnapshot = 30 * time.Second
-
-	// maxPendingRevokes is the maximum number of outstanding expired lease revocations.
-	maxPendingRevokes = 16
-
-	recommendedMaxRequestBytes = 10 * 1024 * 1024
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver")
-
-	storeMemberAttributeRegexp = regexp.MustCompile(path.Join(membership.StoreMembersPrefix, "[[:xdigit:]]{1,16}", "attributes"))
-)
-
-func init() {
-	rand.Seed(time.Now().UnixNano())
-
-	expvar.Publish(
-		"file_descriptor_limit",
-		expvar.Func(
-			func() interface{} {
-				n, _ := runtime.FDLimit()
-				return n
-			},
-		),
-	)
-}
-
-type Response struct {
-	Term    uint64
-	Index   uint64
-	Event   *store.Event
-	Watcher store.Watcher
-	Err     error
-}
-
-type ServerV2 interface {
-	Server
-	// Do takes a V2 request and attempts to fulfill it, returning a Response.
-	Do(ctx context.Context, r pb.Request) (Response, error)
-	stats.Stats
-	ClientCertAuthEnabled() bool
-}
-
-type ServerV3 interface {
-	Server
-	ID() types.ID
-	RaftTimer
-}
-
-func (s *EtcdServer) ClientCertAuthEnabled() bool { return s.Cfg.ClientCertAuthEnabled }
-
-type Server interface {
-	// Leader returns the ID of the leader Server.
-	Leader() types.ID
-
-	// AddMember attempts to add a member into the cluster. It will return
-	// ErrIDRemoved if member ID is removed from the cluster, or return
-	// ErrIDExists if member ID exists in the cluster.
-	AddMember(ctx context.Context, memb membership.Member) ([]*membership.Member, error)
-	// RemoveMember attempts to remove a member from the cluster. It will
-	// return ErrIDRemoved if member ID is removed from the cluster, or return
-	// ErrIDNotFound if member ID is not in the cluster.
-	RemoveMember(ctx context.Context, id uint64) ([]*membership.Member, error)
-	// UpdateMember attempts to update an existing member in the cluster. It will
-	// return ErrIDNotFound if the member ID does not exist.
-	UpdateMember(ctx context.Context, updateMemb membership.Member) ([]*membership.Member, error)
-
-	// ClusterVersion is the cluster-wide minimum major.minor version.
-	// Cluster version is set to the min version that an etcd member is
-	// compatible with when first bootstrap.
-	//
-	// ClusterVersion is nil until the cluster is bootstrapped (has a quorum).
-	//
-	// During a rolling upgrades, the ClusterVersion will be updated
-	// automatically after a sync. (5 second by default)
-	//
-	// The API/raft component can utilize ClusterVersion to determine if
-	// it can accept a client request or a raft RPC.
-	// NOTE: ClusterVersion might be nil when etcd 2.1 works with etcd 2.0 and
-	// the leader is etcd 2.0. etcd 2.0 leader will not update clusterVersion since
-	// this feature is introduced post 2.0.
-	ClusterVersion() *semver.Version
-	Cluster() api.Cluster
-	Alarms() []*pb.AlarmMember
-}
-
-// EtcdServer is the production implementation of the Server interface
-type EtcdServer struct {
-	// inflightSnapshots holds count the number of snapshots currently inflight.
-	inflightSnapshots int64  // must use atomic operations to access; keep 64-bit aligned.
-	appliedIndex      uint64 // must use atomic operations to access; keep 64-bit aligned.
-	committedIndex    uint64 // must use atomic operations to access; keep 64-bit aligned.
-	// consistIndex used to hold the offset of current executing entry
-	// It is initialized to 0 before executing any entry.
-	consistIndex consistentIndex // must use atomic operations to access; keep 64-bit aligned.
-	r            raftNode        // uses 64-bit atomics; keep 64-bit aligned.
-
-	readych chan struct{}
-	Cfg     ServerConfig
-
-	w wait.Wait
-
-	readMu sync.RWMutex
-	// read routine notifies etcd server that it waits for reading by sending an empty struct to
-	// readwaitC
-	readwaitc chan struct{}
-	// readNotifier is used to notify the read routine that it can process the request
-	// when there is no error
-	readNotifier *notifier
-
-	// stop signals the run goroutine should shutdown.
-	stop chan struct{}
-	// stopping is closed by run goroutine on shutdown.
-	stopping chan struct{}
-	// done is closed when all goroutines from start() complete.
-	done chan struct{}
-
-	errorc     chan error
-	id         types.ID
-	attributes membership.Attributes
-
-	cluster *membership.RaftCluster
-
-	store       store.Store
-	snapshotter *snap.Snapshotter
-
-	applyV2 ApplierV2
-
-	// applyV3 is the applier with auth and quotas
-	applyV3 applierV3
-	// applyV3Base is the core applier without auth or quotas
-	applyV3Base applierV3
-	applyWait   wait.WaitTime
-
-	kv         mvcc.ConsistentWatchableKV
-	lessor     lease.Lessor
-	bemu       sync.Mutex
-	be         backend.Backend
-	authStore  auth.AuthStore
-	alarmStore *alarm.AlarmStore
-
-	stats  *stats.ServerStats
-	lstats *stats.LeaderStats
-
-	SyncTicker *time.Ticker
-	// compactor is used to auto-compact the KV.
-	compactor compactor.Compactor
-
-	// peerRt used to send requests (version, lease) to peers.
-	peerRt   http.RoundTripper
-	reqIDGen *idutil.Generator
-
-	// forceVersionC is used to force the version monitor loop
-	// to detect the cluster version immediately.
-	forceVersionC chan struct{}
-
-	// wgMu blocks concurrent waitgroup mutation while server stopping
-	wgMu sync.RWMutex
-	// wg is used to wait for the go routines that depends on the server state
-	// to exit when stopping the server.
-	wg sync.WaitGroup
-
-	// ctx is used for etcd-initiated requests that may need to be canceled
-	// on etcd server shutdown.
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	leadTimeMu      sync.RWMutex
-	leadElectedTime time.Time
-}
-
-// NewServer creates a new EtcdServer from the supplied configuration. The
-// configuration is considered static for the lifetime of the EtcdServer.
-func NewServer(cfg ServerConfig) (srv *EtcdServer, err error) {
-	st := store.New(StoreClusterPrefix, StoreKeysPrefix)
-
-	var (
-		w  *wal.WAL
-		n  raft.Node
-		s  *raft.MemoryStorage
-		id types.ID
-		cl *membership.RaftCluster
-	)
-
-	if cfg.MaxRequestBytes > recommendedMaxRequestBytes {
-		plog.Warningf("MaxRequestBytes %v exceeds maximum recommended size %v", cfg.MaxRequestBytes, recommendedMaxRequestBytes)
-	}
-
-	if terr := fileutil.TouchDirAll(cfg.DataDir); terr != nil {
-		return nil, fmt.Errorf("cannot access data directory: %v", terr)
-	}
-
-	haveWAL := wal.Exist(cfg.WALDir())
-
-	if err = fileutil.TouchDirAll(cfg.SnapDir()); err != nil {
-		plog.Fatalf("create snapshot directory error: %v", err)
-	}
-	ss := snap.New(cfg.SnapDir())
-
-	bepath := cfg.backendPath()
-	beExist := fileutil.Exist(bepath)
-	be := openBackend(cfg)
-
-	defer func() {
-		if err != nil {
-			be.Close()
-		}
-	}()
-
-	prt, err := rafthttp.NewRoundTripper(cfg.PeerTLSInfo, cfg.peerDialTimeout())
-	if err != nil {
-		return nil, err
-	}
-	var (
-		remotes  []*membership.Member
-		snapshot *raftpb.Snapshot
-	)
-
-	switch {
-	case !haveWAL && !cfg.NewCluster:
-		if err = cfg.VerifyJoinExisting(); err != nil {
-			return nil, err
-		}
-		cl, err = membership.NewClusterFromURLsMap(cfg.InitialClusterToken, cfg.InitialPeerURLsMap)
-		if err != nil {
-			return nil, err
-		}
-		existingCluster, gerr := GetClusterFromRemotePeers(getRemotePeerURLs(cl, cfg.Name), prt)
-		if gerr != nil {
-			return nil, fmt.Errorf("cannot fetch cluster info from peer urls: %v", gerr)
-		}
-		if err = membership.ValidateClusterAndAssignIDs(cl, existingCluster); err != nil {
-			return nil, fmt.Errorf("error validating peerURLs %s: %v", existingCluster, err)
-		}
-		if !isCompatibleWithCluster(cl, cl.MemberByName(cfg.Name).ID, prt) {
-			return nil, fmt.Errorf("incompatible with current running cluster")
-		}
-
-		remotes = existingCluster.Members()
-		cl.SetID(existingCluster.ID())
-		cl.SetStore(st)
-		cl.SetBackend(be)
-		cfg.Print()
-		id, n, s, w = startNode(cfg, cl, nil)
-	case !haveWAL && cfg.NewCluster:
-		if err = cfg.VerifyBootstrap(); err != nil {
-			return nil, err
-		}
-		cl, err = membership.NewClusterFromURLsMap(cfg.InitialClusterToken, cfg.InitialPeerURLsMap)
-		if err != nil {
-			return nil, err
-		}
-		m := cl.MemberByName(cfg.Name)
-		if isMemberBootstrapped(cl, cfg.Name, prt, cfg.bootstrapTimeout()) {
-			return nil, fmt.Errorf("member %s has already been bootstrapped", m.ID)
-		}
-		if cfg.ShouldDiscover() {
-			var str string
-			str, err = discovery.JoinCluster(cfg.DiscoveryURL, cfg.DiscoveryProxy, m.ID, cfg.InitialPeerURLsMap.String())
-			if err != nil {
-				return nil, &DiscoveryError{Op: "join", Err: err}
-			}
-			var urlsmap types.URLsMap
-			urlsmap, err = types.NewURLsMap(str)
-			if err != nil {
-				return nil, err
-			}
-			if checkDuplicateURL(urlsmap) {
-				return nil, fmt.Errorf("discovery cluster %s has duplicate url", urlsmap)
-			}
-			if cl, err = membership.NewClusterFromURLsMap(cfg.InitialClusterToken, urlsmap); err != nil {
-				return nil, err
-			}
-		}
-		cl.SetStore(st)
-		cl.SetBackend(be)
-		cfg.PrintWithInitial()
-		id, n, s, w = startNode(cfg, cl, cl.MemberIDs())
-	case haveWAL:
-		if err = fileutil.IsDirWriteable(cfg.MemberDir()); err != nil {
-			return nil, fmt.Errorf("cannot write to member directory: %v", err)
-		}
-
-		if err = fileutil.IsDirWriteable(cfg.WALDir()); err != nil {
-			return nil, fmt.Errorf("cannot write to WAL directory: %v", err)
-		}
-
-		if cfg.ShouldDiscover() {
-			plog.Warningf("discovery token ignored since a cluster has already been initialized. Valid log found at %q", cfg.WALDir())
-		}
-		snapshot, err = ss.Load()
-		if err != nil && err != snap.ErrNoSnapshot {
-			return nil, err
-		}
-		if snapshot != nil {
-			if err = st.Recovery(snapshot.Data); err != nil {
-				plog.Panicf("recovered store from snapshot error: %v", err)
-			}
-			plog.Infof("recovered store from snapshot at index %d", snapshot.Metadata.Index)
-			if be, err = recoverSnapshotBackend(cfg, be, *snapshot); err != nil {
-				plog.Panicf("recovering backend from snapshot error: %v", err)
-			}
-		}
-		cfg.Print()
-		if !cfg.ForceNewCluster {
-			id, cl, n, s, w = restartNode(cfg, snapshot)
-		} else {
-			id, cl, n, s, w = restartAsStandaloneNode(cfg, snapshot)
-		}
-		cl.SetStore(st)
-		cl.SetBackend(be)
-		cl.Recover(api.UpdateCapability)
-		if cl.Version() != nil && !cl.Version().LessThan(semver.Version{Major: 3}) && !beExist {
-			os.RemoveAll(bepath)
-			return nil, fmt.Errorf("database file (%v) of the backend is missing", bepath)
-		}
-	default:
-		return nil, fmt.Errorf("unsupported bootstrap config")
-	}
-
-	if terr := fileutil.TouchDirAll(cfg.MemberDir()); terr != nil {
-		return nil, fmt.Errorf("cannot access member directory: %v", terr)
-	}
-
-	sstats := stats.NewServerStats(cfg.Name, id.String())
-	lstats := stats.NewLeaderStats(id.String())
-
-	heartbeat := time.Duration(cfg.TickMs) * time.Millisecond
-	srv = &EtcdServer{
-		readych:     make(chan struct{}),
-		Cfg:         cfg,
-		errorc:      make(chan error, 1),
-		store:       st,
-		snapshotter: ss,
-		r: *newRaftNode(
-			raftNodeConfig{
-				isIDRemoved: func(id uint64) bool { return cl.IsIDRemoved(types.ID(id)) },
-				Node:        n,
-				heartbeat:   heartbeat,
-				raftStorage: s,
-				storage:     NewStorage(w, ss),
-			},
-		),
-		id:            id,
-		attributes:    membership.Attributes{Name: cfg.Name, ClientURLs: cfg.ClientURLs.StringSlice()},
-		cluster:       cl,
-		stats:         sstats,
-		lstats:        lstats,
-		SyncTicker:    time.NewTicker(500 * time.Millisecond),
-		peerRt:        prt,
-		reqIDGen:      idutil.NewGenerator(uint16(id), time.Now()),
-		forceVersionC: make(chan struct{}),
-	}
-	serverID.With(prometheus.Labels{"server_id": id.String()}).Set(1)
-
-	srv.applyV2 = &applierV2store{store: srv.store, cluster: srv.cluster}
-
-	srv.be = be
-	minTTL := time.Duration((3*cfg.ElectionTicks)/2) * heartbeat
-
-	// always recover lessor before kv. When we recover the mvcc.KV it will reattach keys to its leases.
-	// If we recover mvcc.KV first, it will attach the keys to the wrong lessor before it recovers.
-	srv.lessor = lease.NewLessor(srv.be, int64(math.Ceil(minTTL.Seconds())))
-	srv.kv = mvcc.New(srv.be, srv.lessor, &srv.consistIndex)
-	if beExist {
-		kvindex := srv.kv.ConsistentIndex()
-		// TODO: remove kvindex != 0 checking when we do not expect users to upgrade
-		// etcd from pre-3.0 release.
-		if snapshot != nil && kvindex < snapshot.Metadata.Index {
-			if kvindex != 0 {
-				return nil, fmt.Errorf("database file (%v index %d) does not match with snapshot (index %d).", bepath, kvindex, snapshot.Metadata.Index)
-			}
-			plog.Warningf("consistent index never saved (snapshot index=%d)", snapshot.Metadata.Index)
-		}
-	}
-	newSrv := srv // since srv == nil in defer if srv is returned as nil
-	defer func() {
-		// closing backend without first closing kv can cause
-		// resumed compactions to fail with closed tx errors
-		if err != nil {
-			newSrv.kv.Close()
-		}
-	}()
-
-	srv.consistIndex.setConsistentIndex(srv.kv.ConsistentIndex())
-	tp, err := auth.NewTokenProvider(cfg.AuthToken,
-		func(index uint64) <-chan struct{} {
-			return srv.applyWait.Wait(index)
-		},
-	)
-	if err != nil {
-		plog.Errorf("failed to create token provider: %s", err)
-		return nil, err
-	}
-	srv.authStore = auth.NewAuthStore(srv.be, tp)
-	if num := cfg.AutoCompactionRetention; num != 0 {
-		srv.compactor, err = compactor.New(cfg.AutoCompactionMode, num, srv.kv, srv)
-		if err != nil {
-			return nil, err
-		}
-		srv.compactor.Run()
-	}
-
-	srv.applyV3Base = srv.newApplierV3Backend()
-	if err = srv.restoreAlarms(); err != nil {
-		return nil, err
-	}
-
-	// TODO: move transport initialization near the definition of remote
-	tr := &rafthttp.Transport{
-		TLSInfo:     cfg.PeerTLSInfo,
-		DialTimeout: cfg.peerDialTimeout(),
-		ID:          id,
-		URLs:        cfg.PeerURLs,
-		ClusterID:   cl.ID(),
-		Raft:        srv,
-		Snapshotter: ss,
-		ServerStats: sstats,
-		LeaderStats: lstats,
-		ErrorC:      srv.errorc,
-	}
-	if err = tr.Start(); err != nil {
-		return nil, err
-	}
-	// add all remotes into transport
-	for _, m := range remotes {
-		if m.ID != id {
-			tr.AddRemote(m.ID, m.PeerURLs)
-		}
-	}
-	for _, m := range cl.Members() {
-		if m.ID != id {
-			tr.AddPeer(m.ID, m.PeerURLs)
-		}
-	}
-	srv.r.transport = tr
-
-	return srv, nil
-}
-
-func (s *EtcdServer) adjustTicks() {
-	clusterN := len(s.cluster.Members())
-
-	// single-node fresh start, or single-node recovers from snapshot
-	if clusterN == 1 {
-		ticks := s.Cfg.ElectionTicks - 1
-		plog.Infof("%s as single-node; fast-forwarding %d ticks (election ticks %d)", s.ID(), ticks, s.Cfg.ElectionTicks)
-		s.r.advanceTicks(ticks)
-		return
-	}
-
-	if !s.Cfg.InitialElectionTickAdvance {
-		plog.Infof("skipping initial election tick advance (election tick %d)", s.Cfg.ElectionTicks)
-		return
-	}
-
-	// retry up to "rafthttp.ConnReadTimeout", which is 5-sec
-	// until peer connection reports; otherwise:
-	// 1. all connections failed, or
-	// 2. no active peers, or
-	// 3. restarted single-node with no snapshot
-	// then, do nothing, because advancing ticks would have no effect
-	waitTime := rafthttp.ConnReadTimeout
-	itv := 50 * time.Millisecond
-	for i := int64(0); i < int64(waitTime/itv); i++ {
-		select {
-		case <-time.After(itv):
-		case <-s.stopping:
-			return
-		}
-
-		peerN := s.r.transport.ActivePeers()
-		if peerN > 1 {
-			// multi-node received peer connection reports
-			// adjust ticks, in case slow leader message receive
-			ticks := s.Cfg.ElectionTicks - 2
-			plog.Infof("%s initialzed peer connection; fast-forwarding %d ticks (election ticks %d) with %d active peer(s)", s.ID(), ticks, s.Cfg.ElectionTicks, peerN)
-			s.r.advanceTicks(ticks)
-			return
-		}
-	}
-}
-
-// Start performs any initialization of the Server necessary for it to
-// begin serving requests. It must be called before Do or Process.
-// Start must be non-blocking; any long-running server functionality
-// should be implemented in goroutines.
-func (s *EtcdServer) Start() {
-	s.start()
-	s.goAttach(func() { s.adjustTicks() })
-	s.goAttach(func() { s.publish(s.Cfg.ReqTimeout()) })
-	s.goAttach(s.purgeFile)
-	s.goAttach(func() { monitorFileDescriptor(s.stopping) })
-	s.goAttach(s.monitorVersions)
-	s.goAttach(s.linearizableReadLoop)
-	s.goAttach(s.monitorKVHash)
-}
-
-// start prepares and starts server in a new goroutine. It is no longer safe to
-// modify a server's fields after it has been sent to Start.
-// This function is just used for testing.
-func (s *EtcdServer) start() {
-	if s.Cfg.SnapCount == 0 {
-		plog.Infof("set snapshot count to default %d", DefaultSnapCount)
-		s.Cfg.SnapCount = DefaultSnapCount
-	}
-	s.w = wait.New()
-	s.applyWait = wait.NewTimeList()
-	s.done = make(chan struct{})
-	s.stop = make(chan struct{})
-	s.stopping = make(chan struct{})
-	s.ctx, s.cancel = context.WithCancel(context.Background())
-	s.readwaitc = make(chan struct{}, 1)
-	s.readNotifier = newNotifier()
-	if s.ClusterVersion() != nil {
-		plog.Infof("starting server... [version: %v, cluster version: %v]", version.Version, version.Cluster(s.ClusterVersion().String()))
-	} else {
-		plog.Infof("starting server... [version: %v, cluster version: to_be_decided]", version.Version)
-	}
-	// TODO: if this is an empty log, writes all peer infos
-	// into the first entry
-	go s.run()
-}
-
-func (s *EtcdServer) purgeFile() {
-	var dberrc, serrc, werrc <-chan error
-	if s.Cfg.MaxSnapFiles > 0 {
-		dberrc = fileutil.PurgeFile(s.Cfg.SnapDir(), "snap.db", s.Cfg.MaxSnapFiles, purgeFileInterval, s.done)
-		serrc = fileutil.PurgeFile(s.Cfg.SnapDir(), "snap", s.Cfg.MaxSnapFiles, purgeFileInterval, s.done)
-	}
-	if s.Cfg.MaxWALFiles > 0 {
-		werrc = fileutil.PurgeFile(s.Cfg.WALDir(), "wal", s.Cfg.MaxWALFiles, purgeFileInterval, s.done)
-	}
-	select {
-	case e := <-dberrc:
-		plog.Fatalf("failed to purge snap db file %v", e)
-	case e := <-serrc:
-		plog.Fatalf("failed to purge snap file %v", e)
-	case e := <-werrc:
-		plog.Fatalf("failed to purge wal file %v", e)
-	case <-s.stopping:
-		return
-	}
-}
-
-func (s *EtcdServer) ID() types.ID { return s.id }
-
-func (s *EtcdServer) Cluster() api.Cluster { return s.cluster }
-
-func (s *EtcdServer) ApplyWait() <-chan struct{} { return s.applyWait.Wait(s.getCommittedIndex()) }
-
-type ServerPeer interface {
-	ServerV2
-	RaftHandler() http.Handler
-	LeaseHandler() http.Handler
-}
-
-func (s *EtcdServer) LeaseHandler() http.Handler {
-	if s.lessor == nil {
-		return nil
-	}
-	return leasehttp.NewHandler(s.lessor, s.ApplyWait)
-}
-
-func (s *EtcdServer) RaftHandler() http.Handler { return s.r.transport.Handler() }
-
-// Process takes a raft message and applies it to the server's raft state
-// machine, respecting any timeout of the given context.
-func (s *EtcdServer) Process(ctx context.Context, m raftpb.Message) error {
-	if s.cluster.IsIDRemoved(types.ID(m.From)) {
-		plog.Warningf("reject message from removed member %s", types.ID(m.From).String())
-		return httptypes.NewHTTPError(http.StatusForbidden, "cannot process message from removed member")
-	}
-	if m.Type == raftpb.MsgApp {
-		s.stats.RecvAppendReq(types.ID(m.From).String(), m.Size())
-	}
-	return s.r.Step(ctx, m)
-}
-
-func (s *EtcdServer) IsIDRemoved(id uint64) bool { return s.cluster.IsIDRemoved(types.ID(id)) }
-
-func (s *EtcdServer) ReportUnreachable(id uint64) { s.r.ReportUnreachable(id) }
-
-// ReportSnapshot reports snapshot sent status to the raft state machine,
-// and clears the used snapshot from the snapshot store.
-func (s *EtcdServer) ReportSnapshot(id uint64, status raft.SnapshotStatus) {
-	s.r.ReportSnapshot(id, status)
-}
-
-type etcdProgress struct {
-	confState raftpb.ConfState
-	snapi     uint64
-	appliedt  uint64
-	appliedi  uint64
-}
-
-// raftReadyHandler contains a set of EtcdServer operations to be called by raftNode,
-// and helps decouple state machine logic from Raft algorithms.
-// TODO: add a state machine interface to apply the commit entries and do snapshot/recover
-type raftReadyHandler struct {
-	updateLeadership     func(newLeader bool)
-	updateCommittedIndex func(uint64)
-}
-
-func (s *EtcdServer) run() {
-	sn, err := s.r.raftStorage.Snapshot()
-	if err != nil {
-		plog.Panicf("get snapshot from raft storage error: %v", err)
-	}
-
-	// asynchronously accept apply packets, dispatch progress in-order
-	sched := schedule.NewFIFOScheduler()
-
-	var (
-		smu   sync.RWMutex
-		syncC <-chan time.Time
-	)
-	setSyncC := func(ch <-chan time.Time) {
-		smu.Lock()
-		syncC = ch
-		smu.Unlock()
-	}
-	getSyncC := func() (ch <-chan time.Time) {
-		smu.RLock()
-		ch = syncC
-		smu.RUnlock()
-		return
-	}
-	rh := &raftReadyHandler{
-		updateLeadership: func(newLeader bool) {
-			if !s.isLeader() {
-				if s.lessor != nil {
-					s.lessor.Demote()
-				}
-				if s.compactor != nil {
-					s.compactor.Pause()
-				}
-				setSyncC(nil)
-			} else {
-				if newLeader {
-					t := time.Now()
-					s.leadTimeMu.Lock()
-					s.leadElectedTime = t
-					s.leadTimeMu.Unlock()
-				}
-				setSyncC(s.SyncTicker.C)
-				if s.compactor != nil {
-					s.compactor.Resume()
-				}
-			}
-
-			// TODO: remove the nil checking
-			// current test utility does not provide the stats
-			if s.stats != nil {
-				s.stats.BecomeLeader()
-			}
-		},
-		updateCommittedIndex: func(ci uint64) {
-			cci := s.getCommittedIndex()
-			if ci > cci {
-				s.setCommittedIndex(ci)
-			}
-		},
-	}
-	s.r.start(rh)
-
-	ep := etcdProgress{
-		confState: sn.Metadata.ConfState,
-		snapi:     sn.Metadata.Index,
-		appliedt:  sn.Metadata.Term,
-		appliedi:  sn.Metadata.Index,
-	}
-
-	defer func() {
-		s.wgMu.Lock() // block concurrent waitgroup adds in goAttach while stopping
-		close(s.stopping)
-		s.wgMu.Unlock()
-		s.cancel()
-
-		sched.Stop()
-
-		// wait for gouroutines before closing raft so wal stays open
-		s.wg.Wait()
-
-		s.SyncTicker.Stop()
-
-		// must stop raft after scheduler-- etcdserver can leak rafthttp pipelines
-		// by adding a peer after raft stops the transport
-		s.r.stop()
-
-		// kv, lessor and backend can be nil if running without v3 enabled
-		// or running unit tests.
-		if s.lessor != nil {
-			s.lessor.Stop()
-		}
-		if s.kv != nil {
-			s.kv.Close()
-		}
-		if s.authStore != nil {
-			s.authStore.Close()
-		}
-		if s.be != nil {
-			s.be.Close()
-		}
-		if s.compactor != nil {
-			s.compactor.Stop()
-		}
-		close(s.done)
-	}()
-
-	var expiredLeaseC <-chan []*lease.Lease
-	if s.lessor != nil {
-		expiredLeaseC = s.lessor.ExpiredLeasesC()
-	}
-
-	for {
-		select {
-		case ap := <-s.r.apply():
-			f := func(context.Context) { s.applyAll(&ep, &ap) }
-			sched.Schedule(f)
-		case leases := <-expiredLeaseC:
-			s.goAttach(func() {
-				// Increases throughput of expired leases deletion process through parallelization
-				c := make(chan struct{}, maxPendingRevokes)
-				for _, lease := range leases {
-					select {
-					case c <- struct{}{}:
-					case <-s.stopping:
-						return
-					}
-					lid := lease.ID
-					s.goAttach(func() {
-						ctx := s.authStore.WithRoot(s.ctx)
-						_, lerr := s.LeaseRevoke(ctx, &pb.LeaseRevokeRequest{ID: int64(lid)})
-						if lerr == nil {
-							leaseExpired.Inc()
-						} else {
-							plog.Warningf("failed to revoke %016x (%q)", lid, lerr.Error())
-						}
-
-						<-c
-					})
-				}
-			})
-		case err := <-s.errorc:
-			plog.Errorf("%s", err)
-			plog.Infof("the data-dir used by this member must be removed.")
-			return
-		case <-getSyncC():
-			if s.store.HasTTLKeys() {
-				s.sync(s.Cfg.ReqTimeout())
-			}
-		case <-s.stop:
-			return
-		}
-	}
-}
-
-func (s *EtcdServer) applyAll(ep *etcdProgress, apply *apply) {
-	s.applySnapshot(ep, apply)
-	s.applyEntries(ep, apply)
-
-	proposalsApplied.Set(float64(ep.appliedi))
-	s.applyWait.Trigger(ep.appliedi)
-	// wait for the raft routine to finish the disk writes before triggering a
-	// snapshot. or applied index might be greater than the last index in raft
-	// storage, since the raft routine might be slower than apply routine.
-	<-apply.notifyc
-
-	s.triggerSnapshot(ep)
-	select {
-	// snapshot requested via send()
-	case m := <-s.r.msgSnapC:
-		merged := s.createMergedSnapshotMessage(m, ep.appliedt, ep.appliedi, ep.confState)
-		s.sendMergedSnap(merged)
-	default:
-	}
-}
-
-func (s *EtcdServer) applySnapshot(ep *etcdProgress, apply *apply) {
-	if raft.IsEmptySnap(apply.snapshot) {
-		return
-	}
-
-	plog.Infof("applying snapshot at index %d...", ep.snapi)
-	defer plog.Infof("finished applying incoming snapshot at index %d", ep.snapi)
-
-	if apply.snapshot.Metadata.Index <= ep.appliedi {
-		plog.Panicf("snapshot index [%d] should > appliedi[%d] + 1",
-			apply.snapshot.Metadata.Index, ep.appliedi)
-	}
-
-	// wait for raftNode to persist snapshot onto the disk
-	<-apply.notifyc
-
-	newbe, err := openSnapshotBackend(s.Cfg, s.snapshotter, apply.snapshot)
-	if err != nil {
-		plog.Panic(err)
-	}
-
-	// always recover lessor before kv. When we recover the mvcc.KV it will reattach keys to its leases.
-	// If we recover mvcc.KV first, it will attach the keys to the wrong lessor before it recovers.
-	if s.lessor != nil {
-		plog.Info("recovering lessor...")
-		s.lessor.Recover(newbe, func() lease.TxnDelete { return s.kv.Write() })
-		plog.Info("finished recovering lessor")
-	}
-
-	plog.Info("restoring mvcc store...")
-
-	if err := s.kv.Restore(newbe); err != nil {
-		plog.Panicf("restore KV error: %v", err)
-	}
-	s.consistIndex.setConsistentIndex(s.kv.ConsistentIndex())
-
-	plog.Info("finished restoring mvcc store")
-
-	// Closing old backend might block until all the txns
-	// on the backend are finished.
-	// We do not want to wait on closing the old backend.
-	s.bemu.Lock()
-	oldbe := s.be
-	go func() {
-		plog.Info("closing old backend...")
-		defer plog.Info("finished closing old backend")
-
-		if err := oldbe.Close(); err != nil {
-			plog.Panicf("close backend error: %v", err)
-		}
-	}()
-
-	s.be = newbe
-	s.bemu.Unlock()
-
-	plog.Info("recovering alarms...")
-	if err := s.restoreAlarms(); err != nil {
-		plog.Panicf("restore alarms error: %v", err)
-	}
-	plog.Info("finished recovering alarms")
-
-	if s.authStore != nil {
-		plog.Info("recovering auth store...")
-		s.authStore.Recover(newbe)
-		plog.Info("finished recovering auth store")
-	}
-
-	plog.Info("recovering store v2...")
-	if err := s.store.Recovery(apply.snapshot.Data); err != nil {
-		plog.Panicf("recovery store error: %v", err)
-	}
-	plog.Info("finished recovering store v2")
-
-	s.cluster.SetBackend(s.be)
-	plog.Info("recovering cluster configuration...")
-	s.cluster.Recover(api.UpdateCapability)
-	plog.Info("finished recovering cluster configuration")
-
-	plog.Info("removing old peers from network...")
-	// recover raft transport
-	s.r.transport.RemoveAllPeers()
-	plog.Info("finished removing old peers from network")
-
-	plog.Info("adding peers from new cluster configuration into network...")
-	for _, m := range s.cluster.Members() {
-		if m.ID == s.ID() {
-			continue
-		}
-		s.r.transport.AddPeer(m.ID, m.PeerURLs)
-	}
-	plog.Info("finished adding peers from new cluster configuration into network...")
-
-	ep.appliedt = apply.snapshot.Metadata.Term
-	ep.appliedi = apply.snapshot.Metadata.Index
-	ep.snapi = ep.appliedi
-	ep.confState = apply.snapshot.Metadata.ConfState
-}
-
-func (s *EtcdServer) applyEntries(ep *etcdProgress, apply *apply) {
-	if len(apply.entries) == 0 {
-		return
-	}
-	firsti := apply.entries[0].Index
-	if firsti > ep.appliedi+1 {
-		plog.Panicf("first index of committed entry[%d] should <= appliedi[%d] + 1", firsti, ep.appliedi)
-	}
-	var ents []raftpb.Entry
-	if ep.appliedi+1-firsti < uint64(len(apply.entries)) {
-		ents = apply.entries[ep.appliedi+1-firsti:]
-	}
-	if len(ents) == 0 {
-		return
-	}
-	var shouldstop bool
-	if ep.appliedt, ep.appliedi, shouldstop = s.apply(ents, &ep.confState); shouldstop {
-		go s.stopWithDelay(10*100*time.Millisecond, fmt.Errorf("the member has been permanently removed from the cluster"))
-	}
-}
-
-func (s *EtcdServer) triggerSnapshot(ep *etcdProgress) {
-	if ep.appliedi-ep.snapi <= s.Cfg.SnapCount {
-		return
-	}
-
-	plog.Infof("start to snapshot (applied: %d, lastsnap: %d)", ep.appliedi, ep.snapi)
-	s.snapshot(ep.appliedi, ep.confState)
-	ep.snapi = ep.appliedi
-}
-
-func (s *EtcdServer) isMultiNode() bool {
-	return s.cluster != nil && len(s.cluster.MemberIDs()) > 1
-}
-
-func (s *EtcdServer) isLeader() bool {
-	return uint64(s.ID()) == s.Lead()
-}
-
-// MoveLeader transfers the leader to the given transferee.
-func (s *EtcdServer) MoveLeader(ctx context.Context, lead, transferee uint64) error {
-	now := time.Now()
-	interval := time.Duration(s.Cfg.TickMs) * time.Millisecond
-
-	plog.Infof("%s starts leadership transfer from %s to %s", s.ID(), types.ID(lead), types.ID(transferee))
-	s.r.TransferLeadership(ctx, lead, transferee)
-	for s.Lead() != transferee {
-		select {
-		case <-ctx.Done(): // time out
-			return ErrTimeoutLeaderTransfer
-		case <-time.After(interval):
-		}
-	}
-
-	// TODO: drain all requests, or drop all messages to the old leader
-
-	plog.Infof("%s finished leadership transfer from %s to %s (took %v)", s.ID(), types.ID(lead), types.ID(transferee), time.Since(now))
-	return nil
-}
-
-// TransferLeadership transfers the leader to the chosen transferee.
-func (s *EtcdServer) TransferLeadership() error {
-	if !s.isLeader() {
-		plog.Printf("skipped leadership transfer for stopping non-leader member")
-		return nil
-	}
-
-	if !s.isMultiNode() {
-		plog.Printf("skipped leadership transfer for single member cluster")
-		return nil
-	}
-
-	transferee, ok := longestConnected(s.r.transport, s.cluster.MemberIDs())
-	if !ok {
-		return ErrUnhealthy
-	}
-
-	tm := s.Cfg.ReqTimeout()
-	ctx, cancel := context.WithTimeout(s.ctx, tm)
-	err := s.MoveLeader(ctx, s.Lead(), uint64(transferee))
-	cancel()
-	return err
-}
-
-// HardStop stops the server without coordination with other members in the cluster.
-func (s *EtcdServer) HardStop() {
-	select {
-	case s.stop <- struct{}{}:
-	case <-s.done:
-		return
-	}
-	<-s.done
-}
-
-// Stop stops the server gracefully, and shuts down the running goroutine.
-// Stop should be called after a Start(s), otherwise it will block forever.
-// When stopping leader, Stop transfers its leadership to one of its peers
-// before stopping the server.
-// Stop terminates the Server and performs any necessary finalization.
-// Do and Process cannot be called after Stop has been invoked.
-func (s *EtcdServer) Stop() {
-	if err := s.TransferLeadership(); err != nil {
-		plog.Warningf("%s failed to transfer leadership (%v)", s.ID(), err)
-	}
-	s.HardStop()
-}
-
-// ReadyNotify returns a channel that will be closed when the server
-// is ready to serve client requests
-func (s *EtcdServer) ReadyNotify() <-chan struct{} { return s.readych }
-
-func (s *EtcdServer) stopWithDelay(d time.Duration, err error) {
-	select {
-	case <-time.After(d):
-	case <-s.done:
-	}
-	select {
-	case s.errorc <- err:
-	default:
-	}
-}
-
-// StopNotify returns a channel that receives a empty struct
-// when the server is stopped.
-func (s *EtcdServer) StopNotify() <-chan struct{} { return s.done }
-
-func (s *EtcdServer) SelfStats() []byte { return s.stats.JSON() }
-
-func (s *EtcdServer) LeaderStats() []byte {
-	lead := atomic.LoadUint64(&s.r.lead)
-	if lead != uint64(s.id) {
-		return nil
-	}
-	return s.lstats.JSON()
-}
-
-func (s *EtcdServer) StoreStats() []byte { return s.store.JsonStats() }
-
-func (s *EtcdServer) checkMembershipOperationPermission(ctx context.Context) error {
-	if s.authStore == nil {
-		// In the context of ordinary etcd process, s.authStore will never be nil.
-		// This branch is for handling cases in server_test.go
-		return nil
-	}
-
-	// Note that this permission check is done in the API layer,
-	// so TOCTOU problem can be caused potentially in a schedule like this:
-	// update membership with user A -> revoke root role of A -> apply membership change
-	// in the state machine layer
-	// However, both of membership change and role management requires the root privilege.
-	// So careful operation by admins can prevent the problem.
-	authInfo, err := s.AuthInfoFromCtx(ctx)
-	if err != nil {
-		return err
-	}
-
-	return s.AuthStore().IsAdminPermitted(authInfo)
-}
-
-func (s *EtcdServer) AddMember(ctx context.Context, memb membership.Member) ([]*membership.Member, error) {
-	if err := s.checkMembershipOperationPermission(ctx); err != nil {
-		return nil, err
-	}
-
-	if s.Cfg.StrictReconfigCheck {
-		// by default StrictReconfigCheck is enabled; reject new members if unhealthy
-		if !s.cluster.IsReadyToAddNewMember() {
-			plog.Warningf("not enough started members, rejecting member add %+v", memb)
-			return nil, ErrNotEnoughStartedMembers
-		}
-		if !isConnectedFullySince(s.r.transport, time.Now().Add(-HealthInterval), s.ID(), s.cluster.Members()) {
-			plog.Warningf("not healthy for reconfigure, rejecting member add %+v", memb)
-			return nil, ErrUnhealthy
-		}
-	}
-
-	// TODO: move Member to protobuf type
-	b, err := json.Marshal(memb)
-	if err != nil {
-		return nil, err
-	}
-	cc := raftpb.ConfChange{
-		Type:    raftpb.ConfChangeAddNode,
-		NodeID:  uint64(memb.ID),
-		Context: b,
-	}
-	return s.configure(ctx, cc)
-}
-
-func (s *EtcdServer) RemoveMember(ctx context.Context, id uint64) ([]*membership.Member, error) {
-	if err := s.checkMembershipOperationPermission(ctx); err != nil {
-		return nil, err
-	}
-
-	// by default StrictReconfigCheck is enabled; reject removal if leads to quorum loss
-	if err := s.mayRemoveMember(types.ID(id)); err != nil {
-		return nil, err
-	}
-
-	cc := raftpb.ConfChange{
-		Type:   raftpb.ConfChangeRemoveNode,
-		NodeID: id,
-	}
-	return s.configure(ctx, cc)
-}
-
-func (s *EtcdServer) mayRemoveMember(id types.ID) error {
-	if !s.Cfg.StrictReconfigCheck {
-		return nil
-	}
-
-	if !s.cluster.IsReadyToRemoveMember(uint64(id)) {
-		plog.Warningf("not enough started members, rejecting remove member %s", id)
-		return ErrNotEnoughStartedMembers
-	}
-
-	// downed member is safe to remove since it's not part of the active quorum
-	if t := s.r.transport.ActiveSince(id); id != s.ID() && t.IsZero() {
-		return nil
-	}
-
-	// protect quorum if some members are down
-	m := s.cluster.Members()
-	active := numConnectedSince(s.r.transport, time.Now().Add(-HealthInterval), s.ID(), m)
-	if (active - 1) < 1+((len(m)-1)/2) {
-		plog.Warningf("reconfigure breaks active quorum, rejecting remove member %s", id)
-		return ErrUnhealthy
-	}
-
-	return nil
-}
-
-func (s *EtcdServer) UpdateMember(ctx context.Context, memb membership.Member) ([]*membership.Member, error) {
-	b, merr := json.Marshal(memb)
-	if merr != nil {
-		return nil, merr
-	}
-
-	if err := s.checkMembershipOperationPermission(ctx); err != nil {
-		return nil, err
-	}
-	cc := raftpb.ConfChange{
-		Type:    raftpb.ConfChangeUpdateNode,
-		NodeID:  uint64(memb.ID),
-		Context: b,
-	}
-	return s.configure(ctx, cc)
-}
-
-// Implement the RaftTimer interface
-
-func (s *EtcdServer) Index() uint64 { return atomic.LoadUint64(&s.r.index) }
-
-func (s *EtcdServer) Term() uint64 { return atomic.LoadUint64(&s.r.term) }
-
-// Lead is only for testing purposes.
-// TODO: add Raft server interface to expose raft related info:
-// Index, Term, Lead, Committed, Applied, LastIndex, etc.
-func (s *EtcdServer) Lead() uint64 { return atomic.LoadUint64(&s.r.lead) }
-
-func (s *EtcdServer) Leader() types.ID { return types.ID(s.Lead()) }
-
-type confChangeResponse struct {
-	membs []*membership.Member
-	err   error
-}
-
-// configure sends a configuration change through consensus and
-// then waits for it to be applied to the server. It
-// will block until the change is performed or there is an error.
-func (s *EtcdServer) configure(ctx context.Context, cc raftpb.ConfChange) ([]*membership.Member, error) {
-	cc.ID = s.reqIDGen.Next()
-	ch := s.w.Register(cc.ID)
-	start := time.Now()
-	if err := s.r.ProposeConfChange(ctx, cc); err != nil {
-		s.w.Trigger(cc.ID, nil)
-		return nil, err
-	}
-	select {
-	case x := <-ch:
-		if x == nil {
-			plog.Panicf("configure trigger value should never be nil")
-		}
-		resp := x.(*confChangeResponse)
-		return resp.membs, resp.err
-	case <-ctx.Done():
-		s.w.Trigger(cc.ID, nil) // GC wait
-		return nil, s.parseProposeCtxErr(ctx.Err(), start)
-	case <-s.stopping:
-		return nil, ErrStopped
-	}
-}
-
-// sync proposes a SYNC request and is non-blocking.
-// This makes no guarantee that the request will be proposed or performed.
-// The request will be canceled after the given timeout.
-func (s *EtcdServer) sync(timeout time.Duration) {
-	req := pb.Request{
-		Method: "SYNC",
-		ID:     s.reqIDGen.Next(),
-		Time:   time.Now().UnixNano(),
-	}
-	data := pbutil.MustMarshal(&req)
-	// There is no promise that node has leader when do SYNC request,
-	// so it uses goroutine to propose.
-	ctx, cancel := context.WithTimeout(s.ctx, timeout)
-	s.goAttach(func() {
-		s.r.Propose(ctx, data)
-		cancel()
-	})
-}
-
-// publish registers server information into the cluster. The information
-// is the JSON representation of this server's member struct, updated with the
-// static clientURLs of the server.
-// The function keeps attempting to register until it succeeds,
-// or its server is stopped.
-func (s *EtcdServer) publish(timeout time.Duration) {
-	b, err := json.Marshal(s.attributes)
-	if err != nil {
-		plog.Panicf("json marshal error: %v", err)
-		return
-	}
-	req := pb.Request{
-		Method: "PUT",
-		Path:   membership.MemberAttributesStorePath(s.id),
-		Val:    string(b),
-	}
-
-	for {
-		ctx, cancel := context.WithTimeout(s.ctx, timeout)
-		_, err := s.Do(ctx, req)
-		cancel()
-		switch err {
-		case nil:
-			close(s.readych)
-			plog.Infof("published %+v to cluster %s", s.attributes, s.cluster.ID())
-			return
-		case ErrStopped:
-			plog.Infof("aborting publish because server is stopped")
-			return
-		default:
-			plog.Errorf("publish error: %v", err)
-		}
-	}
-}
-
-func (s *EtcdServer) sendMergedSnap(merged snap.Message) {
-	atomic.AddInt64(&s.inflightSnapshots, 1)
-
-	s.r.transport.SendSnapshot(merged)
-	s.goAttach(func() {
-		select {
-		case ok := <-merged.CloseNotify():
-			// delay releasing inflight snapshot for another 30 seconds to
-			// block log compaction.
-			// If the follower still fails to catch up, it is probably just too slow
-			// to catch up. We cannot avoid the snapshot cycle anyway.
-			if ok {
-				select {
-				case <-time.After(releaseDelayAfterSnapshot):
-				case <-s.stopping:
-				}
-			}
-			atomic.AddInt64(&s.inflightSnapshots, -1)
-		case <-s.stopping:
-			return
-		}
-	})
-}
-
-// apply takes entries received from Raft (after it has been committed) and
-// applies them to the current state of the EtcdServer.
-// The given entries should not be empty.
-func (s *EtcdServer) apply(es []raftpb.Entry, confState *raftpb.ConfState) (appliedt uint64, appliedi uint64, shouldStop bool) {
-	for i := range es {
-		e := es[i]
-		switch e.Type {
-		case raftpb.EntryNormal:
-			s.applyEntryNormal(&e)
-		case raftpb.EntryConfChange:
-			// set the consistent index of current executing entry
-			if e.Index > s.consistIndex.ConsistentIndex() {
-				s.consistIndex.setConsistentIndex(e.Index)
-			}
-			var cc raftpb.ConfChange
-			pbutil.MustUnmarshal(&cc, e.Data)
-			removedSelf, err := s.applyConfChange(cc, confState)
-			s.setAppliedIndex(e.Index)
-			shouldStop = shouldStop || removedSelf
-			s.w.Trigger(cc.ID, &confChangeResponse{s.cluster.Members(), err})
-		default:
-			plog.Panicf("entry type should be either EntryNormal or EntryConfChange")
-		}
-		atomic.StoreUint64(&s.r.index, e.Index)
-		atomic.StoreUint64(&s.r.term, e.Term)
-		appliedt = e.Term
-		appliedi = e.Index
-	}
-	return appliedt, appliedi, shouldStop
-}
-
-// applyEntryNormal apples an EntryNormal type raftpb request to the EtcdServer
-func (s *EtcdServer) applyEntryNormal(e *raftpb.Entry) {
-	shouldApplyV3 := false
-	if e.Index > s.consistIndex.ConsistentIndex() {
-		// set the consistent index of current executing entry
-		s.consistIndex.setConsistentIndex(e.Index)
-		shouldApplyV3 = true
-	}
-	defer s.setAppliedIndex(e.Index)
-
-	// raft state machine may generate noop entry when leader confirmation.
-	// skip it in advance to avoid some potential bug in the future
-	if len(e.Data) == 0 {
-		select {
-		case s.forceVersionC <- struct{}{}:
-		default:
-		}
-		// promote lessor when the local member is leader and finished
-		// applying all entries from the last term.
-		if s.isLeader() {
-			s.lessor.Promote(s.Cfg.electionTimeout())
-		}
-		return
-	}
-
-	var raftReq pb.InternalRaftRequest
-	if !pbutil.MaybeUnmarshal(&raftReq, e.Data) { // backward compatible
-		var r pb.Request
-		rp := &r
-		pbutil.MustUnmarshal(rp, e.Data)
-		s.w.Trigger(r.ID, s.applyV2Request((*RequestV2)(rp)))
-		return
-	}
-	if raftReq.V2 != nil {
-		req := (*RequestV2)(raftReq.V2)
-		s.w.Trigger(req.ID, s.applyV2Request(req))
-		return
-	}
-
-	// do not re-apply applied entries.
-	if !shouldApplyV3 {
-		return
-	}
-
-	id := raftReq.ID
-	if id == 0 {
-		id = raftReq.Header.ID
-	}
-
-	var ar *applyResult
-	needResult := s.w.IsRegistered(id)
-	if needResult || !noSideEffect(&raftReq) {
-		if !needResult && raftReq.Txn != nil {
-			removeNeedlessRangeReqs(raftReq.Txn)
-		}
-		ar = s.applyV3.Apply(&raftReq)
-	}
-
-	if ar == nil {
-		return
-	}
-
-	if ar.err != ErrNoSpace || len(s.alarmStore.Get(pb.AlarmType_NOSPACE)) > 0 {
-		s.w.Trigger(id, ar)
-		return
-	}
-
-	plog.Errorf("applying raft message exceeded backend quota")
-	s.goAttach(func() {
-		a := &pb.AlarmRequest{
-			MemberID: uint64(s.ID()),
-			Action:   pb.AlarmRequest_ACTIVATE,
-			Alarm:    pb.AlarmType_NOSPACE,
-		}
-		s.raftRequest(s.ctx, pb.InternalRaftRequest{Alarm: a})
-		s.w.Trigger(id, ar)
-	})
-}
-
-// applyConfChange applies a ConfChange to the server. It is only
-// invoked with a ConfChange that has already passed through Raft
-func (s *EtcdServer) applyConfChange(cc raftpb.ConfChange, confState *raftpb.ConfState) (bool, error) {
-	if err := s.cluster.ValidateConfigurationChange(cc); err != nil {
-		cc.NodeID = raft.None
-		s.r.ApplyConfChange(cc)
-		return false, err
-	}
-	*confState = *s.r.ApplyConfChange(cc)
-	switch cc.Type {
-	case raftpb.ConfChangeAddNode:
-		m := new(membership.Member)
-		if err := json.Unmarshal(cc.Context, m); err != nil {
-			plog.Panicf("unmarshal member should never fail: %v", err)
-		}
-		if cc.NodeID != uint64(m.ID) {
-			plog.Panicf("nodeID should always be equal to member ID")
-		}
-		s.cluster.AddMember(m)
-		if m.ID != s.id {
-			s.r.transport.AddPeer(m.ID, m.PeerURLs)
-		}
-	case raftpb.ConfChangeRemoveNode:
-		id := types.ID(cc.NodeID)
-		s.cluster.RemoveMember(id)
-		if id == s.id {
-			return true, nil
-		}
-		s.r.transport.RemovePeer(id)
-	case raftpb.ConfChangeUpdateNode:
-		m := new(membership.Member)
-		if err := json.Unmarshal(cc.Context, m); err != nil {
-			plog.Panicf("unmarshal member should never fail: %v", err)
-		}
-		if cc.NodeID != uint64(m.ID) {
-			plog.Panicf("nodeID should always be equal to member ID")
-		}
-		s.cluster.UpdateRaftAttributes(m.ID, m.RaftAttributes)
-		if m.ID != s.id {
-			s.r.transport.UpdatePeer(m.ID, m.PeerURLs)
-		}
-	}
-	return false, nil
-}
-
-// TODO: non-blocking snapshot
-func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) {
-	clone := s.store.Clone()
-	// commit kv to write metadata (for example: consistent index) to disk.
-	// KV().commit() updates the consistent index in backend.
-	// All operations that update consistent index must be called sequentially
-	// from applyAll function.
-	// So KV().Commit() cannot run in parallel with apply. It has to be called outside
-	// the go routine created below.
-	s.KV().Commit()
-
-	s.goAttach(func() {
-		d, err := clone.SaveNoCopy()
-		// TODO: current store will never fail to do a snapshot
-		// what should we do if the store might fail?
-		if err != nil {
-			plog.Panicf("store save should never fail: %v", err)
-		}
-		snap, err := s.r.raftStorage.CreateSnapshot(snapi, &confState, d)
-		if err != nil {
-			// the snapshot was done asynchronously with the progress of raft.
-			// raft might have already got a newer snapshot.
-			if err == raft.ErrSnapOutOfDate {
-				return
-			}
-			plog.Panicf("unexpected create snapshot error %v", err)
-		}
-		// SaveSnap saves the snapshot and releases the locked wal files
-		// to the snapshot index.
-		if err = s.r.storage.SaveSnap(snap); err != nil {
-			plog.Fatalf("save snapshot error: %v", err)
-		}
-		plog.Infof("saved snapshot at index %d", snap.Metadata.Index)
-
-		// When sending a snapshot, etcd will pause compaction.
-		// After receives a snapshot, the slow follower needs to get all the entries right after
-		// the snapshot sent to catch up. If we do not pause compaction, the log entries right after
-		// the snapshot sent might already be compacted. It happens when the snapshot takes long time
-		// to send and save. Pausing compaction avoids triggering a snapshot sending cycle.
-		if atomic.LoadInt64(&s.inflightSnapshots) != 0 {
-			plog.Infof("skip compaction since there is an inflight snapshot")
-			return
-		}
-
-		// keep some in memory log entries for slow followers.
-		compacti := uint64(1)
-		if snapi > numberOfCatchUpEntries {
-			compacti = snapi - numberOfCatchUpEntries
-		}
-		err = s.r.raftStorage.Compact(compacti)
-		if err != nil {
-			// the compaction was done asynchronously with the progress of raft.
-			// raft log might already been compact.
-			if err == raft.ErrCompacted {
-				return
-			}
-			plog.Panicf("unexpected compaction error %v", err)
-		}
-		plog.Infof("compacted raft log at %d", compacti)
-	})
-}
-
-// CutPeer drops messages to the specified peer.
-func (s *EtcdServer) CutPeer(id types.ID) {
-	tr, ok := s.r.transport.(*rafthttp.Transport)
-	if ok {
-		tr.CutPeer(id)
-	}
-}
-
-// MendPeer recovers the message dropping behavior of the given peer.
-func (s *EtcdServer) MendPeer(id types.ID) {
-	tr, ok := s.r.transport.(*rafthttp.Transport)
-	if ok {
-		tr.MendPeer(id)
-	}
-}
-
-func (s *EtcdServer) PauseSending() { s.r.pauseSending() }
-
-func (s *EtcdServer) ResumeSending() { s.r.resumeSending() }
-
-func (s *EtcdServer) ClusterVersion() *semver.Version {
-	if s.cluster == nil {
-		return nil
-	}
-	return s.cluster.Version()
-}
-
-// monitorVersions checks the member's version every monitorVersionInterval.
-// It updates the cluster version if all members agrees on a higher one.
-// It prints out log if there is a member with a higher version than the
-// local version.
-func (s *EtcdServer) monitorVersions() {
-	for {
-		select {
-		case <-s.forceVersionC:
-		case <-time.After(monitorVersionInterval):
-		case <-s.stopping:
-			return
-		}
-
-		if s.Leader() != s.ID() {
-			continue
-		}
-
-		v := decideClusterVersion(getVersions(s.cluster, s.id, s.peerRt))
-		if v != nil {
-			// only keep major.minor version for comparison
-			v = &semver.Version{
-				Major: v.Major,
-				Minor: v.Minor,
-			}
-		}
-
-		// if the current version is nil:
-		// 1. use the decided version if possible
-		// 2. or use the min cluster version
-		if s.cluster.Version() == nil {
-			verStr := version.MinClusterVersion
-			if v != nil {
-				verStr = v.String()
-			}
-			s.goAttach(func() { s.updateClusterVersion(verStr) })
-			continue
-		}
-
-		// update cluster version only if the decided version is greater than
-		// the current cluster version
-		if v != nil && s.cluster.Version().LessThan(*v) {
-			s.goAttach(func() { s.updateClusterVersion(v.String()) })
-		}
-	}
-}
-
-func (s *EtcdServer) updateClusterVersion(ver string) {
-	if s.cluster.Version() == nil {
-		plog.Infof("setting up the initial cluster version to %s", version.Cluster(ver))
-	} else {
-		plog.Infof("updating the cluster version from %s to %s", version.Cluster(s.cluster.Version().String()), version.Cluster(ver))
-	}
-	req := pb.Request{
-		Method: "PUT",
-		Path:   membership.StoreClusterVersionKey(),
-		Val:    ver,
-	}
-	ctx, cancel := context.WithTimeout(s.ctx, s.Cfg.ReqTimeout())
-	_, err := s.Do(ctx, req)
-	cancel()
-	switch err {
-	case nil:
-		return
-	case ErrStopped:
-		plog.Infof("aborting update cluster version because server is stopped")
-		return
-	default:
-		plog.Errorf("error updating cluster version (%v)", err)
-	}
-}
-
-func (s *EtcdServer) parseProposeCtxErr(err error, start time.Time) error {
-	switch err {
-	case context.Canceled:
-		return ErrCanceled
-	case context.DeadlineExceeded:
-		s.leadTimeMu.RLock()
-		curLeadElected := s.leadElectedTime
-		s.leadTimeMu.RUnlock()
-		prevLeadLost := curLeadElected.Add(-2 * time.Duration(s.Cfg.ElectionTicks) * time.Duration(s.Cfg.TickMs) * time.Millisecond)
-		if start.After(prevLeadLost) && start.Before(curLeadElected) {
-			return ErrTimeoutDueToLeaderFail
-		}
-
-		lead := types.ID(atomic.LoadUint64(&s.r.lead))
-		switch lead {
-		case types.ID(raft.None):
-			// TODO: return error to specify it happens because the cluster does not have leader now
-		case s.ID():
-			if !isConnectedToQuorumSince(s.r.transport, start, s.ID(), s.cluster.Members()) {
-				return ErrTimeoutDueToConnectionLost
-			}
-		default:
-			if !isConnectedSince(s.r.transport, start, lead) {
-				return ErrTimeoutDueToConnectionLost
-			}
-		}
-
-		return ErrTimeout
-	default:
-		return err
-	}
-}
-
-func (s *EtcdServer) KV() mvcc.ConsistentWatchableKV { return s.kv }
-func (s *EtcdServer) Backend() backend.Backend {
-	s.bemu.Lock()
-	defer s.bemu.Unlock()
-	return s.be
-}
-
-func (s *EtcdServer) AuthStore() auth.AuthStore { return s.authStore }
-
-func (s *EtcdServer) restoreAlarms() error {
-	s.applyV3 = s.newApplierV3()
-	as, err := alarm.NewAlarmStore(s)
-	if err != nil {
-		return err
-	}
-	s.alarmStore = as
-	if len(as.Get(pb.AlarmType_NOSPACE)) > 0 {
-		s.applyV3 = newApplierV3Capped(s.applyV3)
-	}
-	if len(as.Get(pb.AlarmType_CORRUPT)) > 0 {
-		s.applyV3 = newApplierV3Corrupt(s.applyV3)
-	}
-	return nil
-}
-
-func (s *EtcdServer) getAppliedIndex() uint64 {
-	return atomic.LoadUint64(&s.appliedIndex)
-}
-
-func (s *EtcdServer) setAppliedIndex(v uint64) {
-	atomic.StoreUint64(&s.appliedIndex, v)
-}
-
-func (s *EtcdServer) getCommittedIndex() uint64 {
-	return atomic.LoadUint64(&s.committedIndex)
-}
-
-func (s *EtcdServer) setCommittedIndex(v uint64) {
-	atomic.StoreUint64(&s.committedIndex, v)
-}
-
-// goAttach creates a goroutine on a given function and tracks it using
-// the etcdserver waitgroup.
-func (s *EtcdServer) goAttach(f func()) {
-	s.wgMu.RLock() // this blocks with ongoing close(s.stopping)
-	defer s.wgMu.RUnlock()
-	select {
-	case <-s.stopping:
-		plog.Warning("server has stopped (skipping goAttach)")
-		return
-	default:
-	}
-
-	// now safe to add since waitgroup wait has not started yet
-	s.wg.Add(1)
-	go func() {
-		defer s.wg.Done()
-		f()
-	}()
-}
-
-func (s *EtcdServer) Alarms() []*pb.AlarmMember {
-	return s.alarmStore.Get(pb.AlarmType_NONE)
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go b/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go
deleted file mode 100644
index 928aa95..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/snapshot_merge.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"io"
-
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/snap"
-)
-
-// createMergedSnapshotMessage creates a snapshot message that contains: raft status (term, conf),
-// a snapshot of v2 store inside raft.Snapshot as []byte, a snapshot of v3 KV in the top level message
-// as ReadCloser.
-func (s *EtcdServer) createMergedSnapshotMessage(m raftpb.Message, snapt, snapi uint64, confState raftpb.ConfState) snap.Message {
-	// get a snapshot of v2 store as []byte
-	clone := s.store.Clone()
-	d, err := clone.SaveNoCopy()
-	if err != nil {
-		plog.Panicf("store save should never fail: %v", err)
-	}
-
-	// commit kv to write metadata(for example: consistent index).
-	s.KV().Commit()
-	dbsnap := s.be.Snapshot()
-	// get a snapshot of v3 KV as readCloser
-	rc := newSnapshotReaderCloser(dbsnap)
-
-	// put the []byte snapshot of store into raft snapshot and return the merged snapshot with
-	// KV readCloser snapshot.
-	snapshot := raftpb.Snapshot{
-		Metadata: raftpb.SnapshotMetadata{
-			Index:     snapi,
-			Term:      snapt,
-			ConfState: confState,
-		},
-		Data: d,
-	}
-	m.Snapshot = snapshot
-
-	return *snap.NewMessage(m, rc, dbsnap.Size())
-}
-
-func newSnapshotReaderCloser(snapshot backend.Snapshot) io.ReadCloser {
-	pr, pw := io.Pipe()
-	go func() {
-		n, err := snapshot.WriteTo(pw)
-		if err == nil {
-			plog.Infof("wrote database snapshot out [total bytes: %d]", n)
-		} else {
-			plog.Warningf("failed to write database snapshot out [written bytes: %d]: %v", n, err)
-		}
-		pw.CloseWithError(err)
-		err = snapshot.Close()
-		if err != nil {
-			plog.Panicf("failed to close database snapshot: %v", err)
-		}
-	}()
-	return pr
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/stats/leader.go b/vendor/github.com/coreos/etcd/etcdserver/stats/leader.go
deleted file mode 100644
index 8f6a54f..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/stats/leader.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package stats
-
-import (
-	"encoding/json"
-	"math"
-	"sync"
-	"time"
-)
-
-// LeaderStats is used by the leader in an etcd cluster, and encapsulates
-// statistics about communication with its followers
-type LeaderStats struct {
-	leaderStats
-	sync.Mutex
-}
-
-type leaderStats struct {
-	// Leader is the ID of the leader in the etcd cluster.
-	// TODO(jonboulle): clarify that these are IDs, not names
-	Leader    string                    `json:"leader"`
-	Followers map[string]*FollowerStats `json:"followers"`
-}
-
-// NewLeaderStats generates a new LeaderStats with the given id as leader
-func NewLeaderStats(id string) *LeaderStats {
-	return &LeaderStats{
-		leaderStats: leaderStats{
-			Leader:    id,
-			Followers: make(map[string]*FollowerStats),
-		},
-	}
-}
-
-func (ls *LeaderStats) JSON() []byte {
-	ls.Lock()
-	stats := ls.leaderStats
-	ls.Unlock()
-	b, err := json.Marshal(stats)
-	// TODO(jonboulle): appropriate error handling?
-	if err != nil {
-		plog.Errorf("error marshalling leader stats (%v)", err)
-	}
-	return b
-}
-
-func (ls *LeaderStats) Follower(name string) *FollowerStats {
-	ls.Lock()
-	defer ls.Unlock()
-	fs, ok := ls.Followers[name]
-	if !ok {
-		fs = &FollowerStats{}
-		fs.Latency.Minimum = 1 << 63
-		ls.Followers[name] = fs
-	}
-	return fs
-}
-
-// FollowerStats encapsulates various statistics about a follower in an etcd cluster
-type FollowerStats struct {
-	Latency LatencyStats `json:"latency"`
-	Counts  CountsStats  `json:"counts"`
-
-	sync.Mutex
-}
-
-// LatencyStats encapsulates latency statistics.
-type LatencyStats struct {
-	Current           float64 `json:"current"`
-	Average           float64 `json:"average"`
-	averageSquare     float64
-	StandardDeviation float64 `json:"standardDeviation"`
-	Minimum           float64 `json:"minimum"`
-	Maximum           float64 `json:"maximum"`
-}
-
-// CountsStats encapsulates raft statistics.
-type CountsStats struct {
-	Fail    uint64 `json:"fail"`
-	Success uint64 `json:"success"`
-}
-
-// Succ updates the FollowerStats with a successful send
-func (fs *FollowerStats) Succ(d time.Duration) {
-	fs.Lock()
-	defer fs.Unlock()
-
-	total := float64(fs.Counts.Success) * fs.Latency.Average
-	totalSquare := float64(fs.Counts.Success) * fs.Latency.averageSquare
-
-	fs.Counts.Success++
-
-	fs.Latency.Current = float64(d) / (1000000.0)
-
-	if fs.Latency.Current > fs.Latency.Maximum {
-		fs.Latency.Maximum = fs.Latency.Current
-	}
-
-	if fs.Latency.Current < fs.Latency.Minimum {
-		fs.Latency.Minimum = fs.Latency.Current
-	}
-
-	fs.Latency.Average = (total + fs.Latency.Current) / float64(fs.Counts.Success)
-	fs.Latency.averageSquare = (totalSquare + fs.Latency.Current*fs.Latency.Current) / float64(fs.Counts.Success)
-
-	// sdv = sqrt(avg(x^2) - avg(x)^2)
-	fs.Latency.StandardDeviation = math.Sqrt(fs.Latency.averageSquare - fs.Latency.Average*fs.Latency.Average)
-}
-
-// Fail updates the FollowerStats with an unsuccessful send
-func (fs *FollowerStats) Fail() {
-	fs.Lock()
-	defer fs.Unlock()
-	fs.Counts.Fail++
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/stats/queue.go b/vendor/github.com/coreos/etcd/etcdserver/stats/queue.go
deleted file mode 100644
index 635074c..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/stats/queue.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package stats
-
-import (
-	"sync"
-	"time"
-)
-
-const (
-	queueCapacity = 200
-)
-
-// RequestStats represent the stats for a request.
-// It encapsulates the sending time and the size of the request.
-type RequestStats struct {
-	SendingTime time.Time
-	Size        int
-}
-
-type statsQueue struct {
-	items        [queueCapacity]*RequestStats
-	size         int
-	front        int
-	back         int
-	totalReqSize int
-	rwl          sync.RWMutex
-}
-
-func (q *statsQueue) Len() int {
-	return q.size
-}
-
-func (q *statsQueue) ReqSize() int {
-	return q.totalReqSize
-}
-
-// FrontAndBack gets the front and back elements in the queue
-// We must grab front and back together with the protection of the lock
-func (q *statsQueue) frontAndBack() (*RequestStats, *RequestStats) {
-	q.rwl.RLock()
-	defer q.rwl.RUnlock()
-	if q.size != 0 {
-		return q.items[q.front], q.items[q.back]
-	}
-	return nil, nil
-}
-
-// Insert function insert a RequestStats into the queue and update the records
-func (q *statsQueue) Insert(p *RequestStats) {
-	q.rwl.Lock()
-	defer q.rwl.Unlock()
-
-	q.back = (q.back + 1) % queueCapacity
-
-	if q.size == queueCapacity { //dequeue
-		q.totalReqSize -= q.items[q.front].Size
-		q.front = (q.back + 1) % queueCapacity
-	} else {
-		q.size++
-	}
-
-	q.items[q.back] = p
-	q.totalReqSize += q.items[q.back].Size
-
-}
-
-// Rate function returns the package rate and byte rate
-func (q *statsQueue) Rate() (float64, float64) {
-	front, back := q.frontAndBack()
-
-	if front == nil || back == nil {
-		return 0, 0
-	}
-
-	if time.Since(back.SendingTime) > time.Second {
-		q.Clear()
-		return 0, 0
-	}
-
-	sampleDuration := back.SendingTime.Sub(front.SendingTime)
-
-	pr := float64(q.Len()) / float64(sampleDuration) * float64(time.Second)
-
-	br := float64(q.ReqSize()) / float64(sampleDuration) * float64(time.Second)
-
-	return pr, br
-}
-
-// Clear function clear up the statsQueue
-func (q *statsQueue) Clear() {
-	q.rwl.Lock()
-	defer q.rwl.Unlock()
-	q.back = -1
-	q.front = 0
-	q.size = 0
-	q.totalReqSize = 0
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/stats/server.go b/vendor/github.com/coreos/etcd/etcdserver/stats/server.go
deleted file mode 100644
index b026e44..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/stats/server.go
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package stats
-
-import (
-	"encoding/json"
-	"log"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/raft"
-)
-
-// ServerStats encapsulates various statistics about an EtcdServer and its
-// communication with other members of the cluster
-type ServerStats struct {
-	serverStats
-	sync.Mutex
-}
-
-func NewServerStats(name, id string) *ServerStats {
-	ss := &ServerStats{
-		serverStats: serverStats{
-			Name: name,
-			ID:   id,
-		},
-	}
-	now := time.Now()
-	ss.StartTime = now
-	ss.LeaderInfo.StartTime = now
-	ss.sendRateQueue = &statsQueue{back: -1}
-	ss.recvRateQueue = &statsQueue{back: -1}
-	return ss
-}
-
-type serverStats struct {
-	Name string `json:"name"`
-	// ID is the raft ID of the node.
-	// TODO(jonboulle): use ID instead of name?
-	ID        string         `json:"id"`
-	State     raft.StateType `json:"state"`
-	StartTime time.Time      `json:"startTime"`
-
-	LeaderInfo struct {
-		Name      string    `json:"leader"`
-		Uptime    string    `json:"uptime"`
-		StartTime time.Time `json:"startTime"`
-	} `json:"leaderInfo"`
-
-	RecvAppendRequestCnt uint64  `json:"recvAppendRequestCnt,"`
-	RecvingPkgRate       float64 `json:"recvPkgRate,omitempty"`
-	RecvingBandwidthRate float64 `json:"recvBandwidthRate,omitempty"`
-
-	SendAppendRequestCnt uint64  `json:"sendAppendRequestCnt"`
-	SendingPkgRate       float64 `json:"sendPkgRate,omitempty"`
-	SendingBandwidthRate float64 `json:"sendBandwidthRate,omitempty"`
-
-	sendRateQueue *statsQueue
-	recvRateQueue *statsQueue
-}
-
-func (ss *ServerStats) JSON() []byte {
-	ss.Lock()
-	stats := ss.serverStats
-	stats.SendingPkgRate, stats.SendingBandwidthRate = stats.sendRateQueue.Rate()
-	stats.RecvingPkgRate, stats.RecvingBandwidthRate = stats.recvRateQueue.Rate()
-	stats.LeaderInfo.Uptime = time.Since(stats.LeaderInfo.StartTime).String()
-	ss.Unlock()
-	b, err := json.Marshal(stats)
-	// TODO(jonboulle): appropriate error handling?
-	if err != nil {
-		log.Printf("stats: error marshalling server stats: %v", err)
-	}
-	return b
-}
-
-// RecvAppendReq updates the ServerStats in response to an AppendRequest
-// from the given leader being received
-func (ss *ServerStats) RecvAppendReq(leader string, reqSize int) {
-	ss.Lock()
-	defer ss.Unlock()
-
-	now := time.Now()
-
-	ss.State = raft.StateFollower
-	if leader != ss.LeaderInfo.Name {
-		ss.LeaderInfo.Name = leader
-		ss.LeaderInfo.StartTime = now
-	}
-
-	ss.recvRateQueue.Insert(
-		&RequestStats{
-			SendingTime: now,
-			Size:        reqSize,
-		},
-	)
-	ss.RecvAppendRequestCnt++
-}
-
-// SendAppendReq updates the ServerStats in response to an AppendRequest
-// being sent by this server
-func (ss *ServerStats) SendAppendReq(reqSize int) {
-	ss.Lock()
-	defer ss.Unlock()
-
-	ss.becomeLeader()
-
-	ss.sendRateQueue.Insert(
-		&RequestStats{
-			SendingTime: time.Now(),
-			Size:        reqSize,
-		},
-	)
-
-	ss.SendAppendRequestCnt++
-}
-
-func (ss *ServerStats) BecomeLeader() {
-	ss.Lock()
-	defer ss.Unlock()
-	ss.becomeLeader()
-}
-
-func (ss *ServerStats) becomeLeader() {
-	if ss.State != raft.StateLeader {
-		ss.State = raft.StateLeader
-		ss.LeaderInfo.Name = ss.ID
-		ss.LeaderInfo.StartTime = time.Now()
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/stats/stats.go b/vendor/github.com/coreos/etcd/etcdserver/stats/stats.go
deleted file mode 100644
index 2b5f707..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/stats/stats.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package stats defines a standard interface for etcd cluster statistics.
-package stats
-
-import "github.com/coreos/pkg/capnslog"
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver/stats")
-)
-
-type Stats interface {
-	// SelfStats returns the struct representing statistics of this server
-	SelfStats() []byte
-	// LeaderStats returns the statistics of all followers in the cluster
-	// if this server is leader. Otherwise, nil is returned.
-	LeaderStats() []byte
-	// StoreStats returns statistics of the store backing this EtcdServer
-	StoreStats() []byte
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/storage.go b/vendor/github.com/coreos/etcd/etcdserver/storage.go
deleted file mode 100644
index 55c2dd4..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/storage.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"io"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/pkg/pbutil"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/snap"
-	"github.com/coreos/etcd/wal"
-	"github.com/coreos/etcd/wal/walpb"
-)
-
-type Storage interface {
-	// Save function saves ents and state to the underlying stable storage.
-	// Save MUST block until st and ents are on stable storage.
-	Save(st raftpb.HardState, ents []raftpb.Entry) error
-	// SaveSnap function saves snapshot to the underlying stable storage.
-	SaveSnap(snap raftpb.Snapshot) error
-	// Close closes the Storage and performs finalization.
-	Close() error
-}
-
-type storage struct {
-	*wal.WAL
-	*snap.Snapshotter
-}
-
-func NewStorage(w *wal.WAL, s *snap.Snapshotter) Storage {
-	return &storage{w, s}
-}
-
-// SaveSnap saves the snapshot to disk and release the locked
-// wal files since they will not be used.
-func (st *storage) SaveSnap(snap raftpb.Snapshot) error {
-	walsnap := walpb.Snapshot{
-		Index: snap.Metadata.Index,
-		Term:  snap.Metadata.Term,
-	}
-	err := st.WAL.SaveSnapshot(walsnap)
-	if err != nil {
-		return err
-	}
-	err = st.Snapshotter.SaveSnap(snap)
-	if err != nil {
-		return err
-	}
-	return st.WAL.ReleaseLockTo(snap.Metadata.Index)
-}
-
-func readWAL(waldir string, snap walpb.Snapshot) (w *wal.WAL, id, cid types.ID, st raftpb.HardState, ents []raftpb.Entry) {
-	var (
-		err       error
-		wmetadata []byte
-	)
-
-	repaired := false
-	for {
-		if w, err = wal.Open(waldir, snap); err != nil {
-			plog.Fatalf("open wal error: %v", err)
-		}
-		if wmetadata, st, ents, err = w.ReadAll(); err != nil {
-			w.Close()
-			// we can only repair ErrUnexpectedEOF and we never repair twice.
-			if repaired || err != io.ErrUnexpectedEOF {
-				plog.Fatalf("read wal error (%v) and cannot be repaired", err)
-			}
-			if !wal.Repair(waldir) {
-				plog.Fatalf("WAL error (%v) cannot be repaired", err)
-			} else {
-				plog.Infof("repaired WAL error (%v)", err)
-				repaired = true
-			}
-			continue
-		}
-		break
-	}
-	var metadata pb.Metadata
-	pbutil.MustUnmarshal(&metadata, wmetadata)
-	id = types.ID(metadata.NodeID)
-	cid = types.ID(metadata.ClusterID)
-	return w, id, cid, st, ents
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/util.go b/vendor/github.com/coreos/etcd/etcdserver/util.go
deleted file mode 100644
index 79bb6b8..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/util.go
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-	"time"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/rafthttp"
-	"github.com/golang/protobuf/proto"
-)
-
-// isConnectedToQuorumSince checks whether the local member is connected to the
-// quorum of the cluster since the given time.
-func isConnectedToQuorumSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) bool {
-	return numConnectedSince(transport, since, self, members) >= (len(members)/2)+1
-}
-
-// isConnectedSince checks whether the local member is connected to the
-// remote member since the given time.
-func isConnectedSince(transport rafthttp.Transporter, since time.Time, remote types.ID) bool {
-	t := transport.ActiveSince(remote)
-	return !t.IsZero() && t.Before(since)
-}
-
-// isConnectedFullySince checks whether the local member is connected to all
-// members in the cluster since the given time.
-func isConnectedFullySince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) bool {
-	return numConnectedSince(transport, since, self, members) == len(members)
-}
-
-// numConnectedSince counts how many members are connected to the local member
-// since the given time.
-func numConnectedSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) int {
-	connectedNum := 0
-	for _, m := range members {
-		if m.ID == self || isConnectedSince(transport, since, m.ID) {
-			connectedNum++
-		}
-	}
-	return connectedNum
-}
-
-// longestConnected chooses the member with longest active-since-time.
-// It returns false, if nothing is active.
-func longestConnected(tp rafthttp.Transporter, membs []types.ID) (types.ID, bool) {
-	var longest types.ID
-	var oldest time.Time
-	for _, id := range membs {
-		tm := tp.ActiveSince(id)
-		if tm.IsZero() { // inactive
-			continue
-		}
-
-		if oldest.IsZero() { // first longest candidate
-			oldest = tm
-			longest = id
-		}
-
-		if tm.Before(oldest) {
-			oldest = tm
-			longest = id
-		}
-	}
-	if uint64(longest) == 0 {
-		return longest, false
-	}
-	return longest, true
-}
-
-type notifier struct {
-	c   chan struct{}
-	err error
-}
-
-func newNotifier() *notifier {
-	return &notifier{
-		c: make(chan struct{}),
-	}
-}
-
-func (nc *notifier) notify(err error) {
-	nc.err = err
-	close(nc.c)
-}
-
-func warnOfExpensiveRequest(now time.Time, reqStringer fmt.Stringer, respMsg proto.Message, err error) {
-	var resp string
-	if !isNil(respMsg) {
-		resp = fmt.Sprintf("size:%d", proto.Size(respMsg))
-	}
-	warnOfExpensiveGenericRequest(now, reqStringer, "", resp, err)
-}
-
-func warnOfExpensiveReadOnlyTxnRequest(now time.Time, r *pb.TxnRequest, txnResponse *pb.TxnResponse, err error) {
-	reqStringer := pb.NewLoggableTxnRequest(r)
-	var resp string
-	if !isNil(txnResponse) {
-		var resps []string
-		for _, r := range txnResponse.Responses {
-			switch op := r.Response.(type) {
-			case *pb.ResponseOp_ResponseRange:
-				resps = append(resps, fmt.Sprintf("range_response_count:%d", len(op.ResponseRange.Kvs)))
-			default:
-				// only range responses should be in a read only txn request
-			}
-		}
-		resp = fmt.Sprintf("responses:<%s> size:%d", strings.Join(resps, " "), proto.Size(txnResponse))
-	}
-	warnOfExpensiveGenericRequest(now, reqStringer, "read-only range ", resp, err)
-}
-
-func warnOfExpensiveReadOnlyRangeRequest(now time.Time, reqStringer fmt.Stringer, rangeResponse *pb.RangeResponse, err error) {
-	var resp string
-	if !isNil(rangeResponse) {
-		resp = fmt.Sprintf("range_response_count:%d size:%d", len(rangeResponse.Kvs), proto.Size(rangeResponse))
-	}
-	warnOfExpensiveGenericRequest(now, reqStringer, "read-only range ", resp, err)
-}
-
-func warnOfExpensiveGenericRequest(now time.Time, reqStringer fmt.Stringer, prefix string, resp string, err error) {
-	// TODO: add metrics
-	d := time.Since(now)
-	if d > warnApplyDuration {
-		var result string
-		if err != nil {
-			result = fmt.Sprintf("error:%v", err)
-		} else {
-			result = resp
-		}
-		plog.Warningf("%srequest %q with result %q took too long (%v) to execute", prefix, reqStringer.String(), result, d)
-		slowApplies.Inc()
-	}
-}
-
-func isNil(msg proto.Message) bool {
-	return msg == nil || reflect.ValueOf(msg).IsNil()
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/v2_server.go b/vendor/github.com/coreos/etcd/etcdserver/v2_server.go
deleted file mode 100644
index b458350..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/v2_server.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"context"
-	"time"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/store"
-)
-
-type RequestV2 pb.Request
-
-type RequestV2Handler interface {
-	Post(ctx context.Context, r *RequestV2) (Response, error)
-	Put(ctx context.Context, r *RequestV2) (Response, error)
-	Delete(ctx context.Context, r *RequestV2) (Response, error)
-	QGet(ctx context.Context, r *RequestV2) (Response, error)
-	Get(ctx context.Context, r *RequestV2) (Response, error)
-	Head(ctx context.Context, r *RequestV2) (Response, error)
-}
-
-type reqV2HandlerEtcdServer struct {
-	reqV2HandlerStore
-	s *EtcdServer
-}
-
-type reqV2HandlerStore struct {
-	store   store.Store
-	applier ApplierV2
-}
-
-func NewStoreRequestV2Handler(s store.Store, applier ApplierV2) RequestV2Handler {
-	return &reqV2HandlerStore{s, applier}
-}
-
-func (a *reqV2HandlerStore) Post(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.applier.Post(r), nil
-}
-
-func (a *reqV2HandlerStore) Put(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.applier.Put(r), nil
-}
-
-func (a *reqV2HandlerStore) Delete(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.applier.Delete(r), nil
-}
-
-func (a *reqV2HandlerStore) QGet(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.applier.QGet(r), nil
-}
-
-func (a *reqV2HandlerStore) Get(ctx context.Context, r *RequestV2) (Response, error) {
-	if r.Wait {
-		wc, err := a.store.Watch(r.Path, r.Recursive, r.Stream, r.Since)
-		return Response{Watcher: wc}, err
-	}
-	ev, err := a.store.Get(r.Path, r.Recursive, r.Sorted)
-	return Response{Event: ev}, err
-}
-
-func (a *reqV2HandlerStore) Head(ctx context.Context, r *RequestV2) (Response, error) {
-	ev, err := a.store.Get(r.Path, r.Recursive, r.Sorted)
-	return Response{Event: ev}, err
-}
-
-func (a *reqV2HandlerEtcdServer) Post(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.processRaftRequest(ctx, r)
-}
-
-func (a *reqV2HandlerEtcdServer) Put(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.processRaftRequest(ctx, r)
-}
-
-func (a *reqV2HandlerEtcdServer) Delete(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.processRaftRequest(ctx, r)
-}
-
-func (a *reqV2HandlerEtcdServer) QGet(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.processRaftRequest(ctx, r)
-}
-
-func (a *reqV2HandlerEtcdServer) processRaftRequest(ctx context.Context, r *RequestV2) (Response, error) {
-	data, err := ((*pb.Request)(r)).Marshal()
-	if err != nil {
-		return Response{}, err
-	}
-	ch := a.s.w.Register(r.ID)
-
-	start := time.Now()
-	a.s.r.Propose(ctx, data)
-	proposalsPending.Inc()
-	defer proposalsPending.Dec()
-
-	select {
-	case x := <-ch:
-		resp := x.(Response)
-		return resp, resp.Err
-	case <-ctx.Done():
-		proposalsFailed.Inc()
-		a.s.w.Trigger(r.ID, nil) // GC wait
-		return Response{}, a.s.parseProposeCtxErr(ctx.Err(), start)
-	case <-a.s.stopping:
-	}
-	return Response{}, ErrStopped
-}
-
-func (s *EtcdServer) Do(ctx context.Context, r pb.Request) (Response, error) {
-	r.ID = s.reqIDGen.Next()
-	h := &reqV2HandlerEtcdServer{
-		reqV2HandlerStore: reqV2HandlerStore{
-			store:   s.store,
-			applier: s.applyV2,
-		},
-		s: s,
-	}
-	rp := &r
-	resp, err := ((*RequestV2)(rp)).Handle(ctx, h)
-	resp.Term, resp.Index = s.Term(), s.Index()
-	return resp, err
-}
-
-// Handle interprets r and performs an operation on s.store according to r.Method
-// and other fields. If r.Method is "POST", "PUT", "DELETE", or a "GET" with
-// Quorum == true, r will be sent through consensus before performing its
-// respective operation. Do will block until an action is performed or there is
-// an error.
-func (r *RequestV2) Handle(ctx context.Context, v2api RequestV2Handler) (Response, error) {
-	if r.Method == "GET" && r.Quorum {
-		r.Method = "QGET"
-	}
-	switch r.Method {
-	case "POST":
-		return v2api.Post(ctx, r)
-	case "PUT":
-		return v2api.Put(ctx, r)
-	case "DELETE":
-		return v2api.Delete(ctx, r)
-	case "QGET":
-		return v2api.QGet(ctx, r)
-	case "GET":
-		return v2api.Get(ctx, r)
-	case "HEAD":
-		return v2api.Head(ctx, r)
-	}
-	return Response{}, ErrUnknownMethod
-}
-
-func (r *RequestV2) String() string {
-	rpb := pb.Request(*r)
-	return rpb.String()
-}
diff --git a/vendor/github.com/coreos/etcd/etcdserver/v3_server.go b/vendor/github.com/coreos/etcd/etcdserver/v3_server.go
deleted file mode 100644
index f214a19..0000000
--- a/vendor/github.com/coreos/etcd/etcdserver/v3_server.go
+++ /dev/null
@@ -1,720 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package etcdserver
-
-import (
-	"bytes"
-	"context"
-	"encoding/binary"
-	"time"
-
-	"github.com/coreos/etcd/auth"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/etcdserver/membership"
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/lease/leasehttp"
-	"github.com/coreos/etcd/mvcc"
-	"github.com/coreos/etcd/raft"
-
-	"github.com/gogo/protobuf/proto"
-)
-
-const (
-	// In the health case, there might be a small gap (10s of entries) between
-	// the applied index and committed index.
-	// However, if the committed entries are very heavy to apply, the gap might grow.
-	// We should stop accepting new proposals if the gap growing to a certain point.
-	maxGapBetweenApplyAndCommitIndex = 5000
-)
-
-type RaftKV interface {
-	Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error)
-	Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error)
-	DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error)
-	Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error)
-	Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error)
-}
-
-type Lessor interface {
-	// LeaseGrant sends LeaseGrant request to raft and apply it after committed.
-	LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error)
-	// LeaseRevoke sends LeaseRevoke request to raft and apply it after committed.
-	LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error)
-
-	// LeaseRenew renews the lease with given ID. The renewed TTL is returned. Or an error
-	// is returned.
-	LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, error)
-
-	// LeaseTimeToLive retrieves lease information.
-	LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error)
-
-	// LeaseLeases lists all leases.
-	LeaseLeases(ctx context.Context, r *pb.LeaseLeasesRequest) (*pb.LeaseLeasesResponse, error)
-}
-
-type Authenticator interface {
-	AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error)
-	AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error)
-	Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error)
-	UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
-	UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
-	UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error)
-	UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error)
-	UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error)
-	UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error)
-	RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error)
-	RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error)
-	RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error)
-	RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error)
-	RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error)
-	UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error)
-	RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error)
-}
-
-func (s *EtcdServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) {
-	var resp *pb.RangeResponse
-	var err error
-	defer func(start time.Time) {
-		warnOfExpensiveReadOnlyRangeRequest(start, r, resp, err)
-	}(time.Now())
-
-	if !r.Serializable {
-		err = s.linearizableReadNotify(ctx)
-		if err != nil {
-			return nil, err
-		}
-	}
-	chk := func(ai *auth.AuthInfo) error {
-		return s.authStore.IsRangePermitted(ai, r.Key, r.RangeEnd)
-	}
-
-	get := func() { resp, err = s.applyV3Base.Range(nil, r) }
-	if serr := s.doSerialize(ctx, chk, get); serr != nil {
-		err = serr
-		return nil, err
-	}
-	return resp, err
-}
-
-func (s *EtcdServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{Put: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.PutResponse), nil
-}
-
-func (s *EtcdServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{DeleteRange: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.DeleteRangeResponse), nil
-}
-
-func (s *EtcdServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) {
-	if isTxnReadonly(r) {
-		if !isTxnSerializable(r) {
-			err := s.linearizableReadNotify(ctx)
-			if err != nil {
-				return nil, err
-			}
-		}
-		var resp *pb.TxnResponse
-		var err error
-		chk := func(ai *auth.AuthInfo) error {
-			return checkTxnAuth(s.authStore, ai, r)
-		}
-
-		defer func(start time.Time) {
-			warnOfExpensiveReadOnlyTxnRequest(start, r, resp, err)
-		}(time.Now())
-
-		get := func() { resp, err = s.applyV3Base.Txn(r) }
-		if serr := s.doSerialize(ctx, chk, get); serr != nil {
-			return nil, serr
-		}
-		return resp, err
-	}
-
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{Txn: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.TxnResponse), nil
-}
-
-func isTxnSerializable(r *pb.TxnRequest) bool {
-	for _, u := range r.Success {
-		if r := u.GetRequestRange(); r == nil || !r.Serializable {
-			return false
-		}
-	}
-	for _, u := range r.Failure {
-		if r := u.GetRequestRange(); r == nil || !r.Serializable {
-			return false
-		}
-	}
-	return true
-}
-
-func isTxnReadonly(r *pb.TxnRequest) bool {
-	for _, u := range r.Success {
-		if r := u.GetRequestRange(); r == nil {
-			return false
-		}
-	}
-	for _, u := range r.Failure {
-		if r := u.GetRequestRange(); r == nil {
-			return false
-		}
-	}
-	return true
-}
-
-func (s *EtcdServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) {
-	result, err := s.processInternalRaftRequestOnce(ctx, pb.InternalRaftRequest{Compaction: r})
-	if r.Physical && result != nil && result.physc != nil {
-		<-result.physc
-		// The compaction is done deleting keys; the hash is now settled
-		// but the data is not necessarily committed. If there's a crash,
-		// the hash may revert to a hash prior to compaction completing
-		// if the compaction resumes. Force the finished compaction to
-		// commit so it won't resume following a crash.
-		s.be.ForceCommit()
-	}
-	if err != nil {
-		return nil, err
-	}
-	if result.err != nil {
-		return nil, result.err
-	}
-	resp := result.resp.(*pb.CompactionResponse)
-	if resp == nil {
-		resp = &pb.CompactionResponse{}
-	}
-	if resp.Header == nil {
-		resp.Header = &pb.ResponseHeader{}
-	}
-	resp.Header.Revision = s.kv.Rev()
-	return resp, nil
-}
-
-func (s *EtcdServer) LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	// no id given? choose one
-	for r.ID == int64(lease.NoLease) {
-		// only use positive int64 id's
-		r.ID = int64(s.reqIDGen.Next() & ((1 << 63) - 1))
-	}
-	resp, err := s.raftRequestOnce(ctx, pb.InternalRaftRequest{LeaseGrant: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.LeaseGrantResponse), nil
-}
-
-func (s *EtcdServer) LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	resp, err := s.raftRequestOnce(ctx, pb.InternalRaftRequest{LeaseRevoke: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.LeaseRevokeResponse), nil
-}
-
-func (s *EtcdServer) LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, error) {
-	ttl, err := s.lessor.Renew(id)
-	if err == nil { // already requested to primary lessor(leader)
-		return ttl, nil
-	}
-	if err != lease.ErrNotPrimary {
-		return -1, err
-	}
-
-	cctx, cancel := context.WithTimeout(ctx, s.Cfg.ReqTimeout())
-	defer cancel()
-
-	// renewals don't go through raft; forward to leader manually
-	for cctx.Err() == nil && err != nil {
-		leader, lerr := s.waitLeader(cctx)
-		if lerr != nil {
-			return -1, lerr
-		}
-		for _, url := range leader.PeerURLs {
-			lurl := url + leasehttp.LeasePrefix
-			ttl, err = leasehttp.RenewHTTP(cctx, id, lurl, s.peerRt)
-			if err == nil || err == lease.ErrLeaseNotFound {
-				return ttl, err
-			}
-		}
-	}
-	return -1, ErrTimeout
-}
-
-func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) {
-	if s.Leader() == s.ID() {
-		// primary; timetolive directly from leader
-		le := s.lessor.Lookup(lease.LeaseID(r.ID))
-		if le == nil {
-			return nil, lease.ErrLeaseNotFound
-		}
-		// TODO: fill out ResponseHeader
-		resp := &pb.LeaseTimeToLiveResponse{Header: &pb.ResponseHeader{}, ID: r.ID, TTL: int64(le.Remaining().Seconds()), GrantedTTL: le.TTL()}
-		if r.Keys {
-			ks := le.Keys()
-			kbs := make([][]byte, len(ks))
-			for i := range ks {
-				kbs[i] = []byte(ks[i])
-			}
-			resp.Keys = kbs
-		}
-		return resp, nil
-	}
-
-	cctx, cancel := context.WithTimeout(ctx, s.Cfg.ReqTimeout())
-	defer cancel()
-
-	// forward to leader
-	for cctx.Err() == nil {
-		leader, err := s.waitLeader(cctx)
-		if err != nil {
-			return nil, err
-		}
-		for _, url := range leader.PeerURLs {
-			lurl := url + leasehttp.LeaseInternalPrefix
-			resp, err := leasehttp.TimeToLiveHTTP(cctx, lease.LeaseID(r.ID), r.Keys, lurl, s.peerRt)
-			if err == nil {
-				return resp.LeaseTimeToLiveResponse, nil
-			}
-			if err == lease.ErrLeaseNotFound {
-				return nil, err
-			}
-		}
-	}
-	return nil, ErrTimeout
-}
-
-func (s *EtcdServer) LeaseLeases(ctx context.Context, r *pb.LeaseLeasesRequest) (*pb.LeaseLeasesResponse, error) {
-	ls := s.lessor.Leases()
-	lss := make([]*pb.LeaseStatus, len(ls))
-	for i := range ls {
-		lss[i] = &pb.LeaseStatus{ID: int64(ls[i].ID)}
-	}
-	return &pb.LeaseLeasesResponse{Header: newHeader(s), Leases: lss}, nil
-}
-
-func (s *EtcdServer) waitLeader(ctx context.Context) (*membership.Member, error) {
-	leader := s.cluster.Member(s.Leader())
-	for leader == nil {
-		// wait an election
-		dur := time.Duration(s.Cfg.ElectionTicks) * time.Duration(s.Cfg.TickMs) * time.Millisecond
-		select {
-		case <-time.After(dur):
-			leader = s.cluster.Member(s.Leader())
-		case <-s.stopping:
-			return nil, ErrStopped
-		case <-ctx.Done():
-			return nil, ErrNoLeader
-		}
-	}
-	if leader == nil || len(leader.PeerURLs) == 0 {
-		return nil, ErrNoLeader
-	}
-	return leader, nil
-}
-
-func (s *EtcdServer) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb.AlarmResponse, error) {
-	resp, err := s.raftRequestOnce(ctx, pb.InternalRaftRequest{Alarm: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AlarmResponse), nil
-}
-
-func (s *EtcdServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) {
-	resp, err := s.raftRequestOnce(ctx, pb.InternalRaftRequest{AuthEnable: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthEnableResponse), nil
-}
-
-func (s *EtcdServer) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthDisable: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthDisableResponse), nil
-}
-
-func (s *EtcdServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
-	if err := s.linearizableReadNotify(ctx); err != nil {
-		return nil, err
-	}
-
-	var resp proto.Message
-	for {
-		checkedRevision, err := s.AuthStore().CheckPassword(r.Name, r.Password)
-		if err != nil {
-			if err != auth.ErrAuthNotEnabled {
-				plog.Errorf("invalid authentication request to user %s was issued", r.Name)
-			}
-			return nil, err
-		}
-
-		st, err := s.AuthStore().GenTokenPrefix()
-		if err != nil {
-			return nil, err
-		}
-
-		internalReq := &pb.InternalAuthenticateRequest{
-			Name:        r.Name,
-			Password:    r.Password,
-			SimpleToken: st,
-		}
-
-		resp, err = s.raftRequestOnce(ctx, pb.InternalRaftRequest{Authenticate: internalReq})
-		if err != nil {
-			return nil, err
-		}
-		if checkedRevision == s.AuthStore().Revision() {
-			break
-		}
-		plog.Infof("revision when password checked is obsolete, retrying")
-	}
-
-	return resp.(*pb.AuthenticateResponse), nil
-}
-
-func (s *EtcdServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserAdd: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserAddResponse), nil
-}
-
-func (s *EtcdServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserDelete: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserDeleteResponse), nil
-}
-
-func (s *EtcdServer) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserChangePassword: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserChangePasswordResponse), nil
-}
-
-func (s *EtcdServer) UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserGrantRole: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserGrantRoleResponse), nil
-}
-
-func (s *EtcdServer) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserGet: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserGetResponse), nil
-}
-
-func (s *EtcdServer) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserList: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserListResponse), nil
-}
-
-func (s *EtcdServer) UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserRevokeRole: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserRevokeRoleResponse), nil
-}
-
-func (s *EtcdServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleAdd: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleAddResponse), nil
-}
-
-func (s *EtcdServer) RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleGrantPermission: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleGrantPermissionResponse), nil
-}
-
-func (s *EtcdServer) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleGet: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleGetResponse), nil
-}
-
-func (s *EtcdServer) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleList: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleListResponse), nil
-}
-
-func (s *EtcdServer) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleRevokePermission: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleRevokePermissionResponse), nil
-}
-
-func (s *EtcdServer) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleDelete: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleDeleteResponse), nil
-}
-
-func (s *EtcdServer) raftRequestOnce(ctx context.Context, r pb.InternalRaftRequest) (proto.Message, error) {
-	result, err := s.processInternalRaftRequestOnce(ctx, r)
-	if err != nil {
-		return nil, err
-	}
-	if result.err != nil {
-		return nil, result.err
-	}
-	return result.resp, nil
-}
-
-func (s *EtcdServer) raftRequest(ctx context.Context, r pb.InternalRaftRequest) (proto.Message, error) {
-	for {
-		resp, err := s.raftRequestOnce(ctx, r)
-		if err != auth.ErrAuthOldRevision {
-			return resp, err
-		}
-	}
-}
-
-// doSerialize handles the auth logic, with permissions checked by "chk", for a serialized request "get". Returns a non-nil error on authentication failure.
-func (s *EtcdServer) doSerialize(ctx context.Context, chk func(*auth.AuthInfo) error, get func()) error {
-	for {
-		ai, err := s.AuthInfoFromCtx(ctx)
-		if err != nil {
-			return err
-		}
-		if ai == nil {
-			// chk expects non-nil AuthInfo; use empty credentials
-			ai = &auth.AuthInfo{}
-		}
-		if err = chk(ai); err != nil {
-			if err == auth.ErrAuthOldRevision {
-				continue
-			}
-			return err
-		}
-		// fetch response for serialized request
-		get()
-		//  empty credentials or current auth info means no need to retry
-		if ai.Revision == 0 || ai.Revision == s.authStore.Revision() {
-			return nil
-		}
-		// avoid TOCTOU error, retry of the request is required.
-	}
-}
-
-func (s *EtcdServer) processInternalRaftRequestOnce(ctx context.Context, r pb.InternalRaftRequest) (*applyResult, error) {
-	ai := s.getAppliedIndex()
-	ci := s.getCommittedIndex()
-	if ci > ai+maxGapBetweenApplyAndCommitIndex {
-		return nil, ErrTooManyRequests
-	}
-
-	r.Header = &pb.RequestHeader{
-		ID: s.reqIDGen.Next(),
-	}
-
-	authInfo, err := s.AuthInfoFromCtx(ctx)
-	if err != nil {
-		return nil, err
-	}
-	if authInfo != nil {
-		r.Header.Username = authInfo.Username
-		r.Header.AuthRevision = authInfo.Revision
-	}
-
-	data, err := r.Marshal()
-	if err != nil {
-		return nil, err
-	}
-
-	if len(data) > int(s.Cfg.MaxRequestBytes) {
-		return nil, ErrRequestTooLarge
-	}
-
-	id := r.ID
-	if id == 0 {
-		id = r.Header.ID
-	}
-	ch := s.w.Register(id)
-
-	cctx, cancel := context.WithTimeout(ctx, s.Cfg.ReqTimeout())
-	defer cancel()
-
-	start := time.Now()
-	s.r.Propose(cctx, data)
-	proposalsPending.Inc()
-	defer proposalsPending.Dec()
-
-	select {
-	case x := <-ch:
-		return x.(*applyResult), nil
-	case <-cctx.Done():
-		proposalsFailed.Inc()
-		s.w.Trigger(id, nil) // GC wait
-		return nil, s.parseProposeCtxErr(cctx.Err(), start)
-	case <-s.done:
-		return nil, ErrStopped
-	}
-}
-
-// Watchable returns a watchable interface attached to the etcdserver.
-func (s *EtcdServer) Watchable() mvcc.WatchableKV { return s.KV() }
-
-func (s *EtcdServer) linearizableReadLoop() {
-	var rs raft.ReadState
-
-	for {
-		ctxToSend := make([]byte, 8)
-		id1 := s.reqIDGen.Next()
-		binary.BigEndian.PutUint64(ctxToSend, id1)
-
-		select {
-		case <-s.readwaitc:
-		case <-s.stopping:
-			return
-		}
-
-		nextnr := newNotifier()
-
-		s.readMu.Lock()
-		nr := s.readNotifier
-		s.readNotifier = nextnr
-		s.readMu.Unlock()
-
-		cctx, cancel := context.WithTimeout(context.Background(), s.Cfg.ReqTimeout())
-		if err := s.r.ReadIndex(cctx, ctxToSend); err != nil {
-			cancel()
-			if err == raft.ErrStopped {
-				return
-			}
-			plog.Errorf("failed to get read index from raft: %v", err)
-			readIndexFailed.Inc()
-			nr.notify(err)
-			continue
-		}
-		cancel()
-
-		var (
-			timeout bool
-			done    bool
-		)
-		for !timeout && !done {
-			select {
-			case rs = <-s.r.readStateC:
-				done = bytes.Equal(rs.RequestCtx, ctxToSend)
-				if !done {
-					// a previous request might time out. now we should ignore the response of it and
-					// continue waiting for the response of the current requests.
-					id2 := uint64(0)
-					if len(rs.RequestCtx) == 8 {
-						id2 = binary.BigEndian.Uint64(rs.RequestCtx)
-					}
-					plog.Warningf("ignored out-of-date read index response; local node read indexes queueing up and waiting to be in sync with leader (request ID want %d, got %d)", id1, id2)
-					slowReadIndex.Inc()
-				}
-
-			case <-time.After(s.Cfg.ReqTimeout()):
-				plog.Warningf("timed out waiting for read index response (local node might have slow network)")
-				nr.notify(ErrTimeout)
-				timeout = true
-				slowReadIndex.Inc()
-
-			case <-s.stopping:
-				return
-			}
-		}
-		if !done {
-			continue
-		}
-
-		if ai := s.getAppliedIndex(); ai < rs.Index {
-			select {
-			case <-s.applyWait.Wait(rs.Index):
-			case <-s.stopping:
-				return
-			}
-		}
-		// unblock all l-reads requested at indices before rs.Index
-		nr.notify(nil)
-	}
-}
-
-func (s *EtcdServer) linearizableReadNotify(ctx context.Context) error {
-	s.readMu.RLock()
-	nc := s.readNotifier
-	s.readMu.RUnlock()
-
-	// signal linearizable loop for current notify if it hasn't been already
-	select {
-	case s.readwaitc <- struct{}{}:
-	default:
-	}
-
-	// wait for read state notification
-	select {
-	case <-nc.c:
-		return nc.err
-	case <-ctx.Done():
-		return ctx.Err()
-	case <-s.done:
-		return ErrStopped
-	}
-}
-
-func (s *EtcdServer) AuthInfoFromCtx(ctx context.Context) (*auth.AuthInfo, error) {
-	authInfo, err := s.AuthStore().AuthInfoFromCtx(ctx)
-	if authInfo != nil || err != nil {
-		return authInfo, err
-	}
-	if !s.Cfg.ClientCertAuthEnabled {
-		return nil, nil
-	}
-	authInfo = s.AuthStore().AuthInfoFromTLS(ctx)
-	return authInfo, nil
-}
diff --git a/vendor/github.com/coreos/etcd/functional.yaml b/vendor/github.com/coreos/etcd/functional.yaml
deleted file mode 100644
index 2029a01..0000000
--- a/vendor/github.com/coreos/etcd/functional.yaml
+++ /dev/null
@@ -1,206 +0,0 @@
-agent-configs:
-- etcd-exec-path: ./bin/etcd
-  agent-addr: 127.0.0.1:19027
-  failpoint-http-addr: http://127.0.0.1:7381
-  base-dir: /tmp/etcd-functional-1
-  etcd-log-path: /tmp/etcd-functional-1/etcd.log
-  etcd-client-proxy: false
-  etcd-peer-proxy: true
-  etcd-client-endpoint: 127.0.0.1:1379
-  etcd:
-    name: s1
-    data-dir: /tmp/etcd-functional-1/etcd.data
-    wal-dir: /tmp/etcd-functional-1/etcd.data/member/wal
-    heartbeat-interval: 100
-    election-timeout: 1000
-    listen-client-urls: ["https://127.0.0.1:1379"]
-    advertise-client-urls: ["https://127.0.0.1:1379"]
-    auto-tls: true
-    client-cert-auth: false
-    cert-file: ""
-    key-file: ""
-    trusted-ca-file: ""
-    listen-peer-urls: ["https://127.0.0.1:1380"]
-    initial-advertise-peer-urls: ["https://127.0.0.1:1381"]
-    peer-auto-tls: true
-    peer-client-cert-auth: false
-    peer-cert-file: ""
-    peer-key-file: ""
-    peer-trusted-ca-file: ""
-    initial-cluster: s1=https://127.0.0.1:1381,s2=https://127.0.0.1:2381,s3=https://127.0.0.1:3381
-    initial-cluster-state: new
-    initial-cluster-token: tkn
-    snapshot-count: 10000
-    quota-backend-bytes: 10740000000 # 10 GiB
-    pre-vote: true
-    initial-corrupt-check: true
-  client-cert-data: ""
-  client-cert-path: ""
-  client-key-data: ""
-  client-key-path: ""
-  client-trusted-ca-data: ""
-  client-trusted-ca-path: ""
-  peer-cert-data: ""
-  peer-cert-path: ""
-  peer-key-data: ""
-  peer-key-path: ""
-  peer-trusted-ca-data: ""
-  peer-trusted-ca-path: ""
-  snapshot-path: /tmp/etcd-functional-1.snapshot.db
-
-- etcd-exec-path: ./bin/etcd
-  agent-addr: 127.0.0.1:29027
-  failpoint-http-addr: http://127.0.0.1:7382
-  base-dir: /tmp/etcd-functional-2
-  etcd-log-path: /tmp/etcd-functional-2/etcd.log
-  etcd-client-proxy: false
-  etcd-peer-proxy: true
-  etcd-client-endpoint: 127.0.0.1:2379
-  etcd:
-    name: s2
-    data-dir: /tmp/etcd-functional-2/etcd.data
-    wal-dir: /tmp/etcd-functional-2/etcd.data/member/wal
-    heartbeat-interval: 100
-    election-timeout: 1000
-    listen-client-urls: ["https://127.0.0.1:2379"]
-    advertise-client-urls: ["https://127.0.0.1:2379"]
-    auto-tls: true
-    client-cert-auth: false
-    cert-file: ""
-    key-file: ""
-    trusted-ca-file: ""
-    listen-peer-urls: ["https://127.0.0.1:2380"]
-    initial-advertise-peer-urls: ["https://127.0.0.1:2381"]
-    peer-auto-tls: true
-    peer-client-cert-auth: false
-    peer-cert-file: ""
-    peer-key-file: ""
-    peer-trusted-ca-file: ""
-    initial-cluster: s1=https://127.0.0.1:1381,s2=https://127.0.0.1:2381,s3=https://127.0.0.1:3381
-    initial-cluster-state: new
-    initial-cluster-token: tkn
-    snapshot-count: 10000
-    quota-backend-bytes: 10740000000 # 10 GiB
-    pre-vote: true
-    initial-corrupt-check: true
-  client-cert-data: ""
-  client-cert-path: ""
-  client-key-data: ""
-  client-key-path: ""
-  client-trusted-ca-data: ""
-  client-trusted-ca-path: ""
-  peer-cert-data: ""
-  peer-cert-path: ""
-  peer-key-data: ""
-  peer-key-path: ""
-  peer-trusted-ca-data: ""
-  peer-trusted-ca-path: ""
-  snapshot-path: /tmp/etcd-functional-2.snapshot.db
-
-- etcd-exec-path: ./bin/etcd
-  agent-addr: 127.0.0.1:39027
-  failpoint-http-addr: http://127.0.0.1:7383
-  base-dir: /tmp/etcd-functional-3
-  etcd-log-path: /tmp/etcd-functional-3/etcd.log
-  etcd-client-proxy: false
-  etcd-peer-proxy: true
-  etcd-client-endpoint: 127.0.0.1:3379
-  etcd:
-    name: s3
-    data-dir: /tmp/etcd-functional-3/etcd.data
-    wal-dir: /tmp/etcd-functional-3/etcd.data/member/wal
-    heartbeat-interval: 100
-    election-timeout: 1000
-    listen-client-urls: ["https://127.0.0.1:3379"]
-    advertise-client-urls: ["https://127.0.0.1:3379"]
-    auto-tls: true
-    client-cert-auth: false
-    cert-file: ""
-    key-file: ""
-    trusted-ca-file: ""
-    listen-peer-urls: ["https://127.0.0.1:3380"]
-    initial-advertise-peer-urls: ["https://127.0.0.1:3381"]
-    peer-auto-tls: true
-    peer-client-cert-auth: false
-    peer-cert-file: ""
-    peer-key-file: ""
-    peer-trusted-ca-file: ""
-    initial-cluster: s1=https://127.0.0.1:1381,s2=https://127.0.0.1:2381,s3=https://127.0.0.1:3381
-    initial-cluster-state: new
-    initial-cluster-token: tkn
-    snapshot-count: 10000
-    quota-backend-bytes: 10740000000 # 10 GiB
-    pre-vote: true
-    initial-corrupt-check: true
-  client-cert-data: ""
-  client-cert-path: ""
-  client-key-data: ""
-  client-key-path: ""
-  client-trusted-ca-data: ""
-  client-trusted-ca-path: ""
-  peer-cert-data: ""
-  peer-cert-path: ""
-  peer-key-data: ""
-  peer-key-path: ""
-  peer-trusted-ca-data: ""
-  peer-trusted-ca-path: ""
-  snapshot-path: /tmp/etcd-functional-3.snapshot.db
-
-tester-config:
-  data-dir: /tmp/etcd-tester-data
-  network: tcp
-  addr: 127.0.0.1:9028
-
-  # slow enough to trigger election
-  delay-latency-ms: 5000
-  delay-latency-ms-rv: 500
-
-  round-limit: 1
-  exit-on-failure: true
-  enable-pprof: true
-
-  case-delay-ms: 7000
-  case-shuffle: true
-
-  # For full descriptions,
-  # https://godoc.org/github.com/coreos/etcd/functional/rpcpb#Case
-  cases:
-  - SIGTERM_ONE_FOLLOWER
-  - SIGTERM_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT
-  - SIGTERM_LEADER
-  - SIGTERM_LEADER_UNTIL_TRIGGER_SNAPSHOT
-  - SIGTERM_QUORUM
-  - SIGTERM_ALL
-  - SIGQUIT_AND_REMOVE_ONE_FOLLOWER
-  - SIGQUIT_AND_REMOVE_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT
-  - BLACKHOLE_PEER_PORT_TX_RX_ONE_FOLLOWER
-  - BLACKHOLE_PEER_PORT_TX_RX_ONE_FOLLOWER_UNTIL_TRIGGER_SNAPSHOT
-  - BLACKHOLE_PEER_PORT_TX_RX_LEADER
-  - BLACKHOLE_PEER_PORT_TX_RX_LEADER_UNTIL_TRIGGER_SNAPSHOT
-  - BLACKHOLE_PEER_PORT_TX_RX_QUORUM
-  - DELAY_PEER_PORT_TX_RX_ONE_FOLLOWER
-  - DELAY_PEER_PORT_TX_RX_LEADER
-  - DELAY_PEER_PORT_TX_RX_QUORUM
-
-  failpoint-commands:
-  - panic("etcd-tester")
-
-  runner-exec-path: ./bin/etcd-runner
-  external-exec-path: ""
-
-  stressers:
-  - KV
-  - LEASE
-
-  checkers:
-  - KV_HASH
-  - LEASE_EXPIRE
-
-  stress-key-size: 100
-  stress-key-size-large: 32769
-  stress-key-suffix-range: 250000
-  stress-key-suffix-range-txn: 100
-  stress-key-txn-ops: 10
-
-  stress-clients: 100
-  stress-qps: 2000
diff --git a/vendor/github.com/coreos/etcd/glide.lock b/vendor/github.com/coreos/etcd/glide.lock
deleted file mode 100644
index 4554c84..0000000
--- a/vendor/github.com/coreos/etcd/glide.lock
+++ /dev/null
@@ -1,199 +0,0 @@
-hash: f0697416d74e4c0fb9d6471c39c3e005ecdeccc8a864c1b0b65e0087b3242027
-updated: 2018-04-10T23:45:04.40596807-07:00
-imports:
-- name: github.com/beorn7/perks
-  version: 3a771d992973f24aa725d07868b467d1ddfceafb
-  subpackages:
-  - quantile
-- name: github.com/bgentry/speakeasy
-  version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd
-- name: github.com/coreos/bbolt
-  version: 48ea1b39c25fc1bab3506fbc712ecbaa842c4d2d
-- name: github.com/coreos/go-semver
-  version: 8ab6407b697782a06568d4b7f1db25550ec2e4c6
-  subpackages:
-  - semver
-- name: github.com/coreos/go-systemd
-  version: d2196463941895ee908e13531a23a39feb9e1243
-  subpackages:
-  - daemon
-  - journal
-  - util
-- name: github.com/coreos/pkg
-  version: 3ac0863d7acf3bc44daf49afef8919af12f704ef
-  subpackages:
-  - capnslog
-  - dlopen
-- name: github.com/cpuguy83/go-md2man
-  version: 23709d0847197db6021a51fdb193e66e9222d4e7
-  subpackages:
-  - md2man
-- name: github.com/dgrijalva/jwt-go
-  version: d2709f9f1f31ebcda9651b03077758c1f3a0018c
-- name: github.com/dustin/go-humanize
-  version: bb3d318650d48840a39aa21a027c6630e198e626
-- name: github.com/ghodss/yaml
-  version: 0ca9ea5df5451ffdf184b4428c902747c2c11cd7
-- name: github.com/gogo/protobuf
-  version: 342cbe0a04158f6dcb03ca0079991a51a4248c02
-  subpackages:
-  - gogoproto
-  - proto
-  - protoc-gen-gogo/descriptor
-- name: github.com/golang/groupcache
-  version: 02826c3e79038b59d737d3b1c0a1d937f71a4433
-  subpackages:
-  - lru
-- name: github.com/golang/protobuf
-  version: 1e59b77b52bf8e4b449a57e6f79f21226d571845
-  subpackages:
-  - jsonpb
-  - proto
-  - ptypes
-  - ptypes/any
-  - ptypes/duration
-  - ptypes/struct
-  - ptypes/timestamp
-- name: github.com/google/btree
-  version: 925471ac9e2131377a91e1595defec898166fe49
-- name: github.com/gorilla/websocket
-  version: 4201258b820c74ac8e6922fc9e6b52f71fe46f8d
-- name: github.com/grpc-ecosystem/go-grpc-prometheus
-  version: 0dafe0d496ea71181bf2dd039e7e3f44b6bd11a7
-- name: github.com/grpc-ecosystem/grpc-gateway
-  version: 8cc3a55af3bcf171a1c23a90c4df9cf591706104
-  subpackages:
-  - runtime
-  - runtime/internal
-  - utilities
-- name: github.com/inconshreveable/mousetrap
-  version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
-- name: github.com/jonboulle/clockwork
-  version: 2eee05ed794112d45db504eb05aa693efd2b8b09
-- name: github.com/kr/pty
-  version: 2c10821df3c3cf905230d078702dfbe9404c9b23
-- name: github.com/mattn/go-runewidth
-  version: 9e777a8366cce605130a531d2cd6363d07ad7317
-  subpackages:
-  - runewidth.go
-- name: github.com/matttproud/golang_protobuf_extensions
-  version: c12348ce28de40eed0136aa2b644d0ee0650e56c
-  subpackages:
-  - pbutil
-- name: github.com/olekukonko/tablewriter
-  version: a0225b3f23b5ce0cbec6d7a66a968f8a59eca9c4
-- name: github.com/prometheus/client_golang
-  version: 5cec1d0429b02e4323e042eb04dafdb079ddf568
-  subpackages:
-  - prometheus
-  - prometheus/promhttp
-- name: github.com/prometheus/client_model
-  version: 6f3806018612930941127f2a7c6c453ba2c527d2
-  subpackages:
-  - go
-- name: github.com/prometheus/common
-  version: e3fb1a1acd7605367a2b378bc2e2f893c05174b7
-  subpackages:
-  - expfmt
-  - internal/bitbucket.org/ww/goautoneg
-  - model
-- name: github.com/prometheus/procfs
-  version: a6e9df898b1336106c743392c48ee0b71f5c4efa
-  subpackages:
-  - xfs
-- name: github.com/russross/blackfriday
-  version: 4048872b16cc0fc2c5fd9eacf0ed2c2fedaa0c8c
-- name: github.com/sirupsen/logrus
-  version: f006c2ac4710855cf0f916dd6b77acf6b048dc6e
-- name: github.com/soheilhy/cmux
-  version: bb79a83465015a27a175925ebd155e660f55e9f1
-- name: github.com/spf13/cobra
-  version: 1c44ec8d3f1552cac48999f9306da23c4d8a288b
-- name: github.com/spf13/pflag
-  version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
-- name: github.com/tmc/grpc-websocket-proxy
-  version: 89b8d40f7ca833297db804fcb3be53a76d01c238
-  subpackages:
-  - wsproxy
-- name: github.com/ugorji/go
-  version: bdcc60b419d136a85cdf2e7cbcac34b3f1cd6e57
-  subpackages:
-  - codec
-- name: github.com/urfave/cli
-  version: 1efa31f08b9333f1bd4882d61f9d668a70cd902e
-- name: github.com/xiang90/probing
-  version: 07dd2e8dfe18522e9c447ba95f2fe95262f63bb2
-- name: go.uber.org/atomic
-  version: 8474b86a5a6f79c443ce4b2992817ff32cf208b8
-- name: go.uber.org/multierr
-  version: 3c4937480c32f4c13a875a1829af76c98ca3d40a
-- name: go.uber.org/zap
-  version: 35aad584952c3e7020db7b839f6b102de6271f89
-  subpackages:
-  - buffer
-  - internal/bufferpool
-  - internal/color
-  - internal/exit
-  - zapcore
-- name: golang.org/x/crypto
-  version: 9419663f5a44be8b34ca85f08abc5fe1be11f8a3
-  subpackages:
-  - bcrypt
-  - blowfish
-  - ssh/terminal
-- name: golang.org/x/net
-  version: 66aacef3dd8a676686c7ae3716979581e8b03c47
-  subpackages:
-  - context
-  - http2
-  - http2/hpack
-  - idna
-  - internal/timeseries
-  - lex/httplex
-  - trace
-- name: golang.org/x/sys
-  version: ebfc5b4631820b793c9010c87fd8fef0f39eb082
-  subpackages:
-  - unix
-  - windows
-- name: golang.org/x/text
-  version: b19bf474d317b857955b12035d2c5acb57ce8b01
-  subpackages:
-  - secure/bidirule
-  - transform
-  - unicode/bidi
-  - unicode/norm
-- name: golang.org/x/time
-  version: c06e80d9300e4443158a03817b8a8cb37d230320
-  subpackages:
-  - rate
-- name: google.golang.org/genproto
-  version: 09f6ed296fc66555a25fe4ce95173148778dfa85
-  subpackages:
-  - googleapis/rpc/status
-- name: google.golang.org/grpc
-  version: 5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e
-  subpackages:
-  - balancer
-  - codes
-  - connectivity
-  - credentials
-  - grpclb/grpc_lb_v1/messages
-  - grpclog
-  - health
-  - health/grpc_health_v1
-  - internal
-  - keepalive
-  - metadata
-  - naming
-  - peer
-  - resolver
-  - stats
-  - status
-  - tap
-  - transport
-- name: gopkg.in/cheggaaa/pb.v1
-  version: 226d21d43a305fac52b3a104ef83e721b15275e0
-- name: gopkg.in/yaml.v2
-  version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b
-testImports: []
diff --git a/vendor/github.com/coreos/etcd/glide.yaml b/vendor/github.com/coreos/etcd/glide.yaml
deleted file mode 100644
index cc83a85..0000000
--- a/vendor/github.com/coreos/etcd/glide.yaml
+++ /dev/null
@@ -1,152 +0,0 @@
-package: github.com/coreos/etcd
-ignore:
-- google.golang.org/appengine
-import:
-- package: github.com/bgentry/speakeasy
-  version: v0.1.0
-- package: github.com/coreos/bbolt
-  version: v1.3.1-coreos.6
-- package: github.com/coreos/go-semver
-  version: v0.2.0
-  subpackages:
-  - semver
-- package: github.com/coreos/go-systemd
-  version: v15
-  subpackages:
-  - daemon
-  - journal
-  - util
-- package: go.uber.org/zap
-  version: v1.7.1
-- package: github.com/coreos/pkg
-  version: v3
-  subpackages:
-  - capnslog
-- package: github.com/cpuguy83/go-md2man
-  version: 23709d0847197db6021a51fdb193e66e9222d4e7
-- package: github.com/dustin/go-humanize
-  version: bb3d318650d48840a39aa21a027c6630e198e626
-- package: github.com/ghodss/yaml
-  version: v1.0.0
-- package: github.com/gogo/protobuf
-  version: v0.5
-  subpackages:
-  - proto
-  - gogoproto
-- package: github.com/gorilla/websocket
-  version: 4201258b820c74ac8e6922fc9e6b52f71fe46f8d
-- package: github.com/golang/groupcache
-  version: 02826c3e79038b59d737d3b1c0a1d937f71a4433
-  subpackages:
-  - lru
-- package: github.com/golang/protobuf
-  version: 1e59b77b52bf8e4b449a57e6f79f21226d571845
-  subpackages:
-  - jsonpb
-  - proto
-- package: github.com/google/btree
-  version: 925471ac9e2131377a91e1595defec898166fe49
-- package: github.com/grpc-ecosystem/grpc-gateway
-  version: v1.3.0
-  subpackages:
-  - runtime
-  - runtime/internal
-  - utilities
-- package: github.com/jonboulle/clockwork
-  version: v0.1.0
-- package: github.com/kr/pty
-  version: v1.0.0
-- package: github.com/olekukonko/tablewriter
-  version: a0225b3f23b5ce0cbec6d7a66a968f8a59eca9c4
-- package: github.com/mattn/go-runewidth
-  version: v0.0.2
-  subpackages:
-  - runewidth.go
-- package: github.com/prometheus/client_golang
-  version: 5cec1d0429b02e4323e042eb04dafdb079ddf568
-  subpackages:
-  - prometheus
-  - prometheus/promhttp
-- package: github.com/prometheus/client_model
-  version: 6f3806018612930941127f2a7c6c453ba2c527d2
-  subpackages:
-  - go
-- package: github.com/prometheus/common
-  version: e3fb1a1acd7605367a2b378bc2e2f893c05174b7
-- package: github.com/prometheus/procfs
-  version: a6e9df898b1336106c743392c48ee0b71f5c4efa
-  subpackages:
-  - xfs
-- package: github.com/grpc-ecosystem/go-grpc-prometheus
-  version: 0dafe0d496ea71181bf2dd039e7e3f44b6bd11a7
-- package: github.com/spf13/cobra
-  version: 1c44ec8d3f1552cac48999f9306da23c4d8a288b
-- package: github.com/spf13/pflag
-  version: v1.0.0
-- package: github.com/ugorji/go
-  version: bdcc60b419d136a85cdf2e7cbcac34b3f1cd6e57
-  subpackages:
-  - codec
-- package: github.com/urfave/cli
-  version: v1.18.0
-- package: github.com/xiang90/probing
-  version: 0.0.1
-- package: golang.org/x/crypto
-  version: 9419663f5a44be8b34ca85f08abc5fe1be11f8a3
-  subpackages:
-  - bcrypt
-  - blowfish
-- package: golang.org/x/net
-  version: 66aacef3dd8a676686c7ae3716979581e8b03c47
-  subpackages:
-  - context
-  - http2
-  - http2/hpack
-  - internal/timeseries
-  - trace
-- package: golang.org/x/sys
-  version: ebfc5b4631820b793c9010c87fd8fef0f39eb082
-- package: golang.org/x/time
-  version: c06e80d9300e4443158a03817b8a8cb37d230320
-  subpackages:
-  - rate
-- package: google.golang.org/grpc
-  version: v1.7.5
-  subpackages:
-  - codes
-  - credentials
-  - grpclog
-  - internal
-  - metadata
-  - naming
-  - peer
-  - transport
-  - health
-  - health/grpc_health_v1
-- package: gopkg.in/cheggaaa/pb.v1
-  version: v1.0.2
-- package: gopkg.in/yaml.v2
-  version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b
-- package: github.com/dgrijalva/jwt-go
-  version: v3.0.0
-- package: google.golang.org/genproto
-  version: 09f6ed296fc66555a25fe4ce95173148778dfa85
-  subpackages:
-  - googleapis/rpc/status
-- package: golang.org/x/text
-  version: b19bf474d317b857955b12035d2c5acb57ce8b01
-  subpackages:
-  - secure/bidirule
-  - transform
-  - unicode/bidi
-  - unicode/norm
-- package: github.com/russross/blackfriday
-  version: 4048872b16cc0fc2c5fd9eacf0ed2c2fedaa0c8c
-- package: github.com/sirupsen/logrus
-  version: v1.0.3
-- package: github.com/soheilhy/cmux
-  version: v0.1.3
-- package: github.com/tmc/grpc-websocket-proxy
-  version: 89b8d40f7ca833297db804fcb3be53a76d01c238
-  subpackages:
-  - wsproxy
diff --git a/vendor/github.com/coreos/etcd/lease/doc.go b/vendor/github.com/coreos/etcd/lease/doc.go
deleted file mode 100644
index a74eaf7..0000000
--- a/vendor/github.com/coreos/etcd/lease/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package lease provides an interface and implementation for time-limited leases over arbitrary resources.
-package lease
diff --git a/vendor/github.com/coreos/etcd/lease/leasehttp/doc.go b/vendor/github.com/coreos/etcd/lease/leasehttp/doc.go
deleted file mode 100644
index 8177a37..0000000
--- a/vendor/github.com/coreos/etcd/lease/leasehttp/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package leasehttp serves lease renewals made through HTTP requests.
-package leasehttp
diff --git a/vendor/github.com/coreos/etcd/lease/leasehttp/http.go b/vendor/github.com/coreos/etcd/lease/leasehttp/http.go
deleted file mode 100644
index ac2e788..0000000
--- a/vendor/github.com/coreos/etcd/lease/leasehttp/http.go
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package leasehttp
-
-import (
-	"bytes"
-	"context"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"time"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/lease/leasepb"
-	"github.com/coreos/etcd/pkg/httputil"
-)
-
-var (
-	LeasePrefix         = "/leases"
-	LeaseInternalPrefix = "/leases/internal"
-	applyTimeout        = time.Second
-	ErrLeaseHTTPTimeout = errors.New("waiting for node to catch up its applied index has timed out")
-)
-
-// NewHandler returns an http Handler for lease renewals
-func NewHandler(l lease.Lessor, waitch func() <-chan struct{}) http.Handler {
-	return &leaseHandler{l, waitch}
-}
-
-type leaseHandler struct {
-	l      lease.Lessor
-	waitch func() <-chan struct{}
-}
-
-func (h *leaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if r.Method != "POST" {
-		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-		return
-	}
-
-	b, err := ioutil.ReadAll(r.Body)
-	if err != nil {
-		http.Error(w, "error reading body", http.StatusBadRequest)
-		return
-	}
-
-	var v []byte
-	switch r.URL.Path {
-	case LeasePrefix:
-		lreq := pb.LeaseKeepAliveRequest{}
-		if err := lreq.Unmarshal(b); err != nil {
-			http.Error(w, "error unmarshalling request", http.StatusBadRequest)
-			return
-		}
-		select {
-		case <-h.waitch():
-		case <-time.After(applyTimeout):
-			http.Error(w, ErrLeaseHTTPTimeout.Error(), http.StatusRequestTimeout)
-			return
-		}
-		ttl, err := h.l.Renew(lease.LeaseID(lreq.ID))
-		if err != nil {
-			if err == lease.ErrLeaseNotFound {
-				http.Error(w, err.Error(), http.StatusNotFound)
-				return
-			}
-
-			http.Error(w, err.Error(), http.StatusBadRequest)
-			return
-		}
-		// TODO: fill out ResponseHeader
-		resp := &pb.LeaseKeepAliveResponse{ID: lreq.ID, TTL: ttl}
-		v, err = resp.Marshal()
-		if err != nil {
-			http.Error(w, err.Error(), http.StatusInternalServerError)
-			return
-		}
-
-	case LeaseInternalPrefix:
-		lreq := leasepb.LeaseInternalRequest{}
-		if err := lreq.Unmarshal(b); err != nil {
-			http.Error(w, "error unmarshalling request", http.StatusBadRequest)
-			return
-		}
-		select {
-		case <-h.waitch():
-		case <-time.After(applyTimeout):
-			http.Error(w, ErrLeaseHTTPTimeout.Error(), http.StatusRequestTimeout)
-			return
-		}
-		l := h.l.Lookup(lease.LeaseID(lreq.LeaseTimeToLiveRequest.ID))
-		if l == nil {
-			http.Error(w, lease.ErrLeaseNotFound.Error(), http.StatusNotFound)
-			return
-		}
-		// TODO: fill out ResponseHeader
-		resp := &leasepb.LeaseInternalResponse{
-			LeaseTimeToLiveResponse: &pb.LeaseTimeToLiveResponse{
-				Header:     &pb.ResponseHeader{},
-				ID:         lreq.LeaseTimeToLiveRequest.ID,
-				TTL:        int64(l.Remaining().Seconds()),
-				GrantedTTL: l.TTL(),
-			},
-		}
-		if lreq.LeaseTimeToLiveRequest.Keys {
-			ks := l.Keys()
-			kbs := make([][]byte, len(ks))
-			for i := range ks {
-				kbs[i] = []byte(ks[i])
-			}
-			resp.LeaseTimeToLiveResponse.Keys = kbs
-		}
-
-		v, err = resp.Marshal()
-		if err != nil {
-			http.Error(w, err.Error(), http.StatusInternalServerError)
-			return
-		}
-
-	default:
-		http.Error(w, fmt.Sprintf("unknown request path %q", r.URL.Path), http.StatusBadRequest)
-		return
-	}
-
-	w.Header().Set("Content-Type", "application/protobuf")
-	w.Write(v)
-}
-
-// RenewHTTP renews a lease at a given primary server.
-// TODO: Batch request in future?
-func RenewHTTP(ctx context.Context, id lease.LeaseID, url string, rt http.RoundTripper) (int64, error) {
-	// will post lreq protobuf to leader
-	lreq, err := (&pb.LeaseKeepAliveRequest{ID: int64(id)}).Marshal()
-	if err != nil {
-		return -1, err
-	}
-
-	cc := &http.Client{Transport: rt}
-	req, err := http.NewRequest("POST", url, bytes.NewReader(lreq))
-	if err != nil {
-		return -1, err
-	}
-	req.Header.Set("Content-Type", "application/protobuf")
-	req.Cancel = ctx.Done()
-
-	resp, err := cc.Do(req)
-	if err != nil {
-		return -1, err
-	}
-	b, err := readResponse(resp)
-	if err != nil {
-		return -1, err
-	}
-
-	if resp.StatusCode == http.StatusRequestTimeout {
-		return -1, ErrLeaseHTTPTimeout
-	}
-
-	if resp.StatusCode == http.StatusNotFound {
-		return -1, lease.ErrLeaseNotFound
-	}
-
-	if resp.StatusCode != http.StatusOK {
-		return -1, fmt.Errorf("lease: unknown error(%s)", string(b))
-	}
-
-	lresp := &pb.LeaseKeepAliveResponse{}
-	if err := lresp.Unmarshal(b); err != nil {
-		return -1, fmt.Errorf(`lease: %v. data = "%s"`, err, string(b))
-	}
-	if lresp.ID != int64(id) {
-		return -1, fmt.Errorf("lease: renew id mismatch")
-	}
-	return lresp.TTL, nil
-}
-
-// TimeToLiveHTTP retrieves lease information of the given lease ID.
-func TimeToLiveHTTP(ctx context.Context, id lease.LeaseID, keys bool, url string, rt http.RoundTripper) (*leasepb.LeaseInternalResponse, error) {
-	// will post lreq protobuf to leader
-	lreq, err := (&leasepb.LeaseInternalRequest{
-		LeaseTimeToLiveRequest: &pb.LeaseTimeToLiveRequest{
-			ID:   int64(id),
-			Keys: keys,
-		},
-	}).Marshal()
-	if err != nil {
-		return nil, err
-	}
-
-	req, err := http.NewRequest("POST", url, bytes.NewReader(lreq))
-	if err != nil {
-		return nil, err
-	}
-	req.Header.Set("Content-Type", "application/protobuf")
-
-	req = req.WithContext(ctx)
-
-	cc := &http.Client{Transport: rt}
-	var b []byte
-	// buffer errc channel so that errc don't block inside the go routinue
-	resp, err := cc.Do(req)
-	if err != nil {
-		return nil, err
-	}
-	b, err = readResponse(resp)
-	if err != nil {
-		return nil, err
-	}
-	if resp.StatusCode == http.StatusRequestTimeout {
-		return nil, ErrLeaseHTTPTimeout
-	}
-	if resp.StatusCode == http.StatusNotFound {
-		return nil, lease.ErrLeaseNotFound
-	}
-	if resp.StatusCode != http.StatusOK {
-		return nil, fmt.Errorf("lease: unknown error(%s)", string(b))
-	}
-
-	lresp := &leasepb.LeaseInternalResponse{}
-	if err := lresp.Unmarshal(b); err != nil {
-		return nil, fmt.Errorf(`lease: %v. data = "%s"`, err, string(b))
-	}
-	if lresp.LeaseTimeToLiveResponse.ID != int64(id) {
-		return nil, fmt.Errorf("lease: renew id mismatch")
-	}
-	return lresp, nil
-}
-
-func readResponse(resp *http.Response) (b []byte, err error) {
-	b, err = ioutil.ReadAll(resp.Body)
-	httputil.GracefulClose(resp)
-	return
-}
diff --git a/vendor/github.com/coreos/etcd/lease/leasepb/lease.proto b/vendor/github.com/coreos/etcd/lease/leasepb/lease.proto
deleted file mode 100644
index be414b9..0000000
--- a/vendor/github.com/coreos/etcd/lease/leasepb/lease.proto
+++ /dev/null
@@ -1,24 +0,0 @@
-syntax = "proto3";
-package leasepb;
-
-import "gogoproto/gogo.proto";
-import "etcd/etcdserver/etcdserverpb/rpc.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.sizer_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-option (gogoproto.goproto_getters_all) = false;
-option (gogoproto.goproto_enum_prefix_all) = false;
-
-message Lease {
-  int64 ID = 1;
-  int64 TTL = 2;
-}
-
-message LeaseInternalRequest {
-  etcdserverpb.LeaseTimeToLiveRequest LeaseTimeToLiveRequest = 1;
-}
-
-message LeaseInternalResponse {
-  etcdserverpb.LeaseTimeToLiveResponse LeaseTimeToLiveResponse = 1;
-}
diff --git a/vendor/github.com/coreos/etcd/lease/lessor.go b/vendor/github.com/coreos/etcd/lease/lessor.go
deleted file mode 100644
index 43f0503..0000000
--- a/vendor/github.com/coreos/etcd/lease/lessor.go
+++ /dev/null
@@ -1,680 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package lease
-
-import (
-	"encoding/binary"
-	"errors"
-	"math"
-	"sort"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/lease/leasepb"
-	"github.com/coreos/etcd/mvcc/backend"
-)
-
-// NoLease is a special LeaseID representing the absence of a lease.
-const NoLease = LeaseID(0)
-
-// MaxLeaseTTL is the maximum lease TTL value
-const MaxLeaseTTL = 9000000000
-
-var (
-	forever = time.Time{}
-
-	leaseBucketName = []byte("lease")
-
-	// maximum number of leases to revoke per second; configurable for tests
-	leaseRevokeRate = 1000
-
-	ErrNotPrimary       = errors.New("not a primary lessor")
-	ErrLeaseNotFound    = errors.New("lease not found")
-	ErrLeaseExists      = errors.New("lease already exists")
-	ErrLeaseTTLTooLarge = errors.New("too large lease TTL")
-)
-
-// TxnDelete is a TxnWrite that only permits deletes. Defined here
-// to avoid circular dependency with mvcc.
-type TxnDelete interface {
-	DeleteRange(key, end []byte) (n, rev int64)
-	End()
-}
-
-// RangeDeleter is a TxnDelete constructor.
-type RangeDeleter func() TxnDelete
-
-type LeaseID int64
-
-// Lessor owns leases. It can grant, revoke, renew and modify leases for lessee.
-type Lessor interface {
-	// SetRangeDeleter lets the lessor create TxnDeletes to the store.
-	// Lessor deletes the items in the revoked or expired lease by creating
-	// new TxnDeletes.
-	SetRangeDeleter(rd RangeDeleter)
-
-	// Grant grants a lease that expires at least after TTL seconds.
-	Grant(id LeaseID, ttl int64) (*Lease, error)
-	// Revoke revokes a lease with given ID. The item attached to the
-	// given lease will be removed. If the ID does not exist, an error
-	// will be returned.
-	Revoke(id LeaseID) error
-
-	// Attach attaches given leaseItem to the lease with given LeaseID.
-	// If the lease does not exist, an error will be returned.
-	Attach(id LeaseID, items []LeaseItem) error
-
-	// GetLease returns LeaseID for given item.
-	// If no lease found, NoLease value will be returned.
-	GetLease(item LeaseItem) LeaseID
-
-	// Detach detaches given leaseItem from the lease with given LeaseID.
-	// If the lease does not exist, an error will be returned.
-	Detach(id LeaseID, items []LeaseItem) error
-
-	// Promote promotes the lessor to be the primary lessor. Primary lessor manages
-	// the expiration and renew of leases.
-	// Newly promoted lessor renew the TTL of all lease to extend + previous TTL.
-	Promote(extend time.Duration)
-
-	// Demote demotes the lessor from being the primary lessor.
-	Demote()
-
-	// Renew renews a lease with given ID. It returns the renewed TTL. If the ID does not exist,
-	// an error will be returned.
-	Renew(id LeaseID) (int64, error)
-
-	// Lookup gives the lease at a given lease id, if any
-	Lookup(id LeaseID) *Lease
-
-	// Leases lists all leases.
-	Leases() []*Lease
-
-	// ExpiredLeasesC returns a chan that is used to receive expired leases.
-	ExpiredLeasesC() <-chan []*Lease
-
-	// Recover recovers the lessor state from the given backend and RangeDeleter.
-	Recover(b backend.Backend, rd RangeDeleter)
-
-	// Stop stops the lessor for managing leases. The behavior of calling Stop multiple
-	// times is undefined.
-	Stop()
-}
-
-// lessor implements Lessor interface.
-// TODO: use clockwork for testability.
-type lessor struct {
-	mu sync.Mutex
-
-	// demotec is set when the lessor is the primary.
-	// demotec will be closed if the lessor is demoted.
-	demotec chan struct{}
-
-	// TODO: probably this should be a heap with a secondary
-	// id index.
-	// Now it is O(N) to loop over the leases to find expired ones.
-	// We want to make Grant, Revoke, and findExpiredLeases all O(logN) and
-	// Renew O(1).
-	// findExpiredLeases and Renew should be the most frequent operations.
-	leaseMap map[LeaseID]*Lease
-
-	itemMap map[LeaseItem]LeaseID
-
-	// When a lease expires, the lessor will delete the
-	// leased range (or key) by the RangeDeleter.
-	rd RangeDeleter
-
-	// backend to persist leases. We only persist lease ID and expiry for now.
-	// The leased items can be recovered by iterating all the keys in kv.
-	b backend.Backend
-
-	// minLeaseTTL is the minimum lease TTL that can be granted for a lease. Any
-	// requests for shorter TTLs are extended to the minimum TTL.
-	minLeaseTTL int64
-
-	expiredC chan []*Lease
-	// stopC is a channel whose closure indicates that the lessor should be stopped.
-	stopC chan struct{}
-	// doneC is a channel whose closure indicates that the lessor is stopped.
-	doneC chan struct{}
-}
-
-func NewLessor(b backend.Backend, minLeaseTTL int64) Lessor {
-	return newLessor(b, minLeaseTTL)
-}
-
-func newLessor(b backend.Backend, minLeaseTTL int64) *lessor {
-	l := &lessor{
-		leaseMap:    make(map[LeaseID]*Lease),
-		itemMap:     make(map[LeaseItem]LeaseID),
-		b:           b,
-		minLeaseTTL: minLeaseTTL,
-		// expiredC is a small buffered chan to avoid unnecessary blocking.
-		expiredC: make(chan []*Lease, 16),
-		stopC:    make(chan struct{}),
-		doneC:    make(chan struct{}),
-	}
-	l.initAndRecover()
-
-	go l.runLoop()
-
-	return l
-}
-
-// isPrimary indicates if this lessor is the primary lessor. The primary
-// lessor manages lease expiration and renew.
-//
-// in etcd, raft leader is the primary. Thus there might be two primary
-// leaders at the same time (raft allows concurrent leader but with different term)
-// for at most a leader election timeout.
-// The old primary leader cannot affect the correctness since its proposal has a
-// smaller term and will not be committed.
-//
-// TODO: raft follower do not forward lease management proposals. There might be a
-// very small window (within second normally which depends on go scheduling) that
-// a raft follow is the primary between the raft leader demotion and lessor demotion.
-// Usually this should not be a problem. Lease should not be that sensitive to timing.
-func (le *lessor) isPrimary() bool {
-	return le.demotec != nil
-}
-
-func (le *lessor) SetRangeDeleter(rd RangeDeleter) {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	le.rd = rd
-}
-
-func (le *lessor) Grant(id LeaseID, ttl int64) (*Lease, error) {
-	if id == NoLease {
-		return nil, ErrLeaseNotFound
-	}
-
-	if ttl > MaxLeaseTTL {
-		return nil, ErrLeaseTTLTooLarge
-	}
-
-	// TODO: when lessor is under high load, it should give out lease
-	// with longer TTL to reduce renew load.
-	l := &Lease{
-		ID:      id,
-		ttl:     ttl,
-		itemSet: make(map[LeaseItem]struct{}),
-		revokec: make(chan struct{}),
-	}
-
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	if _, ok := le.leaseMap[id]; ok {
-		return nil, ErrLeaseExists
-	}
-
-	if l.ttl < le.minLeaseTTL {
-		l.ttl = le.minLeaseTTL
-	}
-
-	if le.isPrimary() {
-		l.refresh(0)
-	} else {
-		l.forever()
-	}
-
-	le.leaseMap[id] = l
-	l.persistTo(le.b)
-
-	return l, nil
-}
-
-func (le *lessor) Revoke(id LeaseID) error {
-	le.mu.Lock()
-
-	l := le.leaseMap[id]
-	if l == nil {
-		le.mu.Unlock()
-		return ErrLeaseNotFound
-	}
-	defer close(l.revokec)
-	// unlock before doing external work
-	le.mu.Unlock()
-
-	if le.rd == nil {
-		return nil
-	}
-
-	txn := le.rd()
-
-	// sort keys so deletes are in same order among all members,
-	// otherwise the backened hashes will be different
-	keys := l.Keys()
-	sort.StringSlice(keys).Sort()
-	for _, key := range keys {
-		txn.DeleteRange([]byte(key), nil)
-	}
-
-	le.mu.Lock()
-	defer le.mu.Unlock()
-	delete(le.leaseMap, l.ID)
-	// lease deletion needs to be in the same backend transaction with the
-	// kv deletion. Or we might end up with not executing the revoke or not
-	// deleting the keys if etcdserver fails in between.
-	le.b.BatchTx().UnsafeDelete(leaseBucketName, int64ToBytes(int64(l.ID)))
-
-	txn.End()
-	return nil
-}
-
-// Renew renews an existing lease. If the given lease does not exist or
-// has expired, an error will be returned.
-func (le *lessor) Renew(id LeaseID) (int64, error) {
-	le.mu.Lock()
-
-	unlock := func() { le.mu.Unlock() }
-	defer func() { unlock() }()
-
-	if !le.isPrimary() {
-		// forward renew request to primary instead of returning error.
-		return -1, ErrNotPrimary
-	}
-
-	demotec := le.demotec
-
-	l := le.leaseMap[id]
-	if l == nil {
-		return -1, ErrLeaseNotFound
-	}
-
-	if l.expired() {
-		le.mu.Unlock()
-		unlock = func() {}
-		select {
-		// A expired lease might be pending for revoking or going through
-		// quorum to be revoked. To be accurate, renew request must wait for the
-		// deletion to complete.
-		case <-l.revokec:
-			return -1, ErrLeaseNotFound
-		// The expired lease might fail to be revoked if the primary changes.
-		// The caller will retry on ErrNotPrimary.
-		case <-demotec:
-			return -1, ErrNotPrimary
-		case <-le.stopC:
-			return -1, ErrNotPrimary
-		}
-	}
-
-	l.refresh(0)
-	return l.ttl, nil
-}
-
-func (le *lessor) Lookup(id LeaseID) *Lease {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-	return le.leaseMap[id]
-}
-
-func (le *lessor) unsafeLeases() []*Lease {
-	leases := make([]*Lease, 0, len(le.leaseMap))
-	for _, l := range le.leaseMap {
-		leases = append(leases, l)
-	}
-	sort.Sort(leasesByExpiry(leases))
-	return leases
-}
-
-func (le *lessor) Leases() []*Lease {
-	le.mu.Lock()
-	ls := le.unsafeLeases()
-	le.mu.Unlock()
-	return ls
-}
-
-func (le *lessor) Promote(extend time.Duration) {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	le.demotec = make(chan struct{})
-
-	// refresh the expiries of all leases.
-	for _, l := range le.leaseMap {
-		l.refresh(extend)
-	}
-
-	if len(le.leaseMap) < leaseRevokeRate {
-		// no possibility of lease pile-up
-		return
-	}
-
-	// adjust expiries in case of overlap
-	leases := le.unsafeLeases()
-
-	baseWindow := leases[0].Remaining()
-	nextWindow := baseWindow + time.Second
-	expires := 0
-	// have fewer expires than the total revoke rate so piled up leases
-	// don't consume the entire revoke limit
-	targetExpiresPerSecond := (3 * leaseRevokeRate) / 4
-	for _, l := range leases {
-		remaining := l.Remaining()
-		if remaining > nextWindow {
-			baseWindow = remaining
-			nextWindow = baseWindow + time.Second
-			expires = 1
-			continue
-		}
-		expires++
-		if expires <= targetExpiresPerSecond {
-			continue
-		}
-		rateDelay := float64(time.Second) * (float64(expires) / float64(targetExpiresPerSecond))
-		// If leases are extended by n seconds, leases n seconds ahead of the
-		// base window should be extended by only one second.
-		rateDelay -= float64(remaining - baseWindow)
-		delay := time.Duration(rateDelay)
-		nextWindow = baseWindow + delay
-		l.refresh(delay + extend)
-	}
-}
-
-type leasesByExpiry []*Lease
-
-func (le leasesByExpiry) Len() int           { return len(le) }
-func (le leasesByExpiry) Less(i, j int) bool { return le[i].Remaining() < le[j].Remaining() }
-func (le leasesByExpiry) Swap(i, j int)      { le[i], le[j] = le[j], le[i] }
-
-func (le *lessor) Demote() {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	// set the expiries of all leases to forever
-	for _, l := range le.leaseMap {
-		l.forever()
-	}
-
-	if le.demotec != nil {
-		close(le.demotec)
-		le.demotec = nil
-	}
-}
-
-// Attach attaches items to the lease with given ID. When the lease
-// expires, the attached items will be automatically removed.
-// If the given lease does not exist, an error will be returned.
-func (le *lessor) Attach(id LeaseID, items []LeaseItem) error {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	l := le.leaseMap[id]
-	if l == nil {
-		return ErrLeaseNotFound
-	}
-
-	l.mu.Lock()
-	for _, it := range items {
-		l.itemSet[it] = struct{}{}
-		le.itemMap[it] = id
-	}
-	l.mu.Unlock()
-	return nil
-}
-
-func (le *lessor) GetLease(item LeaseItem) LeaseID {
-	le.mu.Lock()
-	id := le.itemMap[item]
-	le.mu.Unlock()
-	return id
-}
-
-// Detach detaches items from the lease with given ID.
-// If the given lease does not exist, an error will be returned.
-func (le *lessor) Detach(id LeaseID, items []LeaseItem) error {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	l := le.leaseMap[id]
-	if l == nil {
-		return ErrLeaseNotFound
-	}
-
-	l.mu.Lock()
-	for _, it := range items {
-		delete(l.itemSet, it)
-		delete(le.itemMap, it)
-	}
-	l.mu.Unlock()
-	return nil
-}
-
-func (le *lessor) Recover(b backend.Backend, rd RangeDeleter) {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	le.b = b
-	le.rd = rd
-	le.leaseMap = make(map[LeaseID]*Lease)
-	le.itemMap = make(map[LeaseItem]LeaseID)
-	le.initAndRecover()
-}
-
-func (le *lessor) ExpiredLeasesC() <-chan []*Lease {
-	return le.expiredC
-}
-
-func (le *lessor) Stop() {
-	close(le.stopC)
-	<-le.doneC
-}
-
-func (le *lessor) runLoop() {
-	defer close(le.doneC)
-
-	for {
-		var ls []*Lease
-
-		// rate limit
-		revokeLimit := leaseRevokeRate / 2
-
-		le.mu.Lock()
-		if le.isPrimary() {
-			ls = le.findExpiredLeases(revokeLimit)
-		}
-		le.mu.Unlock()
-
-		if len(ls) != 0 {
-			select {
-			case <-le.stopC:
-				return
-			case le.expiredC <- ls:
-			default:
-				// the receiver of expiredC is probably busy handling
-				// other stuff
-				// let's try this next time after 500ms
-			}
-		}
-
-		select {
-		case <-time.After(500 * time.Millisecond):
-		case <-le.stopC:
-			return
-		}
-	}
-}
-
-// findExpiredLeases loops leases in the leaseMap until reaching expired limit
-// and returns the expired leases that needed to be revoked.
-func (le *lessor) findExpiredLeases(limit int) []*Lease {
-	leases := make([]*Lease, 0, 16)
-
-	for _, l := range le.leaseMap {
-		// TODO: probably should change to <= 100-500 millisecond to
-		// make up committing latency.
-		if l.expired() {
-			leases = append(leases, l)
-
-			// reach expired limit
-			if len(leases) == limit {
-				break
-			}
-		}
-	}
-
-	return leases
-}
-
-func (le *lessor) initAndRecover() {
-	tx := le.b.BatchTx()
-	tx.Lock()
-
-	tx.UnsafeCreateBucket(leaseBucketName)
-	_, vs := tx.UnsafeRange(leaseBucketName, int64ToBytes(0), int64ToBytes(math.MaxInt64), 0)
-	// TODO: copy vs and do decoding outside tx lock if lock contention becomes an issue.
-	for i := range vs {
-		var lpb leasepb.Lease
-		err := lpb.Unmarshal(vs[i])
-		if err != nil {
-			tx.Unlock()
-			panic("failed to unmarshal lease proto item")
-		}
-		ID := LeaseID(lpb.ID)
-		if lpb.TTL < le.minLeaseTTL {
-			lpb.TTL = le.minLeaseTTL
-		}
-		le.leaseMap[ID] = &Lease{
-			ID:  ID,
-			ttl: lpb.TTL,
-			// itemSet will be filled in when recover key-value pairs
-			// set expiry to forever, refresh when promoted
-			itemSet: make(map[LeaseItem]struct{}),
-			expiry:  forever,
-			revokec: make(chan struct{}),
-		}
-	}
-	tx.Unlock()
-
-	le.b.ForceCommit()
-}
-
-type Lease struct {
-	ID  LeaseID
-	ttl int64 // time to live in seconds
-	// expiryMu protects concurrent accesses to expiry
-	expiryMu sync.RWMutex
-	// expiry is time when lease should expire. no expiration when expiry.IsZero() is true
-	expiry time.Time
-
-	// mu protects concurrent accesses to itemSet
-	mu      sync.RWMutex
-	itemSet map[LeaseItem]struct{}
-	revokec chan struct{}
-}
-
-func (l *Lease) expired() bool {
-	return l.Remaining() <= 0
-}
-
-func (l *Lease) persistTo(b backend.Backend) {
-	key := int64ToBytes(int64(l.ID))
-
-	lpb := leasepb.Lease{ID: int64(l.ID), TTL: int64(l.ttl)}
-	val, err := lpb.Marshal()
-	if err != nil {
-		panic("failed to marshal lease proto item")
-	}
-
-	b.BatchTx().Lock()
-	b.BatchTx().UnsafePut(leaseBucketName, key, val)
-	b.BatchTx().Unlock()
-}
-
-// TTL returns the TTL of the Lease.
-func (l *Lease) TTL() int64 {
-	return l.ttl
-}
-
-// refresh refreshes the expiry of the lease.
-func (l *Lease) refresh(extend time.Duration) {
-	newExpiry := time.Now().Add(extend + time.Duration(l.ttl)*time.Second)
-	l.expiryMu.Lock()
-	defer l.expiryMu.Unlock()
-	l.expiry = newExpiry
-}
-
-// forever sets the expiry of lease to be forever.
-func (l *Lease) forever() {
-	l.expiryMu.Lock()
-	defer l.expiryMu.Unlock()
-	l.expiry = forever
-}
-
-// Keys returns all the keys attached to the lease.
-func (l *Lease) Keys() []string {
-	l.mu.RLock()
-	keys := make([]string, 0, len(l.itemSet))
-	for k := range l.itemSet {
-		keys = append(keys, k.Key)
-	}
-	l.mu.RUnlock()
-	return keys
-}
-
-// Remaining returns the remaining time of the lease.
-func (l *Lease) Remaining() time.Duration {
-	l.expiryMu.RLock()
-	defer l.expiryMu.RUnlock()
-	if l.expiry.IsZero() {
-		return time.Duration(math.MaxInt64)
-	}
-	return time.Until(l.expiry)
-}
-
-type LeaseItem struct {
-	Key string
-}
-
-func int64ToBytes(n int64) []byte {
-	bytes := make([]byte, 8)
-	binary.BigEndian.PutUint64(bytes, uint64(n))
-	return bytes
-}
-
-// FakeLessor is a fake implementation of Lessor interface.
-// Used for testing only.
-type FakeLessor struct{}
-
-func (fl *FakeLessor) SetRangeDeleter(dr RangeDeleter) {}
-
-func (fl *FakeLessor) Grant(id LeaseID, ttl int64) (*Lease, error) { return nil, nil }
-
-func (fl *FakeLessor) Revoke(id LeaseID) error { return nil }
-
-func (fl *FakeLessor) Attach(id LeaseID, items []LeaseItem) error { return nil }
-
-func (fl *FakeLessor) GetLease(item LeaseItem) LeaseID            { return 0 }
-func (fl *FakeLessor) Detach(id LeaseID, items []LeaseItem) error { return nil }
-
-func (fl *FakeLessor) Promote(extend time.Duration) {}
-
-func (fl *FakeLessor) Demote() {}
-
-func (fl *FakeLessor) Renew(id LeaseID) (int64, error) { return 10, nil }
-
-func (fl *FakeLessor) Lookup(id LeaseID) *Lease { return nil }
-
-func (fl *FakeLessor) Leases() []*Lease { return nil }
-
-func (fl *FakeLessor) ExpiredLeasesC() <-chan []*Lease { return nil }
-
-func (fl *FakeLessor) Recover(b backend.Backend, rd RangeDeleter) {}
-
-func (fl *FakeLessor) Stop() {}
diff --git a/vendor/github.com/coreos/etcd/main.go b/vendor/github.com/coreos/etcd/main.go
deleted file mode 100644
index 0b73573..0000000
--- a/vendor/github.com/coreos/etcd/main.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package main is a simple wrapper of the real etcd entrypoint package
-// (located at github.com/coreos/etcd/etcdmain) to ensure that etcd is still
-// "go getable"; e.g. `go get github.com/coreos/etcd` works as expected and
-// builds a binary in $GOBIN/etcd
-//
-// This package should NOT be extended or modified in any way; to modify the
-// etcd binary, work in the `github.com/coreos/etcd/etcdmain` package.
-//
-package main
-
-import "github.com/coreos/etcd/etcdmain"
-
-func main() {
-	etcdmain.Main()
-}
diff --git a/vendor/github.com/coreos/etcd/meeting.ics b/vendor/github.com/coreos/etcd/meeting.ics
deleted file mode 100644
index 0157f9a..0000000
--- a/vendor/github.com/coreos/etcd/meeting.ics
+++ /dev/null
@@ -1,49 +0,0 @@
-BEGIN:VCALENDAR
-PRODID:-//Google Inc//Google Calendar 70.9054//EN
-VERSION:2.0
-CALSCALE:GREGORIAN
-METHOD:REPLY
-BEGIN:VTIMEZONE
-TZID:America/Los_Angeles
-X-LIC-LOCATION:America/Los_Angeles
-BEGIN:DAYLIGHT
-TZOFFSETFROM:-0800
-TZOFFSETTO:-0700
-TZNAME:PDT
-DTSTART:19700308T020000
-RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:-0700
-TZOFFSETTO:-0800
-TZNAME:PST
-DTSTART:19701101T020000
-RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTART;TZID=America/Los_Angeles:20180116T110000
-DTEND;TZID=America/Los_Angeles:20180116T115000
-RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TU
-DTSTAMP:20171213T131221Z
-ORGANIZER;CN=Gyuho Lee:mailto:gyu_ho.lee@coreos.com
-UID:11ivec3kg2egsng3vrl8t5alar@google.com
-CREATED:20171212T194217Z
-DESCRIPTION:<br>Please add your discussion items to the meeting notes.<br><
- br>Meeting notes<br><a href="https://docs.google.com/document/d/1DbVXOHvd9s
- cFsSmL2oNg4YGOHJdXqtx583DmeVWrB_M/edit?usp=sharing">https://docs.google.com
- /document/d/1DbVXOHvd9scFsSmL2oNg4YGOHJdXqtx583DmeVWrB_M/edit?usp=sharing</
- a><br><br>Zoom meeting<br><a href="https://www.google.com/url?q=https%3A%2F
- %2Fcoreos.zoom.us%2Fj%2F854793406&amp\;sa=D&amp\;ust=1509474820520000&amp\;
- usg=AFQjCNFIOIfx1O_dgC-1N5YLyLOMa7D3Dg" target="_blank">https://coreos.zoom
- .us/j/854793406</a><br><br>Slack<br><a href="https://www.google.com/url?q=h
- ttps%3A%2F%2Fkubernetes.slack.com&amp\;sa=D&amp\;ust=1513114941738000&amp\;
- usg=AFQjCNHbdDPJcyZ2tVATRqTQDuZDFzGoRQ" target="_blank">https://kubernetes.
- slack.com</a> <i>#etcd</i><br><br><i><br></i>
-LAST-MODIFIED:20171213T131220Z
-SEQUENCE:0
-STATUS:CONFIRMED
-SUMMARY:etcd meeting
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/backend.go b/vendor/github.com/coreos/etcd/mvcc/backend/backend.go
deleted file mode 100644
index f7d9e60..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/backend/backend.go
+++ /dev/null
@@ -1,464 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package backend
-
-import (
-	"fmt"
-	"hash/crc32"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	bolt "github.com/coreos/bbolt"
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	defaultBatchLimit    = 10000
-	defaultBatchInterval = 100 * time.Millisecond
-
-	defragLimit = 10000
-
-	// initialMmapSize is the initial size of the mmapped region. Setting this larger than
-	// the potential max db size can prevent writer from blocking reader.
-	// This only works for linux.
-	initialMmapSize = uint64(10 * 1024 * 1024 * 1024)
-
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "mvcc/backend")
-
-	// minSnapshotWarningTimeout is the minimum threshold to trigger a long running snapshot warning.
-	minSnapshotWarningTimeout = time.Duration(30 * time.Second)
-)
-
-type Backend interface {
-	ReadTx() ReadTx
-	BatchTx() BatchTx
-
-	Snapshot() Snapshot
-	Hash(ignores map[IgnoreKey]struct{}) (uint32, error)
-	// Size returns the current size of the backend.
-	Size() int64
-	// SizeInUse returns the current size of the backend logically in use.
-	// Since the backend can manage free space in a non-byte unit such as
-	// number of pages, the returned value can be not exactly accurate in bytes.
-	SizeInUse() int64
-	Defrag() error
-	ForceCommit()
-	Close() error
-}
-
-type Snapshot interface {
-	// Size gets the size of the snapshot.
-	Size() int64
-	// WriteTo writes the snapshot into the given writer.
-	WriteTo(w io.Writer) (n int64, err error)
-	// Close closes the snapshot.
-	Close() error
-}
-
-type backend struct {
-	// size and commits are used with atomic operations so they must be
-	// 64-bit aligned, otherwise 32-bit tests will crash
-
-	// size is the number of bytes in the backend
-	size int64
-
-	// sizeInUse is the number of bytes actually used in the backend
-	sizeInUse int64
-
-	// commits counts number of commits since start
-	commits int64
-
-	mu sync.RWMutex
-	db *bolt.DB
-
-	batchInterval time.Duration
-	batchLimit    int
-	batchTx       *batchTxBuffered
-
-	readTx *readTx
-
-	stopc chan struct{}
-	donec chan struct{}
-}
-
-type BackendConfig struct {
-	// Path is the file path to the backend file.
-	Path string
-	// BatchInterval is the maximum time before flushing the BatchTx.
-	BatchInterval time.Duration
-	// BatchLimit is the maximum puts before flushing the BatchTx.
-	BatchLimit int
-	// MmapSize is the number of bytes to mmap for the backend.
-	MmapSize uint64
-}
-
-func DefaultBackendConfig() BackendConfig {
-	return BackendConfig{
-		BatchInterval: defaultBatchInterval,
-		BatchLimit:    defaultBatchLimit,
-		MmapSize:      initialMmapSize,
-	}
-}
-
-func New(bcfg BackendConfig) Backend {
-	return newBackend(bcfg)
-}
-
-func NewDefaultBackend(path string) Backend {
-	bcfg := DefaultBackendConfig()
-	bcfg.Path = path
-	return newBackend(bcfg)
-}
-
-func newBackend(bcfg BackendConfig) *backend {
-	bopts := &bolt.Options{}
-	if boltOpenOptions != nil {
-		*bopts = *boltOpenOptions
-	}
-	bopts.InitialMmapSize = bcfg.mmapSize()
-
-	db, err := bolt.Open(bcfg.Path, 0600, bopts)
-	if err != nil {
-		plog.Panicf("cannot open database at %s (%v)", bcfg.Path, err)
-	}
-
-	// In future, may want to make buffering optional for low-concurrency systems
-	// or dynamically swap between buffered/non-buffered depending on workload.
-	b := &backend{
-		db: db,
-
-		batchInterval: bcfg.BatchInterval,
-		batchLimit:    bcfg.BatchLimit,
-
-		readTx: &readTx{
-			buf: txReadBuffer{
-				txBuffer: txBuffer{make(map[string]*bucketBuffer)},
-			},
-			buckets: make(map[string]*bolt.Bucket),
-		},
-
-		stopc: make(chan struct{}),
-		donec: make(chan struct{}),
-	}
-	b.batchTx = newBatchTxBuffered(b)
-	go b.run()
-	return b
-}
-
-// BatchTx returns the current batch tx in coalescer. The tx can be used for read and
-// write operations. The write result can be retrieved within the same tx immediately.
-// The write result is isolated with other txs until the current one get committed.
-func (b *backend) BatchTx() BatchTx {
-	return b.batchTx
-}
-
-func (b *backend) ReadTx() ReadTx { return b.readTx }
-
-// ForceCommit forces the current batching tx to commit.
-func (b *backend) ForceCommit() {
-	b.batchTx.Commit()
-}
-
-func (b *backend) Snapshot() Snapshot {
-	b.batchTx.Commit()
-
-	b.mu.RLock()
-	defer b.mu.RUnlock()
-	tx, err := b.db.Begin(false)
-	if err != nil {
-		plog.Fatalf("cannot begin tx (%s)", err)
-	}
-
-	stopc, donec := make(chan struct{}), make(chan struct{})
-	dbBytes := tx.Size()
-	go func() {
-		defer close(donec)
-		// sendRateBytes is based on transferring snapshot data over a 1 gigabit/s connection
-		// assuming a min tcp throughput of 100MB/s.
-		var sendRateBytes int64 = 100 * 1024 * 1014
-		warningTimeout := time.Duration(int64((float64(dbBytes) / float64(sendRateBytes)) * float64(time.Second)))
-		if warningTimeout < minSnapshotWarningTimeout {
-			warningTimeout = minSnapshotWarningTimeout
-		}
-		start := time.Now()
-		ticker := time.NewTicker(warningTimeout)
-		defer ticker.Stop()
-		for {
-			select {
-			case <-ticker.C:
-				plog.Warningf("snapshotting is taking more than %v seconds to finish transferring %v MB [started at %v]", time.Since(start).Seconds(), float64(dbBytes)/float64(1024*1014), start)
-			case <-stopc:
-				snapshotDurations.Observe(time.Since(start).Seconds())
-				return
-			}
-		}
-	}()
-
-	return &snapshot{tx, stopc, donec}
-}
-
-type IgnoreKey struct {
-	Bucket string
-	Key    string
-}
-
-func (b *backend) Hash(ignores map[IgnoreKey]struct{}) (uint32, error) {
-	h := crc32.New(crc32.MakeTable(crc32.Castagnoli))
-
-	b.mu.RLock()
-	defer b.mu.RUnlock()
-	err := b.db.View(func(tx *bolt.Tx) error {
-		c := tx.Cursor()
-		for next, _ := c.First(); next != nil; next, _ = c.Next() {
-			b := tx.Bucket(next)
-			if b == nil {
-				return fmt.Errorf("cannot get hash of bucket %s", string(next))
-			}
-			h.Write(next)
-			b.ForEach(func(k, v []byte) error {
-				bk := IgnoreKey{Bucket: string(next), Key: string(k)}
-				if _, ok := ignores[bk]; !ok {
-					h.Write(k)
-					h.Write(v)
-				}
-				return nil
-			})
-		}
-		return nil
-	})
-
-	if err != nil {
-		return 0, err
-	}
-
-	return h.Sum32(), nil
-}
-
-func (b *backend) Size() int64 {
-	return atomic.LoadInt64(&b.size)
-}
-
-func (b *backend) SizeInUse() int64 {
-	return atomic.LoadInt64(&b.sizeInUse)
-}
-
-func (b *backend) run() {
-	defer close(b.donec)
-	t := time.NewTimer(b.batchInterval)
-	defer t.Stop()
-	for {
-		select {
-		case <-t.C:
-		case <-b.stopc:
-			b.batchTx.CommitAndStop()
-			return
-		}
-		b.batchTx.Commit()
-		t.Reset(b.batchInterval)
-	}
-}
-
-func (b *backend) Close() error {
-	close(b.stopc)
-	<-b.donec
-	return b.db.Close()
-}
-
-// Commits returns total number of commits since start
-func (b *backend) Commits() int64 {
-	return atomic.LoadInt64(&b.commits)
-}
-
-func (b *backend) Defrag() error {
-	return b.defrag()
-}
-
-func (b *backend) defrag() error {
-	now := time.Now()
-	
-	// TODO: make this non-blocking?
-	// lock batchTx to ensure nobody is using previous tx, and then
-	// close previous ongoing tx.
-	b.batchTx.Lock()
-	defer b.batchTx.Unlock()
-
-	// lock database after lock tx to avoid deadlock.
-	b.mu.Lock()
-	defer b.mu.Unlock()
-
-	// block concurrent read requests while resetting tx
-	b.readTx.mu.Lock()
-	defer b.readTx.mu.Unlock()
-
-	b.batchTx.unsafeCommit(true)
-	b.batchTx.tx = nil
-
-	tmpdb, err := bolt.Open(b.db.Path()+".tmp", 0600, boltOpenOptions)
-	if err != nil {
-		return err
-	}
-
-	err = defragdb(b.db, tmpdb, defragLimit)
-
-	if err != nil {
-		tmpdb.Close()
-		os.RemoveAll(tmpdb.Path())
-		return err
-	}
-
-	dbp := b.db.Path()
-	tdbp := tmpdb.Path()
-
-	err = b.db.Close()
-	if err != nil {
-		plog.Fatalf("cannot close database (%s)", err)
-	}
-	err = tmpdb.Close()
-	if err != nil {
-		plog.Fatalf("cannot close database (%s)", err)
-	}
-	err = os.Rename(tdbp, dbp)
-	if err != nil {
-		plog.Fatalf("cannot rename database (%s)", err)
-	}
-
-	b.db, err = bolt.Open(dbp, 0600, boltOpenOptions)
-	if err != nil {
-		plog.Panicf("cannot open database at %s (%v)", dbp, err)
-	}
-	b.batchTx.tx, err = b.db.Begin(true)
-	if err != nil {
-		plog.Fatalf("cannot begin tx (%s)", err)
-	}
-
-	b.readTx.reset()
-	b.readTx.tx = b.unsafeBegin(false)
-
-	size := b.readTx.tx.Size()
-	db := b.db
-	atomic.StoreInt64(&b.size, size)
-	atomic.StoreInt64(&b.sizeInUse, size-(int64(db.Stats().FreePageN)*int64(db.Info().PageSize)))
-
-	took := time.Since(now)
-	defragDurations.Observe(took.Seconds())
-
-	return nil
-}
-
-func defragdb(odb, tmpdb *bolt.DB, limit int) error {
-	// open a tx on tmpdb for writes
-	tmptx, err := tmpdb.Begin(true)
-	if err != nil {
-		return err
-	}
-
-	// open a tx on old db for read
-	tx, err := odb.Begin(false)
-	if err != nil {
-		return err
-	}
-	defer tx.Rollback()
-
-	c := tx.Cursor()
-
-	count := 0
-	for next, _ := c.First(); next != nil; next, _ = c.Next() {
-		b := tx.Bucket(next)
-		if b == nil {
-			return fmt.Errorf("backend: cannot defrag bucket %s", string(next))
-		}
-
-		tmpb, berr := tmptx.CreateBucketIfNotExists(next)
-		if berr != nil {
-			return berr
-		}
-		tmpb.FillPercent = 0.9 // for seq write in for each
-
-		b.ForEach(func(k, v []byte) error {
-			count++
-			if count > limit {
-				err = tmptx.Commit()
-				if err != nil {
-					return err
-				}
-				tmptx, err = tmpdb.Begin(true)
-				if err != nil {
-					return err
-				}
-				tmpb = tmptx.Bucket(next)
-				tmpb.FillPercent = 0.9 // for seq write in for each
-
-				count = 0
-			}
-			return tmpb.Put(k, v)
-		})
-	}
-
-	return tmptx.Commit()
-}
-
-func (b *backend) begin(write bool) *bolt.Tx {
-	b.mu.RLock()
-	tx := b.unsafeBegin(write)
-	b.mu.RUnlock()
-
-	size := tx.Size()
-	db := tx.DB()
-	atomic.StoreInt64(&b.size, size)
-	atomic.StoreInt64(&b.sizeInUse, size-(int64(db.Stats().FreePageN)*int64(db.Info().PageSize)))
-
-	return tx
-}
-
-func (b *backend) unsafeBegin(write bool) *bolt.Tx {
-	tx, err := b.db.Begin(write)
-	if err != nil {
-		plog.Fatalf("cannot begin tx (%s)", err)
-	}
-	return tx
-}
-
-// NewTmpBackend creates a backend implementation for testing.
-func NewTmpBackend(batchInterval time.Duration, batchLimit int) (*backend, string) {
-	dir, err := ioutil.TempDir(os.TempDir(), "etcd_backend_test")
-	if err != nil {
-		plog.Fatal(err)
-	}
-	tmpPath := filepath.Join(dir, "database")
-	bcfg := DefaultBackendConfig()
-	bcfg.Path, bcfg.BatchInterval, bcfg.BatchLimit = tmpPath, batchInterval, batchLimit
-	return newBackend(bcfg), tmpPath
-}
-
-func NewDefaultTmpBackend() (*backend, string) {
-	return NewTmpBackend(defaultBatchInterval, defaultBatchLimit)
-}
-
-type snapshot struct {
-	*bolt.Tx
-	stopc chan struct{}
-	donec chan struct{}
-}
-
-func (s *snapshot) Close() error {
-	close(s.stopc)
-	<-s.donec
-	return s.Tx.Rollback()
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/batch_tx.go b/vendor/github.com/coreos/etcd/mvcc/backend/batch_tx.go
deleted file mode 100644
index aed6893..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/backend/batch_tx.go
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package backend
-
-import (
-	"bytes"
-	"math"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	bolt "github.com/coreos/bbolt"
-)
-
-type BatchTx interface {
-	ReadTx
-	UnsafeCreateBucket(name []byte)
-	UnsafePut(bucketName []byte, key []byte, value []byte)
-	UnsafeSeqPut(bucketName []byte, key []byte, value []byte)
-	UnsafeDelete(bucketName []byte, key []byte)
-	// Commit commits a previous tx and begins a new writable one.
-	Commit()
-	// CommitAndStop commits the previous tx and does not create a new one.
-	CommitAndStop()
-}
-
-type batchTx struct {
-	sync.Mutex
-	tx      *bolt.Tx
-	backend *backend
-
-	pending int
-}
-
-func (t *batchTx) UnsafeCreateBucket(name []byte) {
-	_, err := t.tx.CreateBucket(name)
-	if err != nil && err != bolt.ErrBucketExists {
-		plog.Fatalf("cannot create bucket %s (%v)", name, err)
-	}
-	t.pending++
-}
-
-// UnsafePut must be called holding the lock on the tx.
-func (t *batchTx) UnsafePut(bucketName []byte, key []byte, value []byte) {
-	t.unsafePut(bucketName, key, value, false)
-}
-
-// UnsafeSeqPut must be called holding the lock on the tx.
-func (t *batchTx) UnsafeSeqPut(bucketName []byte, key []byte, value []byte) {
-	t.unsafePut(bucketName, key, value, true)
-}
-
-func (t *batchTx) unsafePut(bucketName []byte, key []byte, value []byte, seq bool) {
-	bucket := t.tx.Bucket(bucketName)
-	if bucket == nil {
-		plog.Fatalf("bucket %s does not exist", bucketName)
-	}
-	if seq {
-		// it is useful to increase fill percent when the workloads are mostly append-only.
-		// this can delay the page split and reduce space usage.
-		bucket.FillPercent = 0.9
-	}
-	if err := bucket.Put(key, value); err != nil {
-		plog.Fatalf("cannot put key into bucket (%v)", err)
-	}
-	t.pending++
-}
-
-// UnsafeRange must be called holding the lock on the tx.
-func (t *batchTx) UnsafeRange(bucketName, key, endKey []byte, limit int64) ([][]byte, [][]byte) {
-	bucket := t.tx.Bucket(bucketName)
-	if bucket == nil {
-		plog.Fatalf("bucket %s does not exist", bucketName)
-	}
-	return unsafeRange(bucket.Cursor(), key, endKey, limit)
-}
-
-func unsafeRange(c *bolt.Cursor, key, endKey []byte, limit int64) (keys [][]byte, vs [][]byte) {
-	if limit <= 0 {
-		limit = math.MaxInt64
-	}
-	var isMatch func(b []byte) bool
-	if len(endKey) > 0 {
-		isMatch = func(b []byte) bool { return bytes.Compare(b, endKey) < 0 }
-	} else {
-		isMatch = func(b []byte) bool { return bytes.Equal(b, key) }
-		limit = 1
-	}
-	for ck, cv := c.Seek(key); ck != nil && isMatch(ck); ck, cv = c.Next() {
-		vs = append(vs, cv)
-		keys = append(keys, ck)
-		if limit == int64(len(keys)) {
-			break
-		}
-	}
-	return keys, vs
-}
-
-// UnsafeDelete must be called holding the lock on the tx.
-func (t *batchTx) UnsafeDelete(bucketName []byte, key []byte) {
-	bucket := t.tx.Bucket(bucketName)
-	if bucket == nil {
-		plog.Fatalf("bucket %s does not exist", bucketName)
-	}
-	err := bucket.Delete(key)
-	if err != nil {
-		plog.Fatalf("cannot delete key from bucket (%v)", err)
-	}
-	t.pending++
-}
-
-// UnsafeForEach must be called holding the lock on the tx.
-func (t *batchTx) UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error {
-	return unsafeForEach(t.tx, bucketName, visitor)
-}
-
-func unsafeForEach(tx *bolt.Tx, bucket []byte, visitor func(k, v []byte) error) error {
-	if b := tx.Bucket(bucket); b != nil {
-		return b.ForEach(visitor)
-	}
-	return nil
-}
-
-// Commit commits a previous tx and begins a new writable one.
-func (t *batchTx) Commit() {
-	t.Lock()
-	t.commit(false)
-	t.Unlock()
-}
-
-// CommitAndStop commits the previous tx and does not create a new one.
-func (t *batchTx) CommitAndStop() {
-	t.Lock()
-	t.commit(true)
-	t.Unlock()
-}
-
-func (t *batchTx) Unlock() {
-	if t.pending >= t.backend.batchLimit {
-		t.commit(false)
-	}
-	t.Mutex.Unlock()
-}
-
-func (t *batchTx) commit(stop bool) {
-	// commit the last tx
-	if t.tx != nil {
-		if t.pending == 0 && !stop {
-			return
-		}
-
-		start := time.Now()
-
-		// gofail: var beforeCommit struct{}
-		err := t.tx.Commit()
-		// gofail: var afterCommit struct{}
-
-		commitDurations.Observe(time.Since(start).Seconds())
-		atomic.AddInt64(&t.backend.commits, 1)
-
-		t.pending = 0
-		if err != nil {
-			plog.Fatalf("cannot commit tx (%s)", err)
-		}
-	}
-	if !stop {
-		t.tx = t.backend.begin(true)
-	}
-}
-
-type batchTxBuffered struct {
-	batchTx
-	buf txWriteBuffer
-}
-
-func newBatchTxBuffered(backend *backend) *batchTxBuffered {
-	tx := &batchTxBuffered{
-		batchTx: batchTx{backend: backend},
-		buf: txWriteBuffer{
-			txBuffer: txBuffer{make(map[string]*bucketBuffer)},
-			seq:      true,
-		},
-	}
-	tx.Commit()
-	return tx
-}
-
-func (t *batchTxBuffered) Unlock() {
-	if t.pending != 0 {
-		t.backend.readTx.mu.Lock()
-		t.buf.writeback(&t.backend.readTx.buf)
-		t.backend.readTx.mu.Unlock()
-		if t.pending >= t.backend.batchLimit {
-			t.commit(false)
-		}
-	}
-	t.batchTx.Unlock()
-}
-
-func (t *batchTxBuffered) Commit() {
-	t.Lock()
-	t.commit(false)
-	t.Unlock()
-}
-
-func (t *batchTxBuffered) CommitAndStop() {
-	t.Lock()
-	t.commit(true)
-	t.Unlock()
-}
-
-func (t *batchTxBuffered) commit(stop bool) {
-	// all read txs must be closed to acquire boltdb commit rwlock
-	t.backend.readTx.mu.Lock()
-	t.unsafeCommit(stop)
-	t.backend.readTx.mu.Unlock()
-}
-
-func (t *batchTxBuffered) unsafeCommit(stop bool) {
-	if t.backend.readTx.tx != nil {
-		if err := t.backend.readTx.tx.Rollback(); err != nil {
-			plog.Fatalf("cannot rollback tx (%s)", err)
-		}
-		t.backend.readTx.reset()
-	}
-
-	t.batchTx.commit(stop)
-
-	if !stop {
-		t.backend.readTx.tx = t.backend.begin(false)
-	}
-}
-
-func (t *batchTxBuffered) UnsafePut(bucketName []byte, key []byte, value []byte) {
-	t.batchTx.UnsafePut(bucketName, key, value)
-	t.buf.put(bucketName, key, value)
-}
-
-func (t *batchTxBuffered) UnsafeSeqPut(bucketName []byte, key []byte, value []byte) {
-	t.batchTx.UnsafeSeqPut(bucketName, key, value)
-	t.buf.putSeq(bucketName, key, value)
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/config_default.go b/vendor/github.com/coreos/etcd/mvcc/backend/config_default.go
deleted file mode 100644
index edfed00..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/backend/config_default.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !linux,!windows
-
-package backend
-
-import bolt "github.com/coreos/bbolt"
-
-var boltOpenOptions *bolt.Options = nil
-
-func (bcfg *BackendConfig) mmapSize() int { return int(bcfg.MmapSize) }
diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/config_linux.go b/vendor/github.com/coreos/etcd/mvcc/backend/config_linux.go
deleted file mode 100644
index b01785f..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/backend/config_linux.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package backend
-
-import (
-	"syscall"
-
-	bolt "github.com/coreos/bbolt"
-)
-
-// syscall.MAP_POPULATE on linux 2.6.23+ does sequential read-ahead
-// which can speed up entire-database read with boltdb. We want to
-// enable MAP_POPULATE for faster key-value store recovery in storage
-// package. If your kernel version is lower than 2.6.23
-// (https://github.com/torvalds/linux/releases/tag/v2.6.23), mmap might
-// silently ignore this flag. Please update your kernel to prevent this.
-var boltOpenOptions = &bolt.Options{
-	MmapFlags:      syscall.MAP_POPULATE,
-	NoFreelistSync: true,
-}
-
-func (bcfg *BackendConfig) mmapSize() int { return int(bcfg.MmapSize) }
diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/config_windows.go b/vendor/github.com/coreos/etcd/mvcc/backend/config_windows.go
deleted file mode 100644
index 71d0270..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/backend/config_windows.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build windows
-
-package backend
-
-import bolt "github.com/coreos/bbolt"
-
-var boltOpenOptions *bolt.Options = nil
-
-// setting mmap size != 0 on windows will allocate the entire
-// mmap size for the file, instead of growing it. So, force 0.
-
-func (bcfg *BackendConfig) mmapSize() int { return 0 }
diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/doc.go b/vendor/github.com/coreos/etcd/mvcc/backend/doc.go
deleted file mode 100644
index 9cc42fa..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/backend/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package backend defines a standard interface for etcd's backend MVCC storage.
-package backend
diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/metrics.go b/vendor/github.com/coreos/etcd/mvcc/backend/metrics.go
deleted file mode 100644
index 3415708..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/backend/metrics.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package backend
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	commitDurations = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "disk",
-		Name:      "backend_commit_duration_seconds",
-		Help:      "The latency distributions of commit called by backend.",
-
-		// lowest bucket start of upper bound 0.001 sec (1 ms) with factor 2
-		// highest bucket start of 0.001 sec * 2^13 == 8.192 sec
-		Buckets: prometheus.ExponentialBuckets(0.001, 2, 14),
-	})
-
-	defragDurations = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "disk",
-		Name:      "backend_defrag_duration_seconds",
-		Help:      "The latency distribution of backend defragmentation.",
-
-		// 100 MB usually takes 1 sec, so start with 10 MB of 100 ms
-		// lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2
-		// highest bucket start of 0.1 sec * 2^12 == 409.6 sec
-		Buckets: prometheus.ExponentialBuckets(.1, 2, 13),
-	})
-
-	snapshotDurations = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "disk",
-		Name:      "backend_snapshot_duration_seconds",
-		Help:      "The latency distribution of backend snapshots.",
-
-		// lowest bucket start of upper bound 0.01 sec (10 ms) with factor 2
-		// highest bucket start of 0.01 sec * 2^16 == 655.36 sec
-		Buckets: prometheus.ExponentialBuckets(.01, 2, 17),
-	})
-)
-
-func init() {
-	prometheus.MustRegister(commitDurations)
-	prometheus.MustRegister(defragDurations)
-	prometheus.MustRegister(snapshotDurations)
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/read_tx.go b/vendor/github.com/coreos/etcd/mvcc/backend/read_tx.go
deleted file mode 100644
index 0536de7..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/backend/read_tx.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package backend
-
-import (
-	"bytes"
-	"math"
-	"sync"
-
-	bolt "github.com/coreos/bbolt"
-)
-
-// safeRangeBucket is a hack to avoid inadvertently reading duplicate keys;
-// overwrites on a bucket should only fetch with limit=1, but safeRangeBucket
-// is known to never overwrite any key so range is safe.
-var safeRangeBucket = []byte("key")
-
-type ReadTx interface {
-	Lock()
-	Unlock()
-
-	UnsafeRange(bucketName []byte, key, endKey []byte, limit int64) (keys [][]byte, vals [][]byte)
-	UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error
-}
-
-type readTx struct {
-	// mu protects accesses to the txReadBuffer
-	mu  sync.RWMutex
-	buf txReadBuffer
-
-	// txmu protects accesses to buckets and tx on Range requests.
-	txmu    sync.RWMutex
-	tx      *bolt.Tx
-	buckets map[string]*bolt.Bucket
-}
-
-func (rt *readTx) Lock()   { rt.mu.RLock() }
-func (rt *readTx) Unlock() { rt.mu.RUnlock() }
-
-func (rt *readTx) UnsafeRange(bucketName, key, endKey []byte, limit int64) ([][]byte, [][]byte) {
-	if endKey == nil {
-		// forbid duplicates for single keys
-		limit = 1
-	}
-	if limit <= 0 {
-		limit = math.MaxInt64
-	}
-	if limit > 1 && !bytes.Equal(bucketName, safeRangeBucket) {
-		panic("do not use unsafeRange on non-keys bucket")
-	}
-	keys, vals := rt.buf.Range(bucketName, key, endKey, limit)
-	if int64(len(keys)) == limit {
-		return keys, vals
-	}
-
-	// find/cache bucket
-	bn := string(bucketName)
-	rt.txmu.RLock()
-	bucket, ok := rt.buckets[bn]
-	rt.txmu.RUnlock()
-	if !ok {
-		rt.txmu.Lock()
-		bucket = rt.tx.Bucket(bucketName)
-		rt.buckets[bn] = bucket
-		rt.txmu.Unlock()
-	}
-
-	// ignore missing bucket since may have been created in this batch
-	if bucket == nil {
-		return keys, vals
-	}
-	rt.txmu.Lock()
-	c := bucket.Cursor()
-	rt.txmu.Unlock()
-
-	k2, v2 := unsafeRange(c, key, endKey, limit-int64(len(keys)))
-	return append(k2, keys...), append(v2, vals...)
-}
-
-func (rt *readTx) UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error {
-	dups := make(map[string]struct{})
-	getDups := func(k, v []byte) error {
-		dups[string(k)] = struct{}{}
-		return nil
-	}
-	visitNoDup := func(k, v []byte) error {
-		if _, ok := dups[string(k)]; ok {
-			return nil
-		}
-		return visitor(k, v)
-	}
-	if err := rt.buf.ForEach(bucketName, getDups); err != nil {
-		return err
-	}
-	rt.txmu.Lock()
-	err := unsafeForEach(rt.tx, bucketName, visitNoDup)
-	rt.txmu.Unlock()
-	if err != nil {
-		return err
-	}
-	return rt.buf.ForEach(bucketName, visitor)
-}
-
-func (rt *readTx) reset() {
-	rt.buf.reset()
-	rt.buckets = make(map[string]*bolt.Bucket)
-	rt.tx = nil
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/backend/tx_buffer.go b/vendor/github.com/coreos/etcd/mvcc/backend/tx_buffer.go
deleted file mode 100644
index 56e885d..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/backend/tx_buffer.go
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package backend
-
-import (
-	"bytes"
-	"sort"
-)
-
-// txBuffer handles functionality shared between txWriteBuffer and txReadBuffer.
-type txBuffer struct {
-	buckets map[string]*bucketBuffer
-}
-
-func (txb *txBuffer) reset() {
-	for k, v := range txb.buckets {
-		if v.used == 0 {
-			// demote
-			delete(txb.buckets, k)
-		}
-		v.used = 0
-	}
-}
-
-// txWriteBuffer buffers writes of pending updates that have not yet committed.
-type txWriteBuffer struct {
-	txBuffer
-	seq bool
-}
-
-func (txw *txWriteBuffer) put(bucket, k, v []byte) {
-	txw.seq = false
-	txw.putSeq(bucket, k, v)
-}
-
-func (txw *txWriteBuffer) putSeq(bucket, k, v []byte) {
-	b, ok := txw.buckets[string(bucket)]
-	if !ok {
-		b = newBucketBuffer()
-		txw.buckets[string(bucket)] = b
-	}
-	b.add(k, v)
-}
-
-func (txw *txWriteBuffer) writeback(txr *txReadBuffer) {
-	for k, wb := range txw.buckets {
-		rb, ok := txr.buckets[k]
-		if !ok {
-			delete(txw.buckets, k)
-			txr.buckets[k] = wb
-			continue
-		}
-		if !txw.seq && wb.used > 1 {
-			// assume no duplicate keys
-			sort.Sort(wb)
-		}
-		rb.merge(wb)
-	}
-	txw.reset()
-}
-
-// txReadBuffer accesses buffered updates.
-type txReadBuffer struct{ txBuffer }
-
-func (txr *txReadBuffer) Range(bucketName, key, endKey []byte, limit int64) ([][]byte, [][]byte) {
-	if b := txr.buckets[string(bucketName)]; b != nil {
-		return b.Range(key, endKey, limit)
-	}
-	return nil, nil
-}
-
-func (txr *txReadBuffer) ForEach(bucketName []byte, visitor func(k, v []byte) error) error {
-	if b := txr.buckets[string(bucketName)]; b != nil {
-		return b.ForEach(visitor)
-	}
-	return nil
-}
-
-type kv struct {
-	key []byte
-	val []byte
-}
-
-// bucketBuffer buffers key-value pairs that are pending commit.
-type bucketBuffer struct {
-	buf []kv
-	// used tracks number of elements in use so buf can be reused without reallocation.
-	used int
-}
-
-func newBucketBuffer() *bucketBuffer {
-	return &bucketBuffer{buf: make([]kv, 512), used: 0}
-}
-
-func (bb *bucketBuffer) Range(key, endKey []byte, limit int64) (keys [][]byte, vals [][]byte) {
-	f := func(i int) bool { return bytes.Compare(bb.buf[i].key, key) >= 0 }
-	idx := sort.Search(bb.used, f)
-	if idx < 0 {
-		return nil, nil
-	}
-	if len(endKey) == 0 {
-		if bytes.Equal(key, bb.buf[idx].key) {
-			keys = append(keys, bb.buf[idx].key)
-			vals = append(vals, bb.buf[idx].val)
-		}
-		return keys, vals
-	}
-	if bytes.Compare(endKey, bb.buf[idx].key) <= 0 {
-		return nil, nil
-	}
-	for i := idx; i < bb.used && int64(len(keys)) < limit; i++ {
-		if bytes.Compare(endKey, bb.buf[i].key) <= 0 {
-			break
-		}
-		keys = append(keys, bb.buf[i].key)
-		vals = append(vals, bb.buf[i].val)
-	}
-	return keys, vals
-}
-
-func (bb *bucketBuffer) ForEach(visitor func(k, v []byte) error) error {
-	for i := 0; i < bb.used; i++ {
-		if err := visitor(bb.buf[i].key, bb.buf[i].val); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (bb *bucketBuffer) add(k, v []byte) {
-	bb.buf[bb.used].key, bb.buf[bb.used].val = k, v
-	bb.used++
-	if bb.used == len(bb.buf) {
-		buf := make([]kv, (3*len(bb.buf))/2)
-		copy(buf, bb.buf)
-		bb.buf = buf
-	}
-}
-
-// merge merges data from bb into bbsrc.
-func (bb *bucketBuffer) merge(bbsrc *bucketBuffer) {
-	for i := 0; i < bbsrc.used; i++ {
-		bb.add(bbsrc.buf[i].key, bbsrc.buf[i].val)
-	}
-	if bb.used == bbsrc.used {
-		return
-	}
-	if bytes.Compare(bb.buf[(bb.used-bbsrc.used)-1].key, bbsrc.buf[0].key) < 0 {
-		return
-	}
-
-	sort.Stable(bb)
-
-	// remove duplicates, using only newest update
-	widx := 0
-	for ridx := 1; ridx < bb.used; ridx++ {
-		if !bytes.Equal(bb.buf[ridx].key, bb.buf[widx].key) {
-			widx++
-		}
-		bb.buf[widx] = bb.buf[ridx]
-	}
-	bb.used = widx + 1
-}
-
-func (bb *bucketBuffer) Len() int { return bb.used }
-func (bb *bucketBuffer) Less(i, j int) bool {
-	return bytes.Compare(bb.buf[i].key, bb.buf[j].key) < 0
-}
-func (bb *bucketBuffer) Swap(i, j int) { bb.buf[i], bb.buf[j] = bb.buf[j], bb.buf[i] }
diff --git a/vendor/github.com/coreos/etcd/mvcc/doc.go b/vendor/github.com/coreos/etcd/mvcc/doc.go
deleted file mode 100644
index ad5be03..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package mvcc defines etcd's stable MVCC storage.
-package mvcc
diff --git a/vendor/github.com/coreos/etcd/mvcc/index.go b/vendor/github.com/coreos/etcd/mvcc/index.go
deleted file mode 100644
index b27a9e5..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/index.go
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"sort"
-	"sync"
-
-	"github.com/google/btree"
-)
-
-type index interface {
-	Get(key []byte, atRev int64) (rev, created revision, ver int64, err error)
-	Range(key, end []byte, atRev int64) ([][]byte, []revision)
-	Revisions(key, end []byte, atRev int64) []revision
-	Put(key []byte, rev revision)
-	Tombstone(key []byte, rev revision) error
-	RangeSince(key, end []byte, rev int64) []revision
-	Compact(rev int64) map[revision]struct{}
-	Keep(rev int64) map[revision]struct{}
-	Equal(b index) bool
-
-	Insert(ki *keyIndex)
-	KeyIndex(ki *keyIndex) *keyIndex
-}
-
-type treeIndex struct {
-	sync.RWMutex
-	tree *btree.BTree
-}
-
-func newTreeIndex() index {
-	return &treeIndex{
-		tree: btree.New(32),
-	}
-}
-
-func (ti *treeIndex) Put(key []byte, rev revision) {
-	keyi := &keyIndex{key: key}
-
-	ti.Lock()
-	defer ti.Unlock()
-	item := ti.tree.Get(keyi)
-	if item == nil {
-		keyi.put(rev.main, rev.sub)
-		ti.tree.ReplaceOrInsert(keyi)
-		return
-	}
-	okeyi := item.(*keyIndex)
-	okeyi.put(rev.main, rev.sub)
-}
-
-func (ti *treeIndex) Get(key []byte, atRev int64) (modified, created revision, ver int64, err error) {
-	keyi := &keyIndex{key: key}
-	ti.RLock()
-	defer ti.RUnlock()
-	if keyi = ti.keyIndex(keyi); keyi == nil {
-		return revision{}, revision{}, 0, ErrRevisionNotFound
-	}
-	return keyi.get(atRev)
-}
-
-func (ti *treeIndex) KeyIndex(keyi *keyIndex) *keyIndex {
-	ti.RLock()
-	defer ti.RUnlock()
-	return ti.keyIndex(keyi)
-}
-
-func (ti *treeIndex) keyIndex(keyi *keyIndex) *keyIndex {
-	if item := ti.tree.Get(keyi); item != nil {
-		return item.(*keyIndex)
-	}
-	return nil
-}
-
-func (ti *treeIndex) visit(key, end []byte, f func(ki *keyIndex)) {
-	keyi, endi := &keyIndex{key: key}, &keyIndex{key: end}
-
-	ti.RLock()
-	defer ti.RUnlock()
-
-	ti.tree.AscendGreaterOrEqual(keyi, func(item btree.Item) bool {
-		if len(endi.key) > 0 && !item.Less(endi) {
-			return false
-		}
-		f(item.(*keyIndex))
-		return true
-	})
-}
-
-func (ti *treeIndex) Revisions(key, end []byte, atRev int64) (revs []revision) {
-	if end == nil {
-		rev, _, _, err := ti.Get(key, atRev)
-		if err != nil {
-			return nil
-		}
-		return []revision{rev}
-	}
-	ti.visit(key, end, func(ki *keyIndex) {
-		if rev, _, _, err := ki.get(atRev); err == nil {
-			revs = append(revs, rev)
-		}
-	})
-	return revs
-}
-
-func (ti *treeIndex) Range(key, end []byte, atRev int64) (keys [][]byte, revs []revision) {
-	if end == nil {
-		rev, _, _, err := ti.Get(key, atRev)
-		if err != nil {
-			return nil, nil
-		}
-		return [][]byte{key}, []revision{rev}
-	}
-	ti.visit(key, end, func(ki *keyIndex) {
-		if rev, _, _, err := ki.get(atRev); err == nil {
-			revs = append(revs, rev)
-			keys = append(keys, ki.key)
-		}
-	})
-	return keys, revs
-}
-
-func (ti *treeIndex) Tombstone(key []byte, rev revision) error {
-	keyi := &keyIndex{key: key}
-
-	ti.Lock()
-	defer ti.Unlock()
-	item := ti.tree.Get(keyi)
-	if item == nil {
-		return ErrRevisionNotFound
-	}
-
-	ki := item.(*keyIndex)
-	return ki.tombstone(rev.main, rev.sub)
-}
-
-// RangeSince returns all revisions from key(including) to end(excluding)
-// at or after the given rev. The returned slice is sorted in the order
-// of revision.
-func (ti *treeIndex) RangeSince(key, end []byte, rev int64) []revision {
-	keyi := &keyIndex{key: key}
-
-	ti.RLock()
-	defer ti.RUnlock()
-
-	if end == nil {
-		item := ti.tree.Get(keyi)
-		if item == nil {
-			return nil
-		}
-		keyi = item.(*keyIndex)
-		return keyi.since(rev)
-	}
-
-	endi := &keyIndex{key: end}
-	var revs []revision
-	ti.tree.AscendGreaterOrEqual(keyi, func(item btree.Item) bool {
-		if len(endi.key) > 0 && !item.Less(endi) {
-			return false
-		}
-		curKeyi := item.(*keyIndex)
-		revs = append(revs, curKeyi.since(rev)...)
-		return true
-	})
-	sort.Sort(revisions(revs))
-
-	return revs
-}
-
-func (ti *treeIndex) Compact(rev int64) map[revision]struct{} {
-	available := make(map[revision]struct{})
-	var emptyki []*keyIndex
-	plog.Printf("store.index: compact %d", rev)
-	// TODO: do not hold the lock for long time?
-	// This is probably OK. Compacting 10M keys takes O(10ms).
-	ti.Lock()
-	defer ti.Unlock()
-	ti.tree.Ascend(compactIndex(rev, available, &emptyki))
-	for _, ki := range emptyki {
-		item := ti.tree.Delete(ki)
-		if item == nil {
-			plog.Panic("store.index: unexpected delete failure during compaction")
-		}
-	}
-	return available
-}
-
-// Keep finds all revisions to be kept for a Compaction at the given rev.
-func (ti *treeIndex) Keep(rev int64) map[revision]struct{} {
-	available := make(map[revision]struct{})
-	ti.RLock()
-	defer ti.RUnlock()
-	ti.tree.Ascend(func(i btree.Item) bool {
-		keyi := i.(*keyIndex)
-		keyi.keep(rev, available)
-		return true
-	})
-	return available
-}
-
-func compactIndex(rev int64, available map[revision]struct{}, emptyki *[]*keyIndex) func(i btree.Item) bool {
-	return func(i btree.Item) bool {
-		keyi := i.(*keyIndex)
-		keyi.compact(rev, available)
-		if keyi.isEmpty() {
-			*emptyki = append(*emptyki, keyi)
-		}
-		return true
-	}
-}
-
-func (ti *treeIndex) Equal(bi index) bool {
-	b := bi.(*treeIndex)
-
-	if ti.tree.Len() != b.tree.Len() {
-		return false
-	}
-
-	equal := true
-
-	ti.tree.Ascend(func(item btree.Item) bool {
-		aki := item.(*keyIndex)
-		bki := b.tree.Get(item).(*keyIndex)
-		if !aki.equal(bki) {
-			equal = false
-			return false
-		}
-		return true
-	})
-
-	return equal
-}
-
-func (ti *treeIndex) Insert(ki *keyIndex) {
-	ti.Lock()
-	defer ti.Unlock()
-	ti.tree.ReplaceOrInsert(ki)
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/key_index.go b/vendor/github.com/coreos/etcd/mvcc/key_index.go
deleted file mode 100644
index 805922b..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/key_index.go
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-
-	"github.com/google/btree"
-)
-
-var (
-	ErrRevisionNotFound = errors.New("mvcc: revision not found")
-)
-
-// keyIndex stores the revisions of a key in the backend.
-// Each keyIndex has at least one key generation.
-// Each generation might have several key versions.
-// Tombstone on a key appends an tombstone version at the end
-// of the current generation and creates a new empty generation.
-// Each version of a key has an index pointing to the backend.
-//
-// For example: put(1.0);put(2.0);tombstone(3.0);put(4.0);tombstone(5.0) on key "foo"
-// generate a keyIndex:
-// key:     "foo"
-// rev: 5
-// generations:
-//    {empty}
-//    {4.0, 5.0(t)}
-//    {1.0, 2.0, 3.0(t)}
-//
-// Compact a keyIndex removes the versions with smaller or equal to
-// rev except the largest one. If the generation becomes empty
-// during compaction, it will be removed. if all the generations get
-// removed, the keyIndex should be removed.
-//
-// For example:
-// compact(2) on the previous example
-// generations:
-//    {empty}
-//    {4.0, 5.0(t)}
-//    {2.0, 3.0(t)}
-//
-// compact(4)
-// generations:
-//    {empty}
-//    {4.0, 5.0(t)}
-//
-// compact(5):
-// generations:
-//    {empty} -> key SHOULD be removed.
-//
-// compact(6):
-// generations:
-//    {empty} -> key SHOULD be removed.
-type keyIndex struct {
-	key         []byte
-	modified    revision // the main rev of the last modification
-	generations []generation
-}
-
-// put puts a revision to the keyIndex.
-func (ki *keyIndex) put(main int64, sub int64) {
-	rev := revision{main: main, sub: sub}
-
-	if !rev.GreaterThan(ki.modified) {
-		plog.Panicf("store.keyindex: put with unexpected smaller revision [%v / %v]", rev, ki.modified)
-	}
-	if len(ki.generations) == 0 {
-		ki.generations = append(ki.generations, generation{})
-	}
-	g := &ki.generations[len(ki.generations)-1]
-	if len(g.revs) == 0 { // create a new key
-		keysGauge.Inc()
-		g.created = rev
-	}
-	g.revs = append(g.revs, rev)
-	g.ver++
-	ki.modified = rev
-}
-
-func (ki *keyIndex) restore(created, modified revision, ver int64) {
-	if len(ki.generations) != 0 {
-		plog.Panicf("store.keyindex: cannot restore non-empty keyIndex")
-	}
-
-	ki.modified = modified
-	g := generation{created: created, ver: ver, revs: []revision{modified}}
-	ki.generations = append(ki.generations, g)
-	keysGauge.Inc()
-}
-
-// tombstone puts a revision, pointing to a tombstone, to the keyIndex.
-// It also creates a new empty generation in the keyIndex.
-// It returns ErrRevisionNotFound when tombstone on an empty generation.
-func (ki *keyIndex) tombstone(main int64, sub int64) error {
-	if ki.isEmpty() {
-		plog.Panicf("store.keyindex: unexpected tombstone on empty keyIndex %s", string(ki.key))
-	}
-	if ki.generations[len(ki.generations)-1].isEmpty() {
-		return ErrRevisionNotFound
-	}
-	ki.put(main, sub)
-	ki.generations = append(ki.generations, generation{})
-	keysGauge.Dec()
-	return nil
-}
-
-// get gets the modified, created revision and version of the key that satisfies the given atRev.
-// Rev must be higher than or equal to the given atRev.
-func (ki *keyIndex) get(atRev int64) (modified, created revision, ver int64, err error) {
-	if ki.isEmpty() {
-		plog.Panicf("store.keyindex: unexpected get on empty keyIndex %s", string(ki.key))
-	}
-	g := ki.findGeneration(atRev)
-	if g.isEmpty() {
-		return revision{}, revision{}, 0, ErrRevisionNotFound
-	}
-
-	n := g.walk(func(rev revision) bool { return rev.main > atRev })
-	if n != -1 {
-		return g.revs[n], g.created, g.ver - int64(len(g.revs)-n-1), nil
-	}
-
-	return revision{}, revision{}, 0, ErrRevisionNotFound
-}
-
-// since returns revisions since the given rev. Only the revision with the
-// largest sub revision will be returned if multiple revisions have the same
-// main revision.
-func (ki *keyIndex) since(rev int64) []revision {
-	if ki.isEmpty() {
-		plog.Panicf("store.keyindex: unexpected get on empty keyIndex %s", string(ki.key))
-	}
-	since := revision{rev, 0}
-	var gi int
-	// find the generations to start checking
-	for gi = len(ki.generations) - 1; gi > 0; gi-- {
-		g := ki.generations[gi]
-		if g.isEmpty() {
-			continue
-		}
-		if since.GreaterThan(g.created) {
-			break
-		}
-	}
-
-	var revs []revision
-	var last int64
-	for ; gi < len(ki.generations); gi++ {
-		for _, r := range ki.generations[gi].revs {
-			if since.GreaterThan(r) {
-				continue
-			}
-			if r.main == last {
-				// replace the revision with a new one that has higher sub value,
-				// because the original one should not be seen by external
-				revs[len(revs)-1] = r
-				continue
-			}
-			revs = append(revs, r)
-			last = r.main
-		}
-	}
-	return revs
-}
-
-// compact compacts a keyIndex by removing the versions with smaller or equal
-// revision than the given atRev except the largest one (If the largest one is
-// a tombstone, it will not be kept).
-// If a generation becomes empty during compaction, it will be removed.
-func (ki *keyIndex) compact(atRev int64, available map[revision]struct{}) {
-	if ki.isEmpty() {
-		plog.Panicf("store.keyindex: unexpected compact on empty keyIndex %s", string(ki.key))
-	}
-
-	genIdx, revIndex := ki.doCompact(atRev, available)
-
-	g := &ki.generations[genIdx]
-	if !g.isEmpty() {
-		// remove the previous contents.
-		if revIndex != -1 {
-			g.revs = g.revs[revIndex:]
-		}
-		// remove any tombstone
-		if len(g.revs) == 1 && genIdx != len(ki.generations)-1 {
-			delete(available, g.revs[0])
-			genIdx++
-		}
-	}
-
-	// remove the previous generations.
-	ki.generations = ki.generations[genIdx:]
-}
-
-// keep finds the revision to be kept if compact is called at given atRev.
-func (ki *keyIndex) keep(atRev int64, available map[revision]struct{}) {
-	if ki.isEmpty() {
-		return
-	}
-
-	genIdx, revIndex := ki.doCompact(atRev, available)
-	g := &ki.generations[genIdx]
-	if !g.isEmpty() {
-		// remove any tombstone
-		if revIndex == len(g.revs)-1 && genIdx != len(ki.generations)-1 {
-			delete(available, g.revs[revIndex])
-		}
-	}
-}
-
-func (ki *keyIndex) doCompact(atRev int64, available map[revision]struct{}) (genIdx int, revIndex int) {
-	// walk until reaching the first revision smaller or equal to "atRev",
-	// and add the revision to the available map
-	f := func(rev revision) bool {
-		if rev.main <= atRev {
-			available[rev] = struct{}{}
-			return false
-		}
-		return true
-	}
-
-	genIdx, g := 0, &ki.generations[0]
-	// find first generation includes atRev or created after atRev
-	for genIdx < len(ki.generations)-1 {
-		if tomb := g.revs[len(g.revs)-1].main; tomb > atRev {
-			break
-		}
-		genIdx++
-		g = &ki.generations[genIdx]
-	}
-
-	revIndex = g.walk(f)
-
-	return genIdx, revIndex
-}
-
-func (ki *keyIndex) isEmpty() bool {
-	return len(ki.generations) == 1 && ki.generations[0].isEmpty()
-}
-
-// findGeneration finds out the generation of the keyIndex that the
-// given rev belongs to. If the given rev is at the gap of two generations,
-// which means that the key does not exist at the given rev, it returns nil.
-func (ki *keyIndex) findGeneration(rev int64) *generation {
-	lastg := len(ki.generations) - 1
-	cg := lastg
-
-	for cg >= 0 {
-		if len(ki.generations[cg].revs) == 0 {
-			cg--
-			continue
-		}
-		g := ki.generations[cg]
-		if cg != lastg {
-			if tomb := g.revs[len(g.revs)-1].main; tomb <= rev {
-				return nil
-			}
-		}
-		if g.revs[0].main <= rev {
-			return &ki.generations[cg]
-		}
-		cg--
-	}
-	return nil
-}
-
-func (a *keyIndex) Less(b btree.Item) bool {
-	return bytes.Compare(a.key, b.(*keyIndex).key) == -1
-}
-
-func (a *keyIndex) equal(b *keyIndex) bool {
-	if !bytes.Equal(a.key, b.key) {
-		return false
-	}
-	if a.modified != b.modified {
-		return false
-	}
-	if len(a.generations) != len(b.generations) {
-		return false
-	}
-	for i := range a.generations {
-		ag, bg := a.generations[i], b.generations[i]
-		if !ag.equal(bg) {
-			return false
-		}
-	}
-	return true
-}
-
-func (ki *keyIndex) String() string {
-	var s string
-	for _, g := range ki.generations {
-		s += g.String()
-	}
-	return s
-}
-
-// generation contains multiple revisions of a key.
-type generation struct {
-	ver     int64
-	created revision // when the generation is created (put in first revision).
-	revs    []revision
-}
-
-func (g *generation) isEmpty() bool { return g == nil || len(g.revs) == 0 }
-
-// walk walks through the revisions in the generation in descending order.
-// It passes the revision to the given function.
-// walk returns until: 1. it finishes walking all pairs 2. the function returns false.
-// walk returns the position at where it stopped. If it stopped after
-// finishing walking, -1 will be returned.
-func (g *generation) walk(f func(rev revision) bool) int {
-	l := len(g.revs)
-	for i := range g.revs {
-		ok := f(g.revs[l-i-1])
-		if !ok {
-			return l - i - 1
-		}
-	}
-	return -1
-}
-
-func (g *generation) String() string {
-	return fmt.Sprintf("g: created[%d] ver[%d], revs %#v\n", g.created, g.ver, g.revs)
-}
-
-func (a generation) equal(b generation) bool {
-	if a.ver != b.ver {
-		return false
-	}
-	if len(a.revs) != len(b.revs) {
-		return false
-	}
-
-	for i := range a.revs {
-		ar, br := a.revs[i], b.revs[i]
-		if ar != br {
-			return false
-		}
-	}
-	return true
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/kv.go b/vendor/github.com/coreos/etcd/mvcc/kv.go
deleted file mode 100644
index 2dad3ad..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/kv.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-type RangeOptions struct {
-	Limit int64
-	Rev   int64
-	Count bool
-}
-
-type RangeResult struct {
-	KVs   []mvccpb.KeyValue
-	Rev   int64
-	Count int
-}
-
-type ReadView interface {
-	// FirstRev returns the first KV revision at the time of opening the txn.
-	// After a compaction, the first revision increases to the compaction
-	// revision.
-	FirstRev() int64
-
-	// Rev returns the revision of the KV at the time of opening the txn.
-	Rev() int64
-
-	// Range gets the keys in the range at rangeRev.
-	// The returned rev is the current revision of the KV when the operation is executed.
-	// If rangeRev <=0, range gets the keys at currentRev.
-	// If `end` is nil, the request returns the key.
-	// If `end` is not nil and not empty, it gets the keys in range [key, range_end).
-	// If `end` is not nil and empty, it gets the keys greater than or equal to key.
-	// Limit limits the number of keys returned.
-	// If the required rev is compacted, ErrCompacted will be returned.
-	Range(key, end []byte, ro RangeOptions) (r *RangeResult, err error)
-}
-
-// TxnRead represents a read-only transaction with operations that will not
-// block other read transactions.
-type TxnRead interface {
-	ReadView
-	// End marks the transaction is complete and ready to commit.
-	End()
-}
-
-type WriteView interface {
-	// DeleteRange deletes the given range from the store.
-	// A deleteRange increases the rev of the store if any key in the range exists.
-	// The number of key deleted will be returned.
-	// The returned rev is the current revision of the KV when the operation is executed.
-	// It also generates one event for each key delete in the event history.
-	// if the `end` is nil, deleteRange deletes the key.
-	// if the `end` is not nil, deleteRange deletes the keys in range [key, range_end).
-	DeleteRange(key, end []byte) (n, rev int64)
-
-	// Put puts the given key, value into the store. Put also takes additional argument lease to
-	// attach a lease to a key-value pair as meta-data. KV implementation does not validate the lease
-	// id.
-	// A put also increases the rev of the store, and generates one event in the event history.
-	// The returned rev is the current revision of the KV when the operation is executed.
-	Put(key, value []byte, lease lease.LeaseID) (rev int64)
-}
-
-// TxnWrite represents a transaction that can modify the store.
-type TxnWrite interface {
-	TxnRead
-	WriteView
-	// Changes gets the changes made since opening the write txn.
-	Changes() []mvccpb.KeyValue
-}
-
-// txnReadWrite coerces a read txn to a write, panicking on any write operation.
-type txnReadWrite struct{ TxnRead }
-
-func (trw *txnReadWrite) DeleteRange(key, end []byte) (n, rev int64) { panic("unexpected DeleteRange") }
-func (trw *txnReadWrite) Put(key, value []byte, lease lease.LeaseID) (rev int64) {
-	panic("unexpected Put")
-}
-func (trw *txnReadWrite) Changes() []mvccpb.KeyValue { return nil }
-
-func NewReadOnlyTxnWrite(txn TxnRead) TxnWrite { return &txnReadWrite{txn} }
-
-type KV interface {
-	ReadView
-	WriteView
-
-	// Read creates a read transaction.
-	Read() TxnRead
-
-	// Write creates a write transaction.
-	Write() TxnWrite
-
-	// Hash computes the hash of the KV's backend.
-	Hash() (hash uint32, revision int64, err error)
-
-	// HashByRev computes the hash of all MVCC revisions up to a given revision.
-	HashByRev(rev int64) (hash uint32, revision int64, compactRev int64, err error)
-
-	// Compact frees all superseded keys with revisions less than rev.
-	Compact(rev int64) (<-chan struct{}, error)
-
-	// Commit commits outstanding txns into the underlying backend.
-	Commit()
-
-	// Restore restores the KV store from a backend.
-	Restore(b backend.Backend) error
-	Close() error
-}
-
-// WatchableKV is a KV that can be watched.
-type WatchableKV interface {
-	KV
-	Watchable
-}
-
-// Watchable is the interface that wraps the NewWatchStream function.
-type Watchable interface {
-	// NewWatchStream returns a WatchStream that can be used to
-	// watch events happened or happening on the KV.
-	NewWatchStream() WatchStream
-}
-
-// ConsistentWatchableKV is a WatchableKV that understands the consistency
-// algorithm and consistent index.
-// If the consistent index of executing entry is not larger than the
-// consistent index of ConsistentWatchableKV, all operations in
-// this entry are skipped and return empty response.
-type ConsistentWatchableKV interface {
-	WatchableKV
-	// ConsistentIndex returns the current consistent index of the KV.
-	ConsistentIndex() uint64
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/kv_view.go b/vendor/github.com/coreos/etcd/mvcc/kv_view.go
deleted file mode 100644
index f40ba8e..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/kv_view.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"github.com/coreos/etcd/lease"
-)
-
-type readView struct{ kv KV }
-
-func (rv *readView) FirstRev() int64 {
-	tr := rv.kv.Read()
-	defer tr.End()
-	return tr.FirstRev()
-}
-
-func (rv *readView) Rev() int64 {
-	tr := rv.kv.Read()
-	defer tr.End()
-	return tr.Rev()
-}
-
-func (rv *readView) Range(key, end []byte, ro RangeOptions) (r *RangeResult, err error) {
-	tr := rv.kv.Read()
-	defer tr.End()
-	return tr.Range(key, end, ro)
-}
-
-type writeView struct{ kv KV }
-
-func (wv *writeView) DeleteRange(key, end []byte) (n, rev int64) {
-	tw := wv.kv.Write()
-	defer tw.End()
-	return tw.DeleteRange(key, end)
-}
-
-func (wv *writeView) Put(key, value []byte, lease lease.LeaseID) (rev int64) {
-	tw := wv.kv.Write()
-	defer tw.End()
-	return tw.Put(key, value, lease)
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/kvstore.go b/vendor/github.com/coreos/etcd/mvcc/kvstore.go
deleted file mode 100644
index dd9f04a..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/kvstore.go
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"context"
-	"encoding/binary"
-	"errors"
-	"hash/crc32"
-	"math"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-	"github.com/coreos/etcd/pkg/schedule"
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	keyBucketName  = []byte("key")
-	metaBucketName = []byte("meta")
-
-	consistentIndexKeyName  = []byte("consistent_index")
-	scheduledCompactKeyName = []byte("scheduledCompactRev")
-	finishedCompactKeyName  = []byte("finishedCompactRev")
-
-	ErrCompacted = errors.New("mvcc: required revision has been compacted")
-	ErrFutureRev = errors.New("mvcc: required revision is a future revision")
-	ErrCanceled  = errors.New("mvcc: watcher is canceled")
-	ErrClosed    = errors.New("mvcc: closed")
-
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "mvcc")
-)
-
-const (
-	// markedRevBytesLen is the byte length of marked revision.
-	// The first `revBytesLen` bytes represents a normal revision. The last
-	// one byte is the mark.
-	markedRevBytesLen      = revBytesLen + 1
-	markBytePosition       = markedRevBytesLen - 1
-	markTombstone     byte = 't'
-)
-
-var restoreChunkKeys = 10000 // non-const for testing
-
-// ConsistentIndexGetter is an interface that wraps the Get method.
-// Consistent index is the offset of an entry in a consistent replicated log.
-type ConsistentIndexGetter interface {
-	// ConsistentIndex returns the consistent index of current executing entry.
-	ConsistentIndex() uint64
-}
-
-type store struct {
-	ReadView
-	WriteView
-
-	// consistentIndex caches the "consistent_index" key's value. Accessed
-	// through atomics so must be 64-bit aligned.
-	consistentIndex uint64
-
-	// mu read locks for txns and write locks for non-txn store changes.
-	mu sync.RWMutex
-
-	ig ConsistentIndexGetter
-
-	b       backend.Backend
-	kvindex index
-
-	le lease.Lessor
-
-	// revMuLock protects currentRev and compactMainRev.
-	// Locked at end of write txn and released after write txn unlock lock.
-	// Locked before locking read txn and released after locking.
-	revMu sync.RWMutex
-	// currentRev is the revision of the last completed transaction.
-	currentRev int64
-	// compactMainRev is the main revision of the last compaction.
-	compactMainRev int64
-
-	// bytesBuf8 is a byte slice of length 8
-	// to avoid a repetitive allocation in saveIndex.
-	bytesBuf8 []byte
-
-	fifoSched schedule.Scheduler
-
-	stopc chan struct{}
-}
-
-// NewStore returns a new store. It is useful to create a store inside
-// mvcc pkg. It should only be used for testing externally.
-func NewStore(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) *store {
-	s := &store{
-		b:       b,
-		ig:      ig,
-		kvindex: newTreeIndex(),
-
-		le: le,
-
-		currentRev:     1,
-		compactMainRev: -1,
-
-		bytesBuf8: make([]byte, 8),
-		fifoSched: schedule.NewFIFOScheduler(),
-
-		stopc: make(chan struct{}),
-	}
-	s.ReadView = &readView{s}
-	s.WriteView = &writeView{s}
-	if s.le != nil {
-		s.le.SetRangeDeleter(func() lease.TxnDelete { return s.Write() })
-	}
-
-	tx := s.b.BatchTx()
-	tx.Lock()
-	tx.UnsafeCreateBucket(keyBucketName)
-	tx.UnsafeCreateBucket(metaBucketName)
-	tx.Unlock()
-	s.b.ForceCommit()
-
-	if err := s.restore(); err != nil {
-		// TODO: return the error instead of panic here?
-		panic("failed to recover store from backend")
-	}
-
-	return s
-}
-
-func (s *store) compactBarrier(ctx context.Context, ch chan struct{}) {
-	if ctx == nil || ctx.Err() != nil {
-		s.mu.Lock()
-		select {
-		case <-s.stopc:
-		default:
-			f := func(ctx context.Context) { s.compactBarrier(ctx, ch) }
-			s.fifoSched.Schedule(f)
-		}
-		s.mu.Unlock()
-		return
-	}
-	close(ch)
-}
-
-func (s *store) Hash() (hash uint32, revision int64, err error) {
-	start := time.Now()
-
-	s.b.ForceCommit()
-	h, err := s.b.Hash(DefaultIgnores)
-
-	hashDurations.Observe(time.Since(start).Seconds())
-	return h, s.currentRev, err
-}
-
-func (s *store) HashByRev(rev int64) (hash uint32, currentRev int64, compactRev int64, err error) {
-	start := time.Now()
-
-	s.mu.RLock()
-	s.revMu.RLock()
-	compactRev, currentRev = s.compactMainRev, s.currentRev
-	s.revMu.RUnlock()
-
-	if rev > 0 && rev <= compactRev {
-		s.mu.RUnlock()
-		return 0, 0, compactRev, ErrCompacted
-	} else if rev > 0 && rev > currentRev {
-		s.mu.RUnlock()
-		return 0, currentRev, 0, ErrFutureRev
-	}
-
-	if rev == 0 {
-		rev = currentRev
-	}
-	keep := s.kvindex.Keep(rev)
-
-	tx := s.b.ReadTx()
-	tx.Lock()
-	defer tx.Unlock()
-	s.mu.RUnlock()
-
-	upper := revision{main: rev + 1}
-	lower := revision{main: compactRev + 1}
-	h := crc32.New(crc32.MakeTable(crc32.Castagnoli))
-
-	h.Write(keyBucketName)
-	err = tx.UnsafeForEach(keyBucketName, func(k, v []byte) error {
-		kr := bytesToRev(k)
-		if !upper.GreaterThan(kr) {
-			return nil
-		}
-		// skip revisions that are scheduled for deletion
-		// due to compacting; don't skip if there isn't one.
-		if lower.GreaterThan(kr) && len(keep) > 0 {
-			if _, ok := keep[kr]; !ok {
-				return nil
-			}
-		}
-		h.Write(k)
-		h.Write(v)
-		return nil
-	})
-	hash = h.Sum32()
-
-	hashRevDurations.Observe(time.Since(start).Seconds())
-	return hash, currentRev, compactRev, err
-}
-
-func (s *store) Compact(rev int64) (<-chan struct{}, error) {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	s.revMu.Lock()
-	defer s.revMu.Unlock()
-
-	if rev <= s.compactMainRev {
-		ch := make(chan struct{})
-		f := func(ctx context.Context) { s.compactBarrier(ctx, ch) }
-		s.fifoSched.Schedule(f)
-		return ch, ErrCompacted
-	}
-	if rev > s.currentRev {
-		return nil, ErrFutureRev
-	}
-
-	start := time.Now()
-
-	s.compactMainRev = rev
-
-	rbytes := newRevBytes()
-	revToBytes(revision{main: rev}, rbytes)
-
-	tx := s.b.BatchTx()
-	tx.Lock()
-	tx.UnsafePut(metaBucketName, scheduledCompactKeyName, rbytes)
-	tx.Unlock()
-	// ensure that desired compaction is persisted
-	s.b.ForceCommit()
-
-	keep := s.kvindex.Compact(rev)
-	ch := make(chan struct{})
-	var j = func(ctx context.Context) {
-		if ctx.Err() != nil {
-			s.compactBarrier(ctx, ch)
-			return
-		}
-		if !s.scheduleCompaction(rev, keep) {
-			s.compactBarrier(nil, ch)
-			return
-		}
-		close(ch)
-	}
-
-	s.fifoSched.Schedule(j)
-
-	indexCompactionPauseDurations.Observe(float64(time.Since(start) / time.Millisecond))
-	return ch, nil
-}
-
-// DefaultIgnores is a map of keys to ignore in hash checking.
-var DefaultIgnores map[backend.IgnoreKey]struct{}
-
-func init() {
-	DefaultIgnores = map[backend.IgnoreKey]struct{}{
-		// consistent index might be changed due to v2 internal sync, which
-		// is not controllable by the user.
-		{Bucket: string(metaBucketName), Key: string(consistentIndexKeyName)}: {},
-	}
-}
-
-func (s *store) Commit() {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	tx := s.b.BatchTx()
-	tx.Lock()
-	s.saveIndex(tx)
-	tx.Unlock()
-	s.b.ForceCommit()
-}
-
-func (s *store) Restore(b backend.Backend) error {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	close(s.stopc)
-	s.fifoSched.Stop()
-
-	atomic.StoreUint64(&s.consistentIndex, 0)
-	s.b = b
-	s.kvindex = newTreeIndex()
-	s.currentRev = 1
-	s.compactMainRev = -1
-	s.fifoSched = schedule.NewFIFOScheduler()
-	s.stopc = make(chan struct{})
-
-	return s.restore()
-}
-
-func (s *store) restore() error {
-	b := s.b
-
-	reportDbTotalSizeInBytesMu.Lock()
-	reportDbTotalSizeInBytes = func() float64 { return float64(b.Size()) }
-	reportDbTotalSizeInBytesMu.Unlock()
-	reportDbTotalSizeInUseInBytesMu.Lock()
-	reportDbTotalSizeInUseInBytes = func() float64 { return float64(b.SizeInUse()) }
-	reportDbTotalSizeInUseInBytesMu.Unlock()
-
-	min, max := newRevBytes(), newRevBytes()
-	revToBytes(revision{main: 1}, min)
-	revToBytes(revision{main: math.MaxInt64, sub: math.MaxInt64}, max)
-
-	keyToLease := make(map[string]lease.LeaseID)
-
-	// restore index
-	tx := s.b.BatchTx()
-	tx.Lock()
-
-	_, finishedCompactBytes := tx.UnsafeRange(metaBucketName, finishedCompactKeyName, nil, 0)
-	if len(finishedCompactBytes) != 0 {
-		s.compactMainRev = bytesToRev(finishedCompactBytes[0]).main
-		plog.Printf("restore compact to %d", s.compactMainRev)
-	}
-	_, scheduledCompactBytes := tx.UnsafeRange(metaBucketName, scheduledCompactKeyName, nil, 0)
-	scheduledCompact := int64(0)
-	if len(scheduledCompactBytes) != 0 {
-		scheduledCompact = bytesToRev(scheduledCompactBytes[0]).main
-	}
-
-	// index keys concurrently as they're loaded in from tx
-	keysGauge.Set(0)
-	rkvc, revc := restoreIntoIndex(s.kvindex)
-	for {
-		keys, vals := tx.UnsafeRange(keyBucketName, min, max, int64(restoreChunkKeys))
-		if len(keys) == 0 {
-			break
-		}
-		// rkvc blocks if the total pending keys exceeds the restore
-		// chunk size to keep keys from consuming too much memory.
-		restoreChunk(rkvc, keys, vals, keyToLease)
-		if len(keys) < restoreChunkKeys {
-			// partial set implies final set
-			break
-		}
-		// next set begins after where this one ended
-		newMin := bytesToRev(keys[len(keys)-1][:revBytesLen])
-		newMin.sub++
-		revToBytes(newMin, min)
-	}
-	close(rkvc)
-	s.currentRev = <-revc
-
-	// keys in the range [compacted revision -N, compaction] might all be deleted due to compaction.
-	// the correct revision should be set to compaction revision in the case, not the largest revision
-	// we have seen.
-	if s.currentRev < s.compactMainRev {
-		s.currentRev = s.compactMainRev
-	}
-	if scheduledCompact <= s.compactMainRev {
-		scheduledCompact = 0
-	}
-
-	for key, lid := range keyToLease {
-		if s.le == nil {
-			panic("no lessor to attach lease")
-		}
-		err := s.le.Attach(lid, []lease.LeaseItem{{Key: key}})
-		if err != nil {
-			plog.Errorf("unexpected Attach error: %v", err)
-		}
-	}
-
-	tx.Unlock()
-
-	if scheduledCompact != 0 {
-		s.Compact(scheduledCompact)
-		plog.Printf("resume scheduled compaction at %d", scheduledCompact)
-	}
-
-	return nil
-}
-
-type revKeyValue struct {
-	key  []byte
-	kv   mvccpb.KeyValue
-	kstr string
-}
-
-func restoreIntoIndex(idx index) (chan<- revKeyValue, <-chan int64) {
-	rkvc, revc := make(chan revKeyValue, restoreChunkKeys), make(chan int64, 1)
-	go func() {
-		currentRev := int64(1)
-		defer func() { revc <- currentRev }()
-		// restore the tree index from streaming the unordered index.
-		kiCache := make(map[string]*keyIndex, restoreChunkKeys)
-		for rkv := range rkvc {
-			ki, ok := kiCache[rkv.kstr]
-			// purge kiCache if many keys but still missing in the cache
-			if !ok && len(kiCache) >= restoreChunkKeys {
-				i := 10
-				for k := range kiCache {
-					delete(kiCache, k)
-					if i--; i == 0 {
-						break
-					}
-				}
-			}
-			// cache miss, fetch from tree index if there
-			if !ok {
-				ki = &keyIndex{key: rkv.kv.Key}
-				if idxKey := idx.KeyIndex(ki); idxKey != nil {
-					kiCache[rkv.kstr], ki = idxKey, idxKey
-					ok = true
-				}
-			}
-			rev := bytesToRev(rkv.key)
-			currentRev = rev.main
-			if ok {
-				if isTombstone(rkv.key) {
-					ki.tombstone(rev.main, rev.sub)
-					continue
-				}
-				ki.put(rev.main, rev.sub)
-			} else if !isTombstone(rkv.key) {
-				ki.restore(revision{rkv.kv.CreateRevision, 0}, rev, rkv.kv.Version)
-				idx.Insert(ki)
-				kiCache[rkv.kstr] = ki
-			}
-		}
-	}()
-	return rkvc, revc
-}
-
-func restoreChunk(kvc chan<- revKeyValue, keys, vals [][]byte, keyToLease map[string]lease.LeaseID) {
-	for i, key := range keys {
-		rkv := revKeyValue{key: key}
-		if err := rkv.kv.Unmarshal(vals[i]); err != nil {
-			plog.Fatalf("cannot unmarshal event: %v", err)
-		}
-		rkv.kstr = string(rkv.kv.Key)
-		if isTombstone(key) {
-			delete(keyToLease, rkv.kstr)
-		} else if lid := lease.LeaseID(rkv.kv.Lease); lid != lease.NoLease {
-			keyToLease[rkv.kstr] = lid
-		} else {
-			delete(keyToLease, rkv.kstr)
-		}
-		kvc <- rkv
-	}
-}
-
-func (s *store) Close() error {
-	close(s.stopc)
-	s.fifoSched.Stop()
-	return nil
-}
-
-func (s *store) saveIndex(tx backend.BatchTx) {
-	if s.ig == nil {
-		return
-	}
-	bs := s.bytesBuf8
-	ci := s.ig.ConsistentIndex()
-	binary.BigEndian.PutUint64(bs, ci)
-	// put the index into the underlying backend
-	// tx has been locked in TxnBegin, so there is no need to lock it again
-	tx.UnsafePut(metaBucketName, consistentIndexKeyName, bs)
-	atomic.StoreUint64(&s.consistentIndex, ci)
-}
-
-func (s *store) ConsistentIndex() uint64 {
-	if ci := atomic.LoadUint64(&s.consistentIndex); ci > 0 {
-		return ci
-	}
-	tx := s.b.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-	_, vs := tx.UnsafeRange(metaBucketName, consistentIndexKeyName, nil, 0)
-	if len(vs) == 0 {
-		return 0
-	}
-	v := binary.BigEndian.Uint64(vs[0])
-	atomic.StoreUint64(&s.consistentIndex, v)
-	return v
-}
-
-// appendMarkTombstone appends tombstone mark to normal revision bytes.
-func appendMarkTombstone(b []byte) []byte {
-	if len(b) != revBytesLen {
-		plog.Panicf("cannot append mark to non normal revision bytes")
-	}
-	return append(b, markTombstone)
-}
-
-// isTombstone checks whether the revision bytes is a tombstone.
-func isTombstone(b []byte) bool {
-	return len(b) == markedRevBytesLen && b[markBytePosition] == markTombstone
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/kvstore_compaction.go b/vendor/github.com/coreos/etcd/mvcc/kvstore_compaction.go
deleted file mode 100644
index 1726490..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/kvstore_compaction.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"encoding/binary"
-	"time"
-)
-
-func (s *store) scheduleCompaction(compactMainRev int64, keep map[revision]struct{}) bool {
-	totalStart := time.Now()
-	defer dbCompactionTotalDurations.Observe(float64(time.Since(totalStart) / time.Millisecond))
-	keyCompactions := 0
-	defer func() { dbCompactionKeysCounter.Add(float64(keyCompactions)) }()
-
-	end := make([]byte, 8)
-	binary.BigEndian.PutUint64(end, uint64(compactMainRev+1))
-
-	batchsize := int64(10000)
-	last := make([]byte, 8+1+8)
-	for {
-		var rev revision
-
-		start := time.Now()
-		tx := s.b.BatchTx()
-		tx.Lock()
-
-		keys, _ := tx.UnsafeRange(keyBucketName, last, end, batchsize)
-		for _, key := range keys {
-			rev = bytesToRev(key)
-			if _, ok := keep[rev]; !ok {
-				tx.UnsafeDelete(keyBucketName, key)
-				keyCompactions++
-			}
-		}
-
-		if len(keys) < int(batchsize) {
-			rbytes := make([]byte, 8+1+8)
-			revToBytes(revision{main: compactMainRev}, rbytes)
-			tx.UnsafePut(metaBucketName, finishedCompactKeyName, rbytes)
-			tx.Unlock()
-			plog.Printf("finished scheduled compaction at %d (took %v)", compactMainRev, time.Since(totalStart))
-			return true
-		}
-
-		// update last
-		revToBytes(revision{main: rev.main, sub: rev.sub + 1}, last)
-		tx.Unlock()
-		dbCompactionPauseDurations.Observe(float64(time.Since(start) / time.Millisecond))
-
-		select {
-		case <-time.After(100 * time.Millisecond):
-		case <-s.stopc:
-			return false
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/kvstore_txn.go b/vendor/github.com/coreos/etcd/mvcc/kvstore_txn.go
deleted file mode 100644
index 8896fb8..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/kvstore_txn.go
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-type storeTxnRead struct {
-	s  *store
-	tx backend.ReadTx
-
-	firstRev int64
-	rev      int64
-}
-
-func (s *store) Read() TxnRead {
-	s.mu.RLock()
-	tx := s.b.ReadTx()
-	s.revMu.RLock()
-	tx.Lock()
-	firstRev, rev := s.compactMainRev, s.currentRev
-	s.revMu.RUnlock()
-	return newMetricsTxnRead(&storeTxnRead{s, tx, firstRev, rev})
-}
-
-func (tr *storeTxnRead) FirstRev() int64 { return tr.firstRev }
-func (tr *storeTxnRead) Rev() int64      { return tr.rev }
-
-func (tr *storeTxnRead) Range(key, end []byte, ro RangeOptions) (r *RangeResult, err error) {
-	return tr.rangeKeys(key, end, tr.Rev(), ro)
-}
-
-func (tr *storeTxnRead) End() {
-	tr.tx.Unlock()
-	tr.s.mu.RUnlock()
-}
-
-type storeTxnWrite struct {
-	storeTxnRead
-	tx backend.BatchTx
-	// beginRev is the revision where the txn begins; it will write to the next revision.
-	beginRev int64
-	changes  []mvccpb.KeyValue
-}
-
-func (s *store) Write() TxnWrite {
-	s.mu.RLock()
-	tx := s.b.BatchTx()
-	tx.Lock()
-	tw := &storeTxnWrite{
-		storeTxnRead: storeTxnRead{s, tx, 0, 0},
-		tx:           tx,
-		beginRev:     s.currentRev,
-		changes:      make([]mvccpb.KeyValue, 0, 4),
-	}
-	return newMetricsTxnWrite(tw)
-}
-
-func (tw *storeTxnWrite) Rev() int64 { return tw.beginRev }
-
-func (tw *storeTxnWrite) Range(key, end []byte, ro RangeOptions) (r *RangeResult, err error) {
-	rev := tw.beginRev
-	if len(tw.changes) > 0 {
-		rev++
-	}
-	return tw.rangeKeys(key, end, rev, ro)
-}
-
-func (tw *storeTxnWrite) DeleteRange(key, end []byte) (int64, int64) {
-	if n := tw.deleteRange(key, end); n != 0 || len(tw.changes) > 0 {
-		return n, int64(tw.beginRev + 1)
-	}
-	return 0, int64(tw.beginRev)
-}
-
-func (tw *storeTxnWrite) Put(key, value []byte, lease lease.LeaseID) int64 {
-	tw.put(key, value, lease)
-	return int64(tw.beginRev + 1)
-}
-
-func (tw *storeTxnWrite) End() {
-	// only update index if the txn modifies the mvcc state.
-	if len(tw.changes) != 0 {
-		tw.s.saveIndex(tw.tx)
-		// hold revMu lock to prevent new read txns from opening until writeback.
-		tw.s.revMu.Lock()
-		tw.s.currentRev++
-	}
-	tw.tx.Unlock()
-	if len(tw.changes) != 0 {
-		tw.s.revMu.Unlock()
-	}
-	tw.s.mu.RUnlock()
-}
-
-func (tr *storeTxnRead) rangeKeys(key, end []byte, curRev int64, ro RangeOptions) (*RangeResult, error) {
-	rev := ro.Rev
-	if rev > curRev {
-		return &RangeResult{KVs: nil, Count: -1, Rev: curRev}, ErrFutureRev
-	}
-	if rev <= 0 {
-		rev = curRev
-	}
-	if rev < tr.s.compactMainRev {
-		return &RangeResult{KVs: nil, Count: -1, Rev: 0}, ErrCompacted
-	}
-
-	revpairs := tr.s.kvindex.Revisions(key, end, int64(rev))
-	if len(revpairs) == 0 {
-		return &RangeResult{KVs: nil, Count: 0, Rev: curRev}, nil
-	}
-	if ro.Count {
-		return &RangeResult{KVs: nil, Count: len(revpairs), Rev: curRev}, nil
-	}
-
-	limit := int(ro.Limit)
-	if limit <= 0 || limit > len(revpairs) {
-		limit = len(revpairs)
-	}
-
-	kvs := make([]mvccpb.KeyValue, limit)
-	revBytes := newRevBytes()
-	for i, revpair := range revpairs[:len(kvs)] {
-		revToBytes(revpair, revBytes)
-		_, vs := tr.tx.UnsafeRange(keyBucketName, revBytes, nil, 0)
-		if len(vs) != 1 {
-			plog.Fatalf("range cannot find rev (%d,%d)", revpair.main, revpair.sub)
-		}
-		if err := kvs[i].Unmarshal(vs[0]); err != nil {
-			plog.Fatalf("cannot unmarshal event: %v", err)
-		}
-	}
-	return &RangeResult{KVs: kvs, Count: len(revpairs), Rev: curRev}, nil
-}
-
-func (tw *storeTxnWrite) put(key, value []byte, leaseID lease.LeaseID) {
-	rev := tw.beginRev + 1
-	c := rev
-	oldLease := lease.NoLease
-
-	// if the key exists before, use its previous created and
-	// get its previous leaseID
-	_, created, ver, err := tw.s.kvindex.Get(key, rev)
-	if err == nil {
-		c = created.main
-		oldLease = tw.s.le.GetLease(lease.LeaseItem{Key: string(key)})
-	}
-
-	ibytes := newRevBytes()
-	idxRev := revision{main: rev, sub: int64(len(tw.changes))}
-	revToBytes(idxRev, ibytes)
-
-	ver = ver + 1
-	kv := mvccpb.KeyValue{
-		Key:            key,
-		Value:          value,
-		CreateRevision: c,
-		ModRevision:    rev,
-		Version:        ver,
-		Lease:          int64(leaseID),
-	}
-
-	d, err := kv.Marshal()
-	if err != nil {
-		plog.Fatalf("cannot marshal event: %v", err)
-	}
-
-	tw.tx.UnsafeSeqPut(keyBucketName, ibytes, d)
-	tw.s.kvindex.Put(key, idxRev)
-	tw.changes = append(tw.changes, kv)
-
-	if oldLease != lease.NoLease {
-		if tw.s.le == nil {
-			panic("no lessor to detach lease")
-		}
-		err = tw.s.le.Detach(oldLease, []lease.LeaseItem{{Key: string(key)}})
-		if err != nil {
-			plog.Errorf("unexpected error from lease detach: %v", err)
-		}
-	}
-	if leaseID != lease.NoLease {
-		if tw.s.le == nil {
-			panic("no lessor to attach lease")
-		}
-		err = tw.s.le.Attach(leaseID, []lease.LeaseItem{{Key: string(key)}})
-		if err != nil {
-			panic("unexpected error from lease Attach")
-		}
-	}
-}
-
-func (tw *storeTxnWrite) deleteRange(key, end []byte) int64 {
-	rrev := tw.beginRev
-	if len(tw.changes) > 0 {
-		rrev += 1
-	}
-	keys, revs := tw.s.kvindex.Range(key, end, rrev)
-	if len(keys) == 0 {
-		return 0
-	}
-	for i, key := range keys {
-		tw.delete(key, revs[i])
-	}
-	return int64(len(keys))
-}
-
-func (tw *storeTxnWrite) delete(key []byte, rev revision) {
-	ibytes := newRevBytes()
-	idxRev := revision{main: tw.beginRev + 1, sub: int64(len(tw.changes))}
-	revToBytes(idxRev, ibytes)
-	ibytes = appendMarkTombstone(ibytes)
-
-	kv := mvccpb.KeyValue{Key: key}
-
-	d, err := kv.Marshal()
-	if err != nil {
-		plog.Fatalf("cannot marshal event: %v", err)
-	}
-
-	tw.tx.UnsafeSeqPut(keyBucketName, ibytes, d)
-	err = tw.s.kvindex.Tombstone(key, idxRev)
-	if err != nil {
-		plog.Fatalf("cannot tombstone an existing key (%s): %v", string(key), err)
-	}
-	tw.changes = append(tw.changes, kv)
-
-	item := lease.LeaseItem{Key: string(key)}
-	leaseID := tw.s.le.GetLease(item)
-
-	if leaseID != lease.NoLease {
-		err = tw.s.le.Detach(leaseID, []lease.LeaseItem{item})
-		if err != nil {
-			plog.Errorf("cannot detach %v", err)
-		}
-	}
-}
-
-func (tw *storeTxnWrite) Changes() []mvccpb.KeyValue { return tw.changes }
diff --git a/vendor/github.com/coreos/etcd/mvcc/metrics.go b/vendor/github.com/coreos/etcd/mvcc/metrics.go
deleted file mode 100644
index b753310..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/metrics.go
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"sync"
-
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-var (
-	rangeCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "range_total",
-			Help:      "Total number of ranges seen by this member.",
-		})
-
-	putCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "put_total",
-			Help:      "Total number of puts seen by this member.",
-		})
-
-	deleteCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "delete_total",
-			Help:      "Total number of deletes seen by this member.",
-		})
-
-	txnCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "txn_total",
-			Help:      "Total number of txns seen by this member.",
-		})
-
-	keysGauge = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "keys_total",
-			Help:      "Total number of keys.",
-		})
-
-	watchStreamGauge = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "watch_stream_total",
-			Help:      "Total number of watch streams.",
-		})
-
-	watcherGauge = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "watcher_total",
-			Help:      "Total number of watchers.",
-		})
-
-	slowWatcherGauge = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "slow_watcher_total",
-			Help:      "Total number of unsynced slow watchers.",
-		})
-
-	totalEventsCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "events_total",
-			Help:      "Total number of events sent by this member.",
-		})
-
-	pendingEventsGauge = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "pending_events_total",
-			Help:      "Total number of pending events to be sent.",
-		})
-
-	indexCompactionPauseDurations = prometheus.NewHistogram(
-		prometheus.HistogramOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "index_compaction_pause_duration_milliseconds",
-			Help:      "Bucketed histogram of index compaction pause duration.",
-			// 0.5ms -> 1second
-			Buckets: prometheus.ExponentialBuckets(0.5, 2, 12),
-		})
-
-	dbCompactionPauseDurations = prometheus.NewHistogram(
-		prometheus.HistogramOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "db_compaction_pause_duration_milliseconds",
-			Help:      "Bucketed histogram of db compaction pause duration.",
-			// 1ms -> 4second
-			Buckets: prometheus.ExponentialBuckets(1, 2, 13),
-		})
-
-	dbCompactionTotalDurations = prometheus.NewHistogram(
-		prometheus.HistogramOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "db_compaction_total_duration_milliseconds",
-			Help:      "Bucketed histogram of db compaction total duration.",
-			// 100ms -> 800second
-			Buckets: prometheus.ExponentialBuckets(100, 2, 14),
-		})
-
-	dbCompactionKeysCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "db_compaction_keys_total",
-			Help:      "Total number of db keys compacted.",
-		})
-
-	dbTotalSizeDebugging = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "mvcc",
-		Name:      "db_total_size_in_bytes",
-		Help:      "Total size of the underlying database physically allocated in bytes. Use etcd_mvcc_db_total_size_in_bytes",
-	},
-		func() float64 {
-			reportDbTotalSizeInBytesMu.RLock()
-			defer reportDbTotalSizeInBytesMu.RUnlock()
-			return reportDbTotalSizeInBytes()
-		},
-	)
-	dbTotalSize = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "mvcc",
-		Name:      "db_total_size_in_bytes",
-		Help:      "Total size of the underlying database physically allocated in bytes.",
-	},
-		func() float64 {
-			reportDbTotalSizeInBytesMu.RLock()
-			defer reportDbTotalSizeInBytesMu.RUnlock()
-			return reportDbTotalSizeInBytes()
-		},
-	)
-	// overridden by mvcc initialization
-	reportDbTotalSizeInBytesMu sync.RWMutex
-	reportDbTotalSizeInBytes   = func() float64 { return 0 }
-
-	dbTotalSizeInUse = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "mvcc",
-		Name:      "db_total_size_in_use_in_bytes",
-		Help:      "Total size of the underlying database logically in use in bytes.",
-	},
-		func() float64 {
-			reportDbTotalSizeInUseInBytesMu.RLock()
-			defer reportDbTotalSizeInUseInBytesMu.RUnlock()
-			return reportDbTotalSizeInUseInBytes()
-		},
-	)
-	// overridden by mvcc initialization
-	reportDbTotalSizeInUseInBytesMu sync.RWMutex
-	reportDbTotalSizeInUseInBytes   func() float64 = func() float64 { return 0 }
-
-	hashDurations = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "mvcc",
-		Name:      "hash_duration_seconds",
-		Help:      "The latency distribution of storage hash operation.",
-
-		// 100 MB usually takes 100 ms, so start with 10 MB of 10 ms
-		// lowest bucket start of upper bound 0.01 sec (10 ms) with factor 2
-		// highest bucket start of 0.01 sec * 2^14 == 163.84 sec
-		Buckets: prometheus.ExponentialBuckets(.01, 2, 15),
-	})
-
-	hashRevDurations = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "mvcc",
-		Name:      "hash_rev_duration_seconds",
-		Help:      "The latency distribution of storage hash by revision operation.",
-
-		// 100 MB usually takes 100 ms, so start with 10 MB of 10 ms
-		// lowest bucket start of upper bound 0.01 sec (10 ms) with factor 2
-		// highest bucket start of 0.01 sec * 2^14 == 163.84 sec
-		Buckets: prometheus.ExponentialBuckets(.01, 2, 15),
-	})
-)
-
-func init() {
-	prometheus.MustRegister(rangeCounter)
-	prometheus.MustRegister(putCounter)
-	prometheus.MustRegister(deleteCounter)
-	prometheus.MustRegister(txnCounter)
-	prometheus.MustRegister(keysGauge)
-	prometheus.MustRegister(watchStreamGauge)
-	prometheus.MustRegister(watcherGauge)
-	prometheus.MustRegister(slowWatcherGauge)
-	prometheus.MustRegister(totalEventsCounter)
-	prometheus.MustRegister(pendingEventsGauge)
-	prometheus.MustRegister(indexCompactionPauseDurations)
-	prometheus.MustRegister(dbCompactionPauseDurations)
-	prometheus.MustRegister(dbCompactionTotalDurations)
-	prometheus.MustRegister(dbCompactionKeysCounter)
-	prometheus.MustRegister(dbTotalSizeDebugging)
-	prometheus.MustRegister(dbTotalSize)
-	prometheus.MustRegister(dbTotalSizeInUse)
-	prometheus.MustRegister(hashDurations)
-	prometheus.MustRegister(hashRevDurations)
-}
-
-// ReportEventReceived reports that an event is received.
-// This function should be called when the external systems received an
-// event from mvcc.Watcher.
-func ReportEventReceived(n int) {
-	pendingEventsGauge.Sub(float64(n))
-	totalEventsCounter.Add(float64(n))
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/metrics_txn.go b/vendor/github.com/coreos/etcd/mvcc/metrics_txn.go
deleted file mode 100644
index 911d648..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/metrics_txn.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"github.com/coreos/etcd/lease"
-)
-
-type metricsTxnWrite struct {
-	TxnWrite
-	ranges  uint
-	puts    uint
-	deletes uint
-}
-
-func newMetricsTxnRead(tr TxnRead) TxnRead {
-	return &metricsTxnWrite{&txnReadWrite{tr}, 0, 0, 0}
-}
-
-func newMetricsTxnWrite(tw TxnWrite) TxnWrite {
-	return &metricsTxnWrite{tw, 0, 0, 0}
-}
-
-func (tw *metricsTxnWrite) Range(key, end []byte, ro RangeOptions) (*RangeResult, error) {
-	tw.ranges++
-	return tw.TxnWrite.Range(key, end, ro)
-}
-
-func (tw *metricsTxnWrite) DeleteRange(key, end []byte) (n, rev int64) {
-	tw.deletes++
-	return tw.TxnWrite.DeleteRange(key, end)
-}
-
-func (tw *metricsTxnWrite) Put(key, value []byte, lease lease.LeaseID) (rev int64) {
-	tw.puts++
-	return tw.TxnWrite.Put(key, value, lease)
-}
-
-func (tw *metricsTxnWrite) End() {
-	defer tw.TxnWrite.End()
-	if sum := tw.ranges + tw.puts + tw.deletes; sum > 1 {
-		txnCounter.Inc()
-	}
-	rangeCounter.Add(float64(tw.ranges))
-	putCounter.Add(float64(tw.puts))
-	deleteCounter.Add(float64(tw.deletes))
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/revision.go b/vendor/github.com/coreos/etcd/mvcc/revision.go
deleted file mode 100644
index 5fa35a1..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/revision.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import "encoding/binary"
-
-// revBytesLen is the byte length of a normal revision.
-// First 8 bytes is the revision.main in big-endian format. The 9th byte
-// is a '_'. The last 8 bytes is the revision.sub in big-endian format.
-const revBytesLen = 8 + 1 + 8
-
-// A revision indicates modification of the key-value space.
-// The set of changes that share same main revision changes the key-value space atomically.
-type revision struct {
-	// main is the main revision of a set of changes that happen atomically.
-	main int64
-
-	// sub is the the sub revision of a change in a set of changes that happen
-	// atomically. Each change has different increasing sub revision in that
-	// set.
-	sub int64
-}
-
-func (a revision) GreaterThan(b revision) bool {
-	if a.main > b.main {
-		return true
-	}
-	if a.main < b.main {
-		return false
-	}
-	return a.sub > b.sub
-}
-
-func newRevBytes() []byte {
-	return make([]byte, revBytesLen, markedRevBytesLen)
-}
-
-func revToBytes(rev revision, bytes []byte) {
-	binary.BigEndian.PutUint64(bytes, uint64(rev.main))
-	bytes[8] = '_'
-	binary.BigEndian.PutUint64(bytes[9:], uint64(rev.sub))
-}
-
-func bytesToRev(bytes []byte) revision {
-	return revision{
-		main: int64(binary.BigEndian.Uint64(bytes[0:8])),
-		sub:  int64(binary.BigEndian.Uint64(bytes[9:])),
-	}
-}
-
-type revisions []revision
-
-func (a revisions) Len() int           { return len(a) }
-func (a revisions) Less(i, j int) bool { return a[j].GreaterThan(a[i]) }
-func (a revisions) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
diff --git a/vendor/github.com/coreos/etcd/mvcc/util.go b/vendor/github.com/coreos/etcd/mvcc/util.go
deleted file mode 100644
index 8a0df0b..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/util.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"encoding/binary"
-
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-func UpdateConsistentIndex(be backend.Backend, index uint64) {
-	tx := be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	var oldi uint64
-	_, vs := tx.UnsafeRange(metaBucketName, consistentIndexKeyName, nil, 0)
-	if len(vs) != 0 {
-		oldi = binary.BigEndian.Uint64(vs[0])
-	}
-
-	if index <= oldi {
-		return
-	}
-
-	bs := make([]byte, 8)
-	binary.BigEndian.PutUint64(bs, index)
-	tx.UnsafePut(metaBucketName, consistentIndexKeyName, bs)
-}
-
-func WriteKV(be backend.Backend, kv mvccpb.KeyValue) {
-	ibytes := newRevBytes()
-	revToBytes(revision{main: kv.ModRevision}, ibytes)
-
-	d, err := kv.Marshal()
-	if err != nil {
-		plog.Fatalf("cannot marshal event: %v", err)
-	}
-
-	be.BatchTx().Lock()
-	be.BatchTx().UnsafePut(keyBucketName, ibytes, d)
-	be.BatchTx().Unlock()
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/watchable_store.go b/vendor/github.com/coreos/etcd/mvcc/watchable_store.go
deleted file mode 100644
index 78df193..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/watchable_store.go
+++ /dev/null
@@ -1,534 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/lease"
-	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-// non-const so modifiable by tests
-var (
-	// chanBufLen is the length of the buffered chan
-	// for sending out watched events.
-	// TODO: find a good buf value. 1024 is just a random one that
-	// seems to be reasonable.
-	chanBufLen = 1024
-
-	// maxWatchersPerSync is the number of watchers to sync in a single batch
-	maxWatchersPerSync = 512
-)
-
-type watchable interface {
-	watch(key, end []byte, startRev int64, id WatchID, ch chan<- WatchResponse, fcs ...FilterFunc) (*watcher, cancelFunc)
-	progress(w *watcher)
-	rev() int64
-}
-
-type watchableStore struct {
-	*store
-
-	// mu protects watcher groups and batches. It should never be locked
-	// before locking store.mu to avoid deadlock.
-	mu sync.RWMutex
-
-	// victims are watcher batches that were blocked on the watch channel
-	victims []watcherBatch
-	victimc chan struct{}
-
-	// contains all unsynced watchers that needs to sync with events that have happened
-	unsynced watcherGroup
-
-	// contains all synced watchers that are in sync with the progress of the store.
-	// The key of the map is the key that the watcher watches on.
-	synced watcherGroup
-
-	stopc chan struct{}
-	wg    sync.WaitGroup
-}
-
-// cancelFunc updates unsynced and synced maps when running
-// cancel operations.
-type cancelFunc func()
-
-func New(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) ConsistentWatchableKV {
-	return newWatchableStore(b, le, ig)
-}
-
-func newWatchableStore(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) *watchableStore {
-	s := &watchableStore{
-		store:    NewStore(b, le, ig),
-		victimc:  make(chan struct{}, 1),
-		unsynced: newWatcherGroup(),
-		synced:   newWatcherGroup(),
-		stopc:    make(chan struct{}),
-	}
-	s.store.ReadView = &readView{s}
-	s.store.WriteView = &writeView{s}
-	if s.le != nil {
-		// use this store as the deleter so revokes trigger watch events
-		s.le.SetRangeDeleter(func() lease.TxnDelete { return s.Write() })
-	}
-	s.wg.Add(2)
-	go s.syncWatchersLoop()
-	go s.syncVictimsLoop()
-	return s
-}
-
-func (s *watchableStore) Close() error {
-	close(s.stopc)
-	s.wg.Wait()
-	return s.store.Close()
-}
-
-func (s *watchableStore) NewWatchStream() WatchStream {
-	watchStreamGauge.Inc()
-	return &watchStream{
-		watchable: s,
-		ch:        make(chan WatchResponse, chanBufLen),
-		cancels:   make(map[WatchID]cancelFunc),
-		watchers:  make(map[WatchID]*watcher),
-	}
-}
-
-func (s *watchableStore) watch(key, end []byte, startRev int64, id WatchID, ch chan<- WatchResponse, fcs ...FilterFunc) (*watcher, cancelFunc) {
-	wa := &watcher{
-		key:    key,
-		end:    end,
-		minRev: startRev,
-		id:     id,
-		ch:     ch,
-		fcs:    fcs,
-	}
-
-	s.mu.Lock()
-	s.revMu.RLock()
-	synced := startRev > s.store.currentRev || startRev == 0
-	if synced {
-		wa.minRev = s.store.currentRev + 1
-		if startRev > wa.minRev {
-			wa.minRev = startRev
-		}
-	}
-	if synced {
-		s.synced.add(wa)
-	} else {
-		slowWatcherGauge.Inc()
-		s.unsynced.add(wa)
-	}
-	s.revMu.RUnlock()
-	s.mu.Unlock()
-
-	watcherGauge.Inc()
-
-	return wa, func() { s.cancelWatcher(wa) }
-}
-
-// cancelWatcher removes references of the watcher from the watchableStore
-func (s *watchableStore) cancelWatcher(wa *watcher) {
-	for {
-		s.mu.Lock()
-		if s.unsynced.delete(wa) {
-			slowWatcherGauge.Dec()
-			break
-		} else if s.synced.delete(wa) {
-			break
-		} else if wa.compacted {
-			break
-		} else if wa.ch == nil {
-			// already canceled (e.g., cancel/close race)
-			break
-		}
-
-		if !wa.victim {
-			panic("watcher not victim but not in watch groups")
-		}
-
-		var victimBatch watcherBatch
-		for _, wb := range s.victims {
-			if wb[wa] != nil {
-				victimBatch = wb
-				break
-			}
-		}
-		if victimBatch != nil {
-			slowWatcherGauge.Dec()
-			delete(victimBatch, wa)
-			break
-		}
-
-		// victim being processed so not accessible; retry
-		s.mu.Unlock()
-		time.Sleep(time.Millisecond)
-	}
-
-	watcherGauge.Dec()
-	wa.ch = nil
-	s.mu.Unlock()
-}
-
-func (s *watchableStore) Restore(b backend.Backend) error {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	err := s.store.Restore(b)
-	if err != nil {
-		return err
-	}
-
-	for wa := range s.synced.watchers {
-		wa.restore = true
-		s.unsynced.add(wa)
-	}
-	s.synced = newWatcherGroup()
-	return nil
-}
-
-// syncWatchersLoop syncs the watcher in the unsynced map every 100ms.
-func (s *watchableStore) syncWatchersLoop() {
-	defer s.wg.Done()
-
-	for {
-		s.mu.RLock()
-		st := time.Now()
-		lastUnsyncedWatchers := s.unsynced.size()
-		s.mu.RUnlock()
-
-		unsyncedWatchers := 0
-		if lastUnsyncedWatchers > 0 {
-			unsyncedWatchers = s.syncWatchers()
-		}
-		syncDuration := time.Since(st)
-
-		waitDuration := 100 * time.Millisecond
-		// more work pending?
-		if unsyncedWatchers != 0 && lastUnsyncedWatchers > unsyncedWatchers {
-			// be fair to other store operations by yielding time taken
-			waitDuration = syncDuration
-		}
-
-		select {
-		case <-time.After(waitDuration):
-		case <-s.stopc:
-			return
-		}
-	}
-}
-
-// syncVictimsLoop tries to write precomputed watcher responses to
-// watchers that had a blocked watcher channel
-func (s *watchableStore) syncVictimsLoop() {
-	defer s.wg.Done()
-
-	for {
-		for s.moveVictims() != 0 {
-			// try to update all victim watchers
-		}
-		s.mu.RLock()
-		isEmpty := len(s.victims) == 0
-		s.mu.RUnlock()
-
-		var tickc <-chan time.Time
-		if !isEmpty {
-			tickc = time.After(10 * time.Millisecond)
-		}
-
-		select {
-		case <-tickc:
-		case <-s.victimc:
-		case <-s.stopc:
-			return
-		}
-	}
-}
-
-// moveVictims tries to update watches with already pending event data
-func (s *watchableStore) moveVictims() (moved int) {
-	s.mu.Lock()
-	victims := s.victims
-	s.victims = nil
-	s.mu.Unlock()
-
-	var newVictim watcherBatch
-	for _, wb := range victims {
-		// try to send responses again
-		for w, eb := range wb {
-			// watcher has observed the store up to, but not including, w.minRev
-			rev := w.minRev - 1
-			if w.send(WatchResponse{WatchID: w.id, Events: eb.evs, Revision: rev}) {
-				pendingEventsGauge.Add(float64(len(eb.evs)))
-			} else {
-				if newVictim == nil {
-					newVictim = make(watcherBatch)
-				}
-				newVictim[w] = eb
-				continue
-			}
-			moved++
-		}
-
-		// assign completed victim watchers to unsync/sync
-		s.mu.Lock()
-		s.store.revMu.RLock()
-		curRev := s.store.currentRev
-		for w, eb := range wb {
-			if newVictim != nil && newVictim[w] != nil {
-				// couldn't send watch response; stays victim
-				continue
-			}
-			w.victim = false
-			if eb.moreRev != 0 {
-				w.minRev = eb.moreRev
-			}
-			if w.minRev <= curRev {
-				s.unsynced.add(w)
-			} else {
-				slowWatcherGauge.Dec()
-				s.synced.add(w)
-			}
-		}
-		s.store.revMu.RUnlock()
-		s.mu.Unlock()
-	}
-
-	if len(newVictim) > 0 {
-		s.mu.Lock()
-		s.victims = append(s.victims, newVictim)
-		s.mu.Unlock()
-	}
-
-	return moved
-}
-
-// syncWatchers syncs unsynced watchers by:
-//	1. choose a set of watchers from the unsynced watcher group
-//	2. iterate over the set to get the minimum revision and remove compacted watchers
-//	3. use minimum revision to get all key-value pairs and send those events to watchers
-//	4. remove synced watchers in set from unsynced group and move to synced group
-func (s *watchableStore) syncWatchers() int {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	if s.unsynced.size() == 0 {
-		return 0
-	}
-
-	s.store.revMu.RLock()
-	defer s.store.revMu.RUnlock()
-
-	// in order to find key-value pairs from unsynced watchers, we need to
-	// find min revision index, and these revisions can be used to
-	// query the backend store of key-value pairs
-	curRev := s.store.currentRev
-	compactionRev := s.store.compactMainRev
-
-	wg, minRev := s.unsynced.choose(maxWatchersPerSync, curRev, compactionRev)
-	minBytes, maxBytes := newRevBytes(), newRevBytes()
-	revToBytes(revision{main: minRev}, minBytes)
-	revToBytes(revision{main: curRev + 1}, maxBytes)
-
-	// UnsafeRange returns keys and values. And in boltdb, keys are revisions.
-	// values are actual key-value pairs in backend.
-	tx := s.store.b.ReadTx()
-	tx.Lock()
-	revs, vs := tx.UnsafeRange(keyBucketName, minBytes, maxBytes, 0)
-	evs := kvsToEvents(wg, revs, vs)
-	tx.Unlock()
-
-	var victims watcherBatch
-	wb := newWatcherBatch(wg, evs)
-	for w := range wg.watchers {
-		w.minRev = curRev + 1
-
-		eb, ok := wb[w]
-		if !ok {
-			// bring un-notified watcher to synced
-			s.synced.add(w)
-			s.unsynced.delete(w)
-			continue
-		}
-
-		if eb.moreRev != 0 {
-			w.minRev = eb.moreRev
-		}
-
-		if w.send(WatchResponse{WatchID: w.id, Events: eb.evs, Revision: curRev}) {
-			pendingEventsGauge.Add(float64(len(eb.evs)))
-		} else {
-			if victims == nil {
-				victims = make(watcherBatch)
-			}
-			w.victim = true
-		}
-
-		if w.victim {
-			victims[w] = eb
-		} else {
-			if eb.moreRev != 0 {
-				// stay unsynced; more to read
-				continue
-			}
-			s.synced.add(w)
-		}
-		s.unsynced.delete(w)
-	}
-	s.addVictim(victims)
-
-	vsz := 0
-	for _, v := range s.victims {
-		vsz += len(v)
-	}
-	slowWatcherGauge.Set(float64(s.unsynced.size() + vsz))
-
-	return s.unsynced.size()
-}
-
-// kvsToEvents gets all events for the watchers from all key-value pairs
-func kvsToEvents(wg *watcherGroup, revs, vals [][]byte) (evs []mvccpb.Event) {
-	for i, v := range vals {
-		var kv mvccpb.KeyValue
-		if err := kv.Unmarshal(v); err != nil {
-			plog.Panicf("cannot unmarshal event: %v", err)
-		}
-
-		if !wg.contains(string(kv.Key)) {
-			continue
-		}
-
-		ty := mvccpb.PUT
-		if isTombstone(revs[i]) {
-			ty = mvccpb.DELETE
-			// patch in mod revision so watchers won't skip
-			kv.ModRevision = bytesToRev(revs[i]).main
-		}
-		evs = append(evs, mvccpb.Event{Kv: &kv, Type: ty})
-	}
-	return evs
-}
-
-// notify notifies the fact that given event at the given rev just happened to
-// watchers that watch on the key of the event.
-func (s *watchableStore) notify(rev int64, evs []mvccpb.Event) {
-	var victim watcherBatch
-	for w, eb := range newWatcherBatch(&s.synced, evs) {
-		if eb.revs != 1 {
-			plog.Panicf("unexpected multiple revisions in notification")
-		}
-		if w.send(WatchResponse{WatchID: w.id, Events: eb.evs, Revision: rev}) {
-			pendingEventsGauge.Add(float64(len(eb.evs)))
-		} else {
-			// move slow watcher to victims
-			w.minRev = rev + 1
-			if victim == nil {
-				victim = make(watcherBatch)
-			}
-			w.victim = true
-			victim[w] = eb
-			s.synced.delete(w)
-			slowWatcherGauge.Inc()
-		}
-	}
-	s.addVictim(victim)
-}
-
-func (s *watchableStore) addVictim(victim watcherBatch) {
-	if victim == nil {
-		return
-	}
-	s.victims = append(s.victims, victim)
-	select {
-	case s.victimc <- struct{}{}:
-	default:
-	}
-}
-
-func (s *watchableStore) rev() int64 { return s.store.Rev() }
-
-func (s *watchableStore) progress(w *watcher) {
-	s.mu.RLock()
-	defer s.mu.RUnlock()
-
-	if _, ok := s.synced.watchers[w]; ok {
-		w.send(WatchResponse{WatchID: w.id, Revision: s.rev()})
-		// If the ch is full, this watcher is receiving events.
-		// We do not need to send progress at all.
-	}
-}
-
-type watcher struct {
-	// the watcher key
-	key []byte
-	// end indicates the end of the range to watch.
-	// If end is set, the watcher is on a range.
-	end []byte
-
-	// victim is set when ch is blocked and undergoing victim processing
-	victim bool
-
-	// compacted is set when the watcher is removed because of compaction
-	compacted bool
-
-	// restore is true when the watcher is being restored from leader snapshot
-	// which means that this watcher has just been moved from "synced" to "unsynced"
-	// watcher group, possibly with a future revision when it was first added
-	// to the synced watcher
-	// "unsynced" watcher revision must always be <= current revision,
-	// except when the watcher were to be moved from "synced" watcher group
-	restore bool
-
-	// minRev is the minimum revision update the watcher will accept
-	minRev int64
-	id     WatchID
-
-	fcs []FilterFunc
-	// a chan to send out the watch response.
-	// The chan might be shared with other watchers.
-	ch chan<- WatchResponse
-}
-
-func (w *watcher) send(wr WatchResponse) bool {
-	progressEvent := len(wr.Events) == 0
-
-	if len(w.fcs) != 0 {
-		ne := make([]mvccpb.Event, 0, len(wr.Events))
-		for i := range wr.Events {
-			filtered := false
-			for _, filter := range w.fcs {
-				if filter(wr.Events[i]) {
-					filtered = true
-					break
-				}
-			}
-			if !filtered {
-				ne = append(ne, wr.Events[i])
-			}
-		}
-		wr.Events = ne
-	}
-
-	// if all events are filtered out, we should send nothing.
-	if !progressEvent && len(wr.Events) == 0 {
-		return true
-	}
-	select {
-	case w.ch <- wr:
-		return true
-	default:
-		return false
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/watchable_store_txn.go b/vendor/github.com/coreos/etcd/mvcc/watchable_store_txn.go
deleted file mode 100644
index 5c5bfda..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/watchable_store_txn.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-func (tw *watchableStoreTxnWrite) End() {
-	changes := tw.Changes()
-	if len(changes) == 0 {
-		tw.TxnWrite.End()
-		return
-	}
-
-	rev := tw.Rev() + 1
-	evs := make([]mvccpb.Event, len(changes))
-	for i, change := range changes {
-		evs[i].Kv = &changes[i]
-		if change.CreateRevision == 0 {
-			evs[i].Type = mvccpb.DELETE
-			evs[i].Kv.ModRevision = rev
-		} else {
-			evs[i].Type = mvccpb.PUT
-		}
-	}
-
-	// end write txn under watchable store lock so the updates are visible
-	// when asynchronous event posting checks the current store revision
-	tw.s.mu.Lock()
-	tw.s.notify(rev, evs)
-	tw.TxnWrite.End()
-	tw.s.mu.Unlock()
-}
-
-type watchableStoreTxnWrite struct {
-	TxnWrite
-	s *watchableStore
-}
-
-func (s *watchableStore) Write() TxnWrite { return &watchableStoreTxnWrite{s.store.Write(), s} }
diff --git a/vendor/github.com/coreos/etcd/mvcc/watcher.go b/vendor/github.com/coreos/etcd/mvcc/watcher.go
deleted file mode 100644
index bc0c632..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/watcher.go
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"bytes"
-	"errors"
-	"sync"
-
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-var (
-	ErrWatcherNotExist = errors.New("mvcc: watcher does not exist")
-)
-
-type WatchID int64
-
-// FilterFunc returns true if the given event should be filtered out.
-type FilterFunc func(e mvccpb.Event) bool
-
-type WatchStream interface {
-	// Watch creates a watcher. The watcher watches the events happening or
-	// happened on the given key or range [key, end) from the given startRev.
-	//
-	// The whole event history can be watched unless compacted.
-	// If `startRev` <=0, watch observes events after currentRev.
-	//
-	// The returned `id` is the ID of this watcher. It appears as WatchID
-	// in events that are sent to the created watcher through stream channel.
-	//
-	Watch(key, end []byte, startRev int64, fcs ...FilterFunc) WatchID
-
-	// Chan returns a chan. All watch response will be sent to the returned chan.
-	Chan() <-chan WatchResponse
-
-	// RequestProgress requests the progress of the watcher with given ID. The response
-	// will only be sent if the watcher is currently synced.
-	// The responses will be sent through the WatchRespone Chan attached
-	// with this stream to ensure correct ordering.
-	// The responses contains no events. The revision in the response is the progress
-	// of the watchers since the watcher is currently synced.
-	RequestProgress(id WatchID)
-
-	// Cancel cancels a watcher by giving its ID. If watcher does not exist, an error will be
-	// returned.
-	Cancel(id WatchID) error
-
-	// Close closes Chan and release all related resources.
-	Close()
-
-	// Rev returns the current revision of the KV the stream watches on.
-	Rev() int64
-}
-
-type WatchResponse struct {
-	// WatchID is the WatchID of the watcher this response sent to.
-	WatchID WatchID
-
-	// Events contains all the events that needs to send.
-	Events []mvccpb.Event
-
-	// Revision is the revision of the KV when the watchResponse is created.
-	// For a normal response, the revision should be the same as the last
-	// modified revision inside Events. For a delayed response to a unsynced
-	// watcher, the revision is greater than the last modified revision
-	// inside Events.
-	Revision int64
-
-	// CompactRevision is set when the watcher is cancelled due to compaction.
-	CompactRevision int64
-}
-
-// watchStream contains a collection of watchers that share
-// one streaming chan to send out watched events and other control events.
-type watchStream struct {
-	watchable watchable
-	ch        chan WatchResponse
-
-	mu sync.Mutex // guards fields below it
-	// nextID is the ID pre-allocated for next new watcher in this stream
-	nextID   WatchID
-	closed   bool
-	cancels  map[WatchID]cancelFunc
-	watchers map[WatchID]*watcher
-}
-
-// Watch creates a new watcher in the stream and returns its WatchID.
-// TODO: return error if ws is closed?
-func (ws *watchStream) Watch(key, end []byte, startRev int64, fcs ...FilterFunc) WatchID {
-	// prevent wrong range where key >= end lexicographically
-	// watch request with 'WithFromKey' has empty-byte range end
-	if len(end) != 0 && bytes.Compare(key, end) != -1 {
-		return -1
-	}
-
-	ws.mu.Lock()
-	defer ws.mu.Unlock()
-	if ws.closed {
-		return -1
-	}
-
-	id := ws.nextID
-	ws.nextID++
-
-	w, c := ws.watchable.watch(key, end, startRev, id, ws.ch, fcs...)
-
-	ws.cancels[id] = c
-	ws.watchers[id] = w
-	return id
-}
-
-func (ws *watchStream) Chan() <-chan WatchResponse {
-	return ws.ch
-}
-
-func (ws *watchStream) Cancel(id WatchID) error {
-	ws.mu.Lock()
-	cancel, ok := ws.cancels[id]
-	w := ws.watchers[id]
-	ok = ok && !ws.closed
-	ws.mu.Unlock()
-
-	if !ok {
-		return ErrWatcherNotExist
-	}
-	cancel()
-
-	ws.mu.Lock()
-	// The watch isn't removed until cancel so that if Close() is called,
-	// it will wait for the cancel. Otherwise, Close() could close the
-	// watch channel while the store is still posting events.
-	if ww := ws.watchers[id]; ww == w {
-		delete(ws.cancels, id)
-		delete(ws.watchers, id)
-	}
-	ws.mu.Unlock()
-
-	return nil
-}
-
-func (ws *watchStream) Close() {
-	ws.mu.Lock()
-	defer ws.mu.Unlock()
-
-	for _, cancel := range ws.cancels {
-		cancel()
-	}
-	ws.closed = true
-	close(ws.ch)
-	watchStreamGauge.Dec()
-}
-
-func (ws *watchStream) Rev() int64 {
-	ws.mu.Lock()
-	defer ws.mu.Unlock()
-	return ws.watchable.rev()
-}
-
-func (ws *watchStream) RequestProgress(id WatchID) {
-	ws.mu.Lock()
-	w, ok := ws.watchers[id]
-	ws.mu.Unlock()
-	if !ok {
-		return
-	}
-	ws.watchable.progress(w)
-}
diff --git a/vendor/github.com/coreos/etcd/mvcc/watcher_group.go b/vendor/github.com/coreos/etcd/mvcc/watcher_group.go
deleted file mode 100644
index b65c7bc..0000000
--- a/vendor/github.com/coreos/etcd/mvcc/watcher_group.go
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mvcc
-
-import (
-	"fmt"
-	"math"
-
-	"github.com/coreos/etcd/mvcc/mvccpb"
-	"github.com/coreos/etcd/pkg/adt"
-)
-
-var (
-	// watchBatchMaxRevs is the maximum distinct revisions that
-	// may be sent to an unsynced watcher at a time. Declared as
-	// var instead of const for testing purposes.
-	watchBatchMaxRevs = 1000
-)
-
-type eventBatch struct {
-	// evs is a batch of revision-ordered events
-	evs []mvccpb.Event
-	// revs is the minimum unique revisions observed for this batch
-	revs int
-	// moreRev is first revision with more events following this batch
-	moreRev int64
-}
-
-func (eb *eventBatch) add(ev mvccpb.Event) {
-	if eb.revs > watchBatchMaxRevs {
-		// maxed out batch size
-		return
-	}
-
-	if len(eb.evs) == 0 {
-		// base case
-		eb.revs = 1
-		eb.evs = append(eb.evs, ev)
-		return
-	}
-
-	// revision accounting
-	ebRev := eb.evs[len(eb.evs)-1].Kv.ModRevision
-	evRev := ev.Kv.ModRevision
-	if evRev > ebRev {
-		eb.revs++
-		if eb.revs > watchBatchMaxRevs {
-			eb.moreRev = evRev
-			return
-		}
-	}
-
-	eb.evs = append(eb.evs, ev)
-}
-
-type watcherBatch map[*watcher]*eventBatch
-
-func (wb watcherBatch) add(w *watcher, ev mvccpb.Event) {
-	eb := wb[w]
-	if eb == nil {
-		eb = &eventBatch{}
-		wb[w] = eb
-	}
-	eb.add(ev)
-}
-
-// newWatcherBatch maps watchers to their matched events. It enables quick
-// events look up by watcher.
-func newWatcherBatch(wg *watcherGroup, evs []mvccpb.Event) watcherBatch {
-	if len(wg.watchers) == 0 {
-		return nil
-	}
-
-	wb := make(watcherBatch)
-	for _, ev := range evs {
-		for w := range wg.watcherSetByKey(string(ev.Kv.Key)) {
-			if ev.Kv.ModRevision >= w.minRev {
-				// don't double notify
-				wb.add(w, ev)
-			}
-		}
-	}
-	return wb
-}
-
-type watcherSet map[*watcher]struct{}
-
-func (w watcherSet) add(wa *watcher) {
-	if _, ok := w[wa]; ok {
-		panic("add watcher twice!")
-	}
-	w[wa] = struct{}{}
-}
-
-func (w watcherSet) union(ws watcherSet) {
-	for wa := range ws {
-		w.add(wa)
-	}
-}
-
-func (w watcherSet) delete(wa *watcher) {
-	if _, ok := w[wa]; !ok {
-		panic("removing missing watcher!")
-	}
-	delete(w, wa)
-}
-
-type watcherSetByKey map[string]watcherSet
-
-func (w watcherSetByKey) add(wa *watcher) {
-	set := w[string(wa.key)]
-	if set == nil {
-		set = make(watcherSet)
-		w[string(wa.key)] = set
-	}
-	set.add(wa)
-}
-
-func (w watcherSetByKey) delete(wa *watcher) bool {
-	k := string(wa.key)
-	if v, ok := w[k]; ok {
-		if _, ok := v[wa]; ok {
-			delete(v, wa)
-			if len(v) == 0 {
-				// remove the set; nothing left
-				delete(w, k)
-			}
-			return true
-		}
-	}
-	return false
-}
-
-// watcherGroup is a collection of watchers organized by their ranges
-type watcherGroup struct {
-	// keyWatchers has the watchers that watch on a single key
-	keyWatchers watcherSetByKey
-	// ranges has the watchers that watch a range; it is sorted by interval
-	ranges adt.IntervalTree
-	// watchers is the set of all watchers
-	watchers watcherSet
-}
-
-func newWatcherGroup() watcherGroup {
-	return watcherGroup{
-		keyWatchers: make(watcherSetByKey),
-		watchers:    make(watcherSet),
-	}
-}
-
-// add puts a watcher in the group.
-func (wg *watcherGroup) add(wa *watcher) {
-	wg.watchers.add(wa)
-	if wa.end == nil {
-		wg.keyWatchers.add(wa)
-		return
-	}
-
-	// interval already registered?
-	ivl := adt.NewStringAffineInterval(string(wa.key), string(wa.end))
-	if iv := wg.ranges.Find(ivl); iv != nil {
-		iv.Val.(watcherSet).add(wa)
-		return
-	}
-
-	// not registered, put in interval tree
-	ws := make(watcherSet)
-	ws.add(wa)
-	wg.ranges.Insert(ivl, ws)
-}
-
-// contains is whether the given key has a watcher in the group.
-func (wg *watcherGroup) contains(key string) bool {
-	_, ok := wg.keyWatchers[key]
-	return ok || wg.ranges.Intersects(adt.NewStringAffinePoint(key))
-}
-
-// size gives the number of unique watchers in the group.
-func (wg *watcherGroup) size() int { return len(wg.watchers) }
-
-// delete removes a watcher from the group.
-func (wg *watcherGroup) delete(wa *watcher) bool {
-	if _, ok := wg.watchers[wa]; !ok {
-		return false
-	}
-	wg.watchers.delete(wa)
-	if wa.end == nil {
-		wg.keyWatchers.delete(wa)
-		return true
-	}
-
-	ivl := adt.NewStringAffineInterval(string(wa.key), string(wa.end))
-	iv := wg.ranges.Find(ivl)
-	if iv == nil {
-		return false
-	}
-
-	ws := iv.Val.(watcherSet)
-	delete(ws, wa)
-	if len(ws) == 0 {
-		// remove interval missing watchers
-		if ok := wg.ranges.Delete(ivl); !ok {
-			panic("could not remove watcher from interval tree")
-		}
-	}
-
-	return true
-}
-
-// choose selects watchers from the watcher group to update
-func (wg *watcherGroup) choose(maxWatchers int, curRev, compactRev int64) (*watcherGroup, int64) {
-	if len(wg.watchers) < maxWatchers {
-		return wg, wg.chooseAll(curRev, compactRev)
-	}
-	ret := newWatcherGroup()
-	for w := range wg.watchers {
-		if maxWatchers <= 0 {
-			break
-		}
-		maxWatchers--
-		ret.add(w)
-	}
-	return &ret, ret.chooseAll(curRev, compactRev)
-}
-
-func (wg *watcherGroup) chooseAll(curRev, compactRev int64) int64 {
-	minRev := int64(math.MaxInt64)
-	for w := range wg.watchers {
-		if w.minRev > curRev {
-			// after network partition, possibly choosing future revision watcher from restore operation
-			// with watch key "proxy-namespace__lostleader" and revision "math.MaxInt64 - 2"
-			// do not panic when such watcher had been moved from "synced" watcher during restore operation
-			if !w.restore {
-				panic(fmt.Errorf("watcher minimum revision %d should not exceed current revision %d", w.minRev, curRev))
-			}
-
-			// mark 'restore' done, since it's chosen
-			w.restore = false
-		}
-		if w.minRev < compactRev {
-			select {
-			case w.ch <- WatchResponse{WatchID: w.id, CompactRevision: compactRev}:
-				w.compacted = true
-				wg.delete(w)
-			default:
-				// retry next time
-			}
-			continue
-		}
-		if minRev > w.minRev {
-			minRev = w.minRev
-		}
-	}
-	return minRev
-}
-
-// watcherSetByKey gets the set of watchers that receive events on the given key.
-func (wg *watcherGroup) watcherSetByKey(key string) watcherSet {
-	wkeys := wg.keyWatchers[key]
-	wranges := wg.ranges.Stab(adt.NewStringAffinePoint(key))
-
-	// zero-copy cases
-	switch {
-	case len(wranges) == 0:
-		// no need to merge ranges or copy; reuse single-key set
-		return wkeys
-	case len(wranges) == 0 && len(wkeys) == 0:
-		return nil
-	case len(wranges) == 1 && len(wkeys) == 0:
-		return wranges[0].Val.(watcherSet)
-	}
-
-	// copy case
-	ret := make(watcherSet)
-	ret.union(wg.keyWatchers[key])
-	for _, item := range wranges {
-		ret.union(item.Val.(watcherSet))
-	}
-	return ret
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/adt/doc.go b/vendor/github.com/coreos/etcd/pkg/adt/doc.go
deleted file mode 100644
index 1a95591..0000000
--- a/vendor/github.com/coreos/etcd/pkg/adt/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package adt implements useful abstract data types.
-package adt
diff --git a/vendor/github.com/coreos/etcd/pkg/adt/interval_tree.go b/vendor/github.com/coreos/etcd/pkg/adt/interval_tree.go
deleted file mode 100644
index ec302e4..0000000
--- a/vendor/github.com/coreos/etcd/pkg/adt/interval_tree.go
+++ /dev/null
@@ -1,599 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adt
-
-import (
-	"bytes"
-	"math"
-)
-
-// Comparable is an interface for trichotomic comparisons.
-type Comparable interface {
-	// Compare gives the result of a 3-way comparison
-	// a.Compare(b) = 1 => a > b
-	// a.Compare(b) = 0 => a == b
-	// a.Compare(b) = -1 => a < b
-	Compare(c Comparable) int
-}
-
-type rbcolor int
-
-const (
-	black rbcolor = iota
-	red
-)
-
-// Interval implements a Comparable interval [begin, end)
-// TODO: support different sorts of intervals: (a,b), [a,b], (a, b]
-type Interval struct {
-	Begin Comparable
-	End   Comparable
-}
-
-// Compare on an interval gives == if the interval overlaps.
-func (ivl *Interval) Compare(c Comparable) int {
-	ivl2 := c.(*Interval)
-	ivbCmpBegin := ivl.Begin.Compare(ivl2.Begin)
-	ivbCmpEnd := ivl.Begin.Compare(ivl2.End)
-	iveCmpBegin := ivl.End.Compare(ivl2.Begin)
-
-	// ivl is left of ivl2
-	if ivbCmpBegin < 0 && iveCmpBegin <= 0 {
-		return -1
-	}
-
-	// iv is right of iv2
-	if ivbCmpEnd >= 0 {
-		return 1
-	}
-
-	return 0
-}
-
-type intervalNode struct {
-	// iv is the interval-value pair entry.
-	iv IntervalValue
-	// max endpoint of all descendent nodes.
-	max Comparable
-	// left and right are sorted by low endpoint of key interval
-	left, right *intervalNode
-	// parent is the direct ancestor of the node
-	parent *intervalNode
-	c      rbcolor
-}
-
-func (x *intervalNode) color() rbcolor {
-	if x == nil {
-		return black
-	}
-	return x.c
-}
-
-func (n *intervalNode) height() int {
-	if n == nil {
-		return 0
-	}
-	ld := n.left.height()
-	rd := n.right.height()
-	if ld < rd {
-		return rd + 1
-	}
-	return ld + 1
-}
-
-func (x *intervalNode) min() *intervalNode {
-	for x.left != nil {
-		x = x.left
-	}
-	return x
-}
-
-// successor is the next in-order node in the tree
-func (x *intervalNode) successor() *intervalNode {
-	if x.right != nil {
-		return x.right.min()
-	}
-	y := x.parent
-	for y != nil && x == y.right {
-		x = y
-		y = y.parent
-	}
-	return y
-}
-
-// updateMax updates the maximum values for a node and its ancestors
-func (x *intervalNode) updateMax() {
-	for x != nil {
-		oldmax := x.max
-		max := x.iv.Ivl.End
-		if x.left != nil && x.left.max.Compare(max) > 0 {
-			max = x.left.max
-		}
-		if x.right != nil && x.right.max.Compare(max) > 0 {
-			max = x.right.max
-		}
-		if oldmax.Compare(max) == 0 {
-			break
-		}
-		x.max = max
-		x = x.parent
-	}
-}
-
-type nodeVisitor func(n *intervalNode) bool
-
-// visit will call a node visitor on each node that overlaps the given interval
-func (x *intervalNode) visit(iv *Interval, nv nodeVisitor) bool {
-	if x == nil {
-		return true
-	}
-	v := iv.Compare(&x.iv.Ivl)
-	switch {
-	case v < 0:
-		if !x.left.visit(iv, nv) {
-			return false
-		}
-	case v > 0:
-		maxiv := Interval{x.iv.Ivl.Begin, x.max}
-		if maxiv.Compare(iv) == 0 {
-			if !x.left.visit(iv, nv) || !x.right.visit(iv, nv) {
-				return false
-			}
-		}
-	default:
-		if !x.left.visit(iv, nv) || !nv(x) || !x.right.visit(iv, nv) {
-			return false
-		}
-	}
-	return true
-}
-
-type IntervalValue struct {
-	Ivl Interval
-	Val interface{}
-}
-
-// IntervalTree represents a (mostly) textbook implementation of the
-// "Introduction to Algorithms" (Cormen et al, 2nd ed.) chapter 13 red-black tree
-// and chapter 14.3 interval tree with search supporting "stabbing queries".
-type IntervalTree struct {
-	root  *intervalNode
-	count int
-}
-
-// Delete removes the node with the given interval from the tree, returning
-// true if a node is in fact removed.
-func (ivt *IntervalTree) Delete(ivl Interval) bool {
-	z := ivt.find(ivl)
-	if z == nil {
-		return false
-	}
-
-	y := z
-	if z.left != nil && z.right != nil {
-		y = z.successor()
-	}
-
-	x := y.left
-	if x == nil {
-		x = y.right
-	}
-	if x != nil {
-		x.parent = y.parent
-	}
-
-	if y.parent == nil {
-		ivt.root = x
-	} else {
-		if y == y.parent.left {
-			y.parent.left = x
-		} else {
-			y.parent.right = x
-		}
-		y.parent.updateMax()
-	}
-	if y != z {
-		z.iv = y.iv
-		z.updateMax()
-	}
-
-	if y.color() == black && x != nil {
-		ivt.deleteFixup(x)
-	}
-
-	ivt.count--
-	return true
-}
-
-func (ivt *IntervalTree) deleteFixup(x *intervalNode) {
-	for x != ivt.root && x.color() == black && x.parent != nil {
-		if x == x.parent.left {
-			w := x.parent.right
-			if w.color() == red {
-				w.c = black
-				x.parent.c = red
-				ivt.rotateLeft(x.parent)
-				w = x.parent.right
-			}
-			if w == nil {
-				break
-			}
-			if w.left.color() == black && w.right.color() == black {
-				w.c = red
-				x = x.parent
-			} else {
-				if w.right.color() == black {
-					w.left.c = black
-					w.c = red
-					ivt.rotateRight(w)
-					w = x.parent.right
-				}
-				w.c = x.parent.color()
-				x.parent.c = black
-				w.right.c = black
-				ivt.rotateLeft(x.parent)
-				x = ivt.root
-			}
-		} else {
-			// same as above but with left and right exchanged
-			w := x.parent.left
-			if w.color() == red {
-				w.c = black
-				x.parent.c = red
-				ivt.rotateRight(x.parent)
-				w = x.parent.left
-			}
-			if w == nil {
-				break
-			}
-			if w.left.color() == black && w.right.color() == black {
-				w.c = red
-				x = x.parent
-			} else {
-				if w.left.color() == black {
-					w.right.c = black
-					w.c = red
-					ivt.rotateLeft(w)
-					w = x.parent.left
-				}
-				w.c = x.parent.color()
-				x.parent.c = black
-				w.left.c = black
-				ivt.rotateRight(x.parent)
-				x = ivt.root
-			}
-		}
-	}
-	if x != nil {
-		x.c = black
-	}
-}
-
-// Insert adds a node with the given interval into the tree.
-func (ivt *IntervalTree) Insert(ivl Interval, val interface{}) {
-	var y *intervalNode
-	z := &intervalNode{iv: IntervalValue{ivl, val}, max: ivl.End, c: red}
-	x := ivt.root
-	for x != nil {
-		y = x
-		if z.iv.Ivl.Begin.Compare(x.iv.Ivl.Begin) < 0 {
-			x = x.left
-		} else {
-			x = x.right
-		}
-	}
-
-	z.parent = y
-	if y == nil {
-		ivt.root = z
-	} else {
-		if z.iv.Ivl.Begin.Compare(y.iv.Ivl.Begin) < 0 {
-			y.left = z
-		} else {
-			y.right = z
-		}
-		y.updateMax()
-	}
-	z.c = red
-	ivt.insertFixup(z)
-	ivt.count++
-}
-
-func (ivt *IntervalTree) insertFixup(z *intervalNode) {
-	for z.parent != nil && z.parent.parent != nil && z.parent.color() == red {
-		if z.parent == z.parent.parent.left {
-			y := z.parent.parent.right
-			if y.color() == red {
-				y.c = black
-				z.parent.c = black
-				z.parent.parent.c = red
-				z = z.parent.parent
-			} else {
-				if z == z.parent.right {
-					z = z.parent
-					ivt.rotateLeft(z)
-				}
-				z.parent.c = black
-				z.parent.parent.c = red
-				ivt.rotateRight(z.parent.parent)
-			}
-		} else {
-			// same as then with left/right exchanged
-			y := z.parent.parent.left
-			if y.color() == red {
-				y.c = black
-				z.parent.c = black
-				z.parent.parent.c = red
-				z = z.parent.parent
-			} else {
-				if z == z.parent.left {
-					z = z.parent
-					ivt.rotateRight(z)
-				}
-				z.parent.c = black
-				z.parent.parent.c = red
-				ivt.rotateLeft(z.parent.parent)
-			}
-		}
-	}
-	ivt.root.c = black
-}
-
-// rotateLeft moves x so it is left of its right child
-func (ivt *IntervalTree) rotateLeft(x *intervalNode) {
-	y := x.right
-	x.right = y.left
-	if y.left != nil {
-		y.left.parent = x
-	}
-	x.updateMax()
-	ivt.replaceParent(x, y)
-	y.left = x
-	y.updateMax()
-}
-
-// rotateLeft moves x so it is right of its left child
-func (ivt *IntervalTree) rotateRight(x *intervalNode) {
-	if x == nil {
-		return
-	}
-	y := x.left
-	x.left = y.right
-	if y.right != nil {
-		y.right.parent = x
-	}
-	x.updateMax()
-	ivt.replaceParent(x, y)
-	y.right = x
-	y.updateMax()
-}
-
-// replaceParent replaces x's parent with y
-func (ivt *IntervalTree) replaceParent(x *intervalNode, y *intervalNode) {
-	y.parent = x.parent
-	if x.parent == nil {
-		ivt.root = y
-	} else {
-		if x == x.parent.left {
-			x.parent.left = y
-		} else {
-			x.parent.right = y
-		}
-		x.parent.updateMax()
-	}
-	x.parent = y
-}
-
-// Len gives the number of elements in the tree
-func (ivt *IntervalTree) Len() int { return ivt.count }
-
-// Height is the number of levels in the tree; one node has height 1.
-func (ivt *IntervalTree) Height() int { return ivt.root.height() }
-
-// MaxHeight is the expected maximum tree height given the number of nodes
-func (ivt *IntervalTree) MaxHeight() int {
-	return int((2 * math.Log2(float64(ivt.Len()+1))) + 0.5)
-}
-
-// IntervalVisitor is used on tree searches; return false to stop searching.
-type IntervalVisitor func(n *IntervalValue) bool
-
-// Visit calls a visitor function on every tree node intersecting the given interval.
-// It will visit each interval [x, y) in ascending order sorted on x.
-func (ivt *IntervalTree) Visit(ivl Interval, ivv IntervalVisitor) {
-	ivt.root.visit(&ivl, func(n *intervalNode) bool { return ivv(&n.iv) })
-}
-
-// find the exact node for a given interval
-func (ivt *IntervalTree) find(ivl Interval) (ret *intervalNode) {
-	f := func(n *intervalNode) bool {
-		if n.iv.Ivl != ivl {
-			return true
-		}
-		ret = n
-		return false
-	}
-	ivt.root.visit(&ivl, f)
-	return ret
-}
-
-// Find gets the IntervalValue for the node matching the given interval
-func (ivt *IntervalTree) Find(ivl Interval) (ret *IntervalValue) {
-	n := ivt.find(ivl)
-	if n == nil {
-		return nil
-	}
-	return &n.iv
-}
-
-// Intersects returns true if there is some tree node intersecting the given interval.
-func (ivt *IntervalTree) Intersects(iv Interval) bool {
-	x := ivt.root
-	for x != nil && iv.Compare(&x.iv.Ivl) != 0 {
-		if x.left != nil && x.left.max.Compare(iv.Begin) > 0 {
-			x = x.left
-		} else {
-			x = x.right
-		}
-	}
-	return x != nil
-}
-
-// Contains returns true if the interval tree's keys cover the entire given interval.
-func (ivt *IntervalTree) Contains(ivl Interval) bool {
-	var maxEnd, minBegin Comparable
-
-	isContiguous := true
-	ivt.Visit(ivl, func(n *IntervalValue) bool {
-		if minBegin == nil {
-			minBegin = n.Ivl.Begin
-			maxEnd = n.Ivl.End
-			return true
-		}
-		if maxEnd.Compare(n.Ivl.Begin) < 0 {
-			isContiguous = false
-			return false
-		}
-		if n.Ivl.End.Compare(maxEnd) > 0 {
-			maxEnd = n.Ivl.End
-		}
-		return true
-	})
-
-	return isContiguous && minBegin != nil && maxEnd.Compare(ivl.End) >= 0 && minBegin.Compare(ivl.Begin) <= 0
-}
-
-// Stab returns a slice with all elements in the tree intersecting the interval.
-func (ivt *IntervalTree) Stab(iv Interval) (ivs []*IntervalValue) {
-	if ivt.count == 0 {
-		return nil
-	}
-	f := func(n *IntervalValue) bool { ivs = append(ivs, n); return true }
-	ivt.Visit(iv, f)
-	return ivs
-}
-
-// Union merges a given interval tree into the receiver.
-func (ivt *IntervalTree) Union(inIvt IntervalTree, ivl Interval) {
-	f := func(n *IntervalValue) bool {
-		ivt.Insert(n.Ivl, n.Val)
-		return true
-	}
-	inIvt.Visit(ivl, f)
-}
-
-type StringComparable string
-
-func (s StringComparable) Compare(c Comparable) int {
-	sc := c.(StringComparable)
-	if s < sc {
-		return -1
-	}
-	if s > sc {
-		return 1
-	}
-	return 0
-}
-
-func NewStringInterval(begin, end string) Interval {
-	return Interval{StringComparable(begin), StringComparable(end)}
-}
-
-func NewStringPoint(s string) Interval {
-	return Interval{StringComparable(s), StringComparable(s + "\x00")}
-}
-
-// StringAffineComparable treats "" as > all other strings
-type StringAffineComparable string
-
-func (s StringAffineComparable) Compare(c Comparable) int {
-	sc := c.(StringAffineComparable)
-
-	if len(s) == 0 {
-		if len(sc) == 0 {
-			return 0
-		}
-		return 1
-	}
-	if len(sc) == 0 {
-		return -1
-	}
-
-	if s < sc {
-		return -1
-	}
-	if s > sc {
-		return 1
-	}
-	return 0
-}
-
-func NewStringAffineInterval(begin, end string) Interval {
-	return Interval{StringAffineComparable(begin), StringAffineComparable(end)}
-}
-func NewStringAffinePoint(s string) Interval {
-	return NewStringAffineInterval(s, s+"\x00")
-}
-
-func NewInt64Interval(a int64, b int64) Interval {
-	return Interval{Int64Comparable(a), Int64Comparable(b)}
-}
-
-func NewInt64Point(a int64) Interval {
-	return Interval{Int64Comparable(a), Int64Comparable(a + 1)}
-}
-
-type Int64Comparable int64
-
-func (v Int64Comparable) Compare(c Comparable) int {
-	vc := c.(Int64Comparable)
-	cmp := v - vc
-	if cmp < 0 {
-		return -1
-	}
-	if cmp > 0 {
-		return 1
-	}
-	return 0
-}
-
-// BytesAffineComparable treats empty byte arrays as > all other byte arrays
-type BytesAffineComparable []byte
-
-func (b BytesAffineComparable) Compare(c Comparable) int {
-	bc := c.(BytesAffineComparable)
-
-	if len(b) == 0 {
-		if len(bc) == 0 {
-			return 0
-		}
-		return 1
-	}
-	if len(bc) == 0 {
-		return -1
-	}
-
-	return bytes.Compare(b, bc)
-}
-
-func NewBytesAffineInterval(begin, end []byte) Interval {
-	return Interval{BytesAffineComparable(begin), BytesAffineComparable(end)}
-}
-func NewBytesAffinePoint(b []byte) Interval {
-	be := make([]byte, len(b)+1)
-	copy(be, b)
-	be[len(b)] = 0
-	return NewBytesAffineInterval(b, be)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/contention/contention.go b/vendor/github.com/coreos/etcd/pkg/contention/contention.go
deleted file mode 100644
index 26ce9a2..0000000
--- a/vendor/github.com/coreos/etcd/pkg/contention/contention.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package contention
-
-import (
-	"sync"
-	"time"
-)
-
-// TimeoutDetector detects routine starvations by
-// observing the actual time duration to finish an action
-// or between two events that should happen in a fixed
-// interval. If the observed duration is longer than
-// the expectation, the detector will report the result.
-type TimeoutDetector struct {
-	mu          sync.Mutex // protects all
-	maxDuration time.Duration
-	// map from event to time
-	// time is the last seen time of the event.
-	records map[uint64]time.Time
-}
-
-// NewTimeoutDetector creates the TimeoutDetector.
-func NewTimeoutDetector(maxDuration time.Duration) *TimeoutDetector {
-	return &TimeoutDetector{
-		maxDuration: maxDuration,
-		records:     make(map[uint64]time.Time),
-	}
-}
-
-// Reset resets the NewTimeoutDetector.
-func (td *TimeoutDetector) Reset() {
-	td.mu.Lock()
-	defer td.mu.Unlock()
-
-	td.records = make(map[uint64]time.Time)
-}
-
-// Observe observes an event for given id. It returns false and exceeded duration
-// if the interval is longer than the expectation.
-func (td *TimeoutDetector) Observe(which uint64) (bool, time.Duration) {
-	td.mu.Lock()
-	defer td.mu.Unlock()
-
-	ok := true
-	now := time.Now()
-	exceed := time.Duration(0)
-
-	if pt, found := td.records[which]; found {
-		exceed = now.Sub(pt) - td.maxDuration
-		if exceed > 0 {
-			ok = false
-		}
-	}
-	td.records[which] = now
-	return ok, exceed
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/contention/doc.go b/vendor/github.com/coreos/etcd/pkg/contention/doc.go
deleted file mode 100644
index daf4522..0000000
--- a/vendor/github.com/coreos/etcd/pkg/contention/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package contention provides facilities for detecting system contention.
-package contention
diff --git a/vendor/github.com/coreos/etcd/pkg/cors/cors.go b/vendor/github.com/coreos/etcd/pkg/cors/cors.go
deleted file mode 100644
index 0c64f16..0000000
--- a/vendor/github.com/coreos/etcd/pkg/cors/cors.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package cors handles cross-origin HTTP requests (CORS).
-package cors
-
-import (
-	"fmt"
-	"net/http"
-	"net/url"
-	"sort"
-	"strings"
-)
-
-type CORSInfo map[string]bool
-
-// Set implements the flag.Value interface to allow users to define a list of CORS origins
-func (ci *CORSInfo) Set(s string) error {
-	m := make(map[string]bool)
-	for _, v := range strings.Split(s, ",") {
-		v = strings.TrimSpace(v)
-		if v == "" {
-			continue
-		}
-		if v != "*" {
-			if _, err := url.Parse(v); err != nil {
-				return fmt.Errorf("Invalid CORS origin: %s", err)
-			}
-		}
-		m[v] = true
-
-	}
-	*ci = CORSInfo(m)
-	return nil
-}
-
-func (ci *CORSInfo) String() string {
-	o := make([]string, 0)
-	for k := range *ci {
-		o = append(o, k)
-	}
-	sort.StringSlice(o).Sort()
-	return strings.Join(o, ",")
-}
-
-// OriginAllowed determines whether the server will allow a given CORS origin.
-func (c CORSInfo) OriginAllowed(origin string) bool {
-	return c["*"] || c[origin]
-}
-
-type CORSHandler struct {
-	Handler http.Handler
-	Info    *CORSInfo
-}
-
-// addHeader adds the correct cors headers given an origin
-func (h *CORSHandler) addHeader(w http.ResponseWriter, origin string) {
-	w.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
-	w.Header().Add("Access-Control-Allow-Origin", origin)
-	w.Header().Add("Access-Control-Allow-Headers", "accept, content-type, authorization")
-}
-
-// ServeHTTP adds the correct CORS headers based on the origin and returns immediately
-// with a 200 OK if the method is OPTIONS.
-func (h *CORSHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
-	// Write CORS header.
-	if h.Info.OriginAllowed("*") {
-		h.addHeader(w, "*")
-	} else if origin := req.Header.Get("Origin"); h.Info.OriginAllowed(origin) {
-		h.addHeader(w, origin)
-	}
-
-	if req.Method == "OPTIONS" {
-		w.WriteHeader(http.StatusOK)
-		return
-	}
-
-	h.Handler.ServeHTTP(w, req)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/cpuutil/doc.go b/vendor/github.com/coreos/etcd/pkg/cpuutil/doc.go
deleted file mode 100644
index 0323b2d..0000000
--- a/vendor/github.com/coreos/etcd/pkg/cpuutil/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package cpuutil provides facilities for detecting cpu-specific features.
-package cpuutil
diff --git a/vendor/github.com/coreos/etcd/pkg/cpuutil/endian.go b/vendor/github.com/coreos/etcd/pkg/cpuutil/endian.go
deleted file mode 100644
index 6ab898d..0000000
--- a/vendor/github.com/coreos/etcd/pkg/cpuutil/endian.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cpuutil
-
-import (
-	"encoding/binary"
-	"unsafe"
-)
-
-const intWidth int = int(unsafe.Sizeof(0))
-
-var byteOrder binary.ByteOrder
-
-// ByteOrder returns the byte order for the CPU's native endianness.
-func ByteOrder() binary.ByteOrder { return byteOrder }
-
-func init() {
-	var i int = 0x1
-	if v := (*[intWidth]byte)(unsafe.Pointer(&i)); v[0] == 0 {
-		byteOrder = binary.BigEndian
-	} else {
-		byteOrder = binary.LittleEndian
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/crc/crc.go b/vendor/github.com/coreos/etcd/pkg/crc/crc.go
deleted file mode 100644
index 4b998a4..0000000
--- a/vendor/github.com/coreos/etcd/pkg/crc/crc.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package crc provides utility function for cyclic redundancy check
-// algorithms.
-package crc
-
-import (
-	"hash"
-	"hash/crc32"
-)
-
-// The size of a CRC-32 checksum in bytes.
-const Size = 4
-
-type digest struct {
-	crc uint32
-	tab *crc32.Table
-}
-
-// New creates a new hash.Hash32 computing the CRC-32 checksum
-// using the polynomial represented by the Table.
-// Modified by xiangli to take a prevcrc.
-func New(prev uint32, tab *crc32.Table) hash.Hash32 { return &digest{prev, tab} }
-
-func (d *digest) Size() int { return Size }
-
-func (d *digest) BlockSize() int { return 1 }
-
-func (d *digest) Reset() { d.crc = 0 }
-
-func (d *digest) Write(p []byte) (n int, err error) {
-	d.crc = crc32.Update(d.crc, d.tab, p)
-	return len(p), nil
-}
-
-func (d *digest) Sum32() uint32 { return d.crc }
-
-func (d *digest) Sum(in []byte) []byte {
-	s := d.Sum32()
-	return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/debugutil/doc.go b/vendor/github.com/coreos/etcd/pkg/debugutil/doc.go
deleted file mode 100644
index 74499eb..0000000
--- a/vendor/github.com/coreos/etcd/pkg/debugutil/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package debugutil includes utility functions for debugging.
-package debugutil
diff --git a/vendor/github.com/coreos/etcd/pkg/debugutil/pprof.go b/vendor/github.com/coreos/etcd/pkg/debugutil/pprof.go
deleted file mode 100644
index 8d5544a..0000000
--- a/vendor/github.com/coreos/etcd/pkg/debugutil/pprof.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package debugutil
-
-import (
-	"net/http"
-	"net/http/pprof"
-	"runtime"
-)
-
-const HTTPPrefixPProf = "/debug/pprof"
-
-// PProfHandlers returns a map of pprof handlers keyed by the HTTP path.
-func PProfHandlers() map[string]http.Handler {
-	// set only when there's no existing setting
-	if runtime.SetMutexProfileFraction(-1) == 0 {
-		// 1 out of 5 mutex events are reported, on average
-		runtime.SetMutexProfileFraction(5)
-	}
-
-	m := make(map[string]http.Handler)
-
-	m[HTTPPrefixPProf+"/"] = http.HandlerFunc(pprof.Index)
-	m[HTTPPrefixPProf+"/profile"] = http.HandlerFunc(pprof.Profile)
-	m[HTTPPrefixPProf+"/symbol"] = http.HandlerFunc(pprof.Symbol)
-	m[HTTPPrefixPProf+"/cmdline"] = http.HandlerFunc(pprof.Cmdline)
-	m[HTTPPrefixPProf+"/trace "] = http.HandlerFunc(pprof.Trace)
-	m[HTTPPrefixPProf+"/heap"] = pprof.Handler("heap")
-	m[HTTPPrefixPProf+"/goroutine"] = pprof.Handler("goroutine")
-	m[HTTPPrefixPProf+"/threadcreate"] = pprof.Handler("threadcreate")
-	m[HTTPPrefixPProf+"/block"] = pprof.Handler("block")
-	m[HTTPPrefixPProf+"/mutex"] = pprof.Handler("mutex")
-
-	return m
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/dir_unix.go b/vendor/github.com/coreos/etcd/pkg/fileutil/dir_unix.go
deleted file mode 100644
index 58a77df..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/dir_unix.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !windows
-
-package fileutil
-
-import "os"
-
-// OpenDir opens a directory for syncing.
-func OpenDir(path string) (*os.File, error) { return os.Open(path) }
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/dir_windows.go b/vendor/github.com/coreos/etcd/pkg/fileutil/dir_windows.go
deleted file mode 100644
index c123395..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/dir_windows.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build windows
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-// OpenDir opens a directory in windows with write access for syncing.
-func OpenDir(path string) (*os.File, error) {
-	fd, err := openDir(path)
-	if err != nil {
-		return nil, err
-	}
-	return os.NewFile(uintptr(fd), path), nil
-}
-
-func openDir(path string) (fd syscall.Handle, err error) {
-	if len(path) == 0 {
-		return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND
-	}
-	pathp, err := syscall.UTF16PtrFromString(path)
-	if err != nil {
-		return syscall.InvalidHandle, err
-	}
-	access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE)
-	sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE)
-	createmode := uint32(syscall.OPEN_EXISTING)
-	fl := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
-	return syscall.CreateFile(pathp, access, sharemode, nil, createmode, fl, 0)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go b/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go
deleted file mode 100644
index fce5126..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/fileutil.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package fileutil implements utility functions related to files and paths.
-package fileutil
-
-import (
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"sort"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-const (
-	// PrivateFileMode grants owner to read/write a file.
-	PrivateFileMode = 0600
-	// PrivateDirMode grants owner to make/remove files inside the directory.
-	PrivateDirMode = 0700
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "pkg/fileutil")
-)
-
-// IsDirWriteable checks if dir is writable by writing and removing a file
-// to dir. It returns nil if dir is writable.
-func IsDirWriteable(dir string) error {
-	f := filepath.Join(dir, ".touch")
-	if err := ioutil.WriteFile(f, []byte(""), PrivateFileMode); err != nil {
-		return err
-	}
-	return os.Remove(f)
-}
-
-// ReadDir returns the filenames in the given directory in sorted order.
-func ReadDir(dirpath string) ([]string, error) {
-	dir, err := os.Open(dirpath)
-	if err != nil {
-		return nil, err
-	}
-	defer dir.Close()
-	names, err := dir.Readdirnames(-1)
-	if err != nil {
-		return nil, err
-	}
-	sort.Strings(names)
-	return names, nil
-}
-
-// TouchDirAll is similar to os.MkdirAll. It creates directories with 0700 permission if any directory
-// does not exists. TouchDirAll also ensures the given directory is writable.
-func TouchDirAll(dir string) error {
-	// If path is already a directory, MkdirAll does nothing
-	// and returns nil.
-	err := os.MkdirAll(dir, PrivateDirMode)
-	if err != nil {
-		// if mkdirAll("a/text") and "text" is not
-		// a directory, this will return syscall.ENOTDIR
-		return err
-	}
-	return IsDirWriteable(dir)
-}
-
-// CreateDirAll is similar to TouchDirAll but returns error
-// if the deepest directory was not empty.
-func CreateDirAll(dir string) error {
-	err := TouchDirAll(dir)
-	if err == nil {
-		var ns []string
-		ns, err = ReadDir(dir)
-		if err != nil {
-			return err
-		}
-		if len(ns) != 0 {
-			err = fmt.Errorf("expected %q to be empty, got %q", dir, ns)
-		}
-	}
-	return err
-}
-
-func Exist(name string) bool {
-	_, err := os.Stat(name)
-	return err == nil
-}
-
-// ZeroToEnd zeros a file starting from SEEK_CUR to its SEEK_END. May temporarily
-// shorten the length of the file.
-func ZeroToEnd(f *os.File) error {
-	// TODO: support FALLOC_FL_ZERO_RANGE
-	off, err := f.Seek(0, io.SeekCurrent)
-	if err != nil {
-		return err
-	}
-	lenf, lerr := f.Seek(0, io.SeekEnd)
-	if lerr != nil {
-		return lerr
-	}
-	if err = f.Truncate(off); err != nil {
-		return err
-	}
-	// make sure blocks remain allocated
-	if err = Preallocate(f, lenf, true); err != nil {
-		return err
-	}
-	_, err = f.Seek(off, io.SeekStart)
-	return err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock.go
deleted file mode 100644
index 338627f..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package fileutil
-
-import (
-	"errors"
-	"os"
-)
-
-var (
-	ErrLocked = errors.New("fileutil: file already locked")
-)
-
-type LockedFile struct{ *os.File }
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_flock.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_flock.go
deleted file mode 100644
index 542550b..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_flock.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !windows,!plan9,!solaris
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-func flockTryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
-		f.Close()
-		if err == syscall.EWOULDBLOCK {
-			err = ErrLocked
-		}
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
-
-func flockLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil {
-		f.Close()
-		return nil, err
-	}
-	return &LockedFile{f}, err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_linux.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_linux.go
deleted file mode 100644
index 939fea6..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_linux.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build linux
-
-package fileutil
-
-import (
-	"io"
-	"os"
-	"syscall"
-)
-
-// This used to call syscall.Flock() but that call fails with EBADF on NFS.
-// An alternative is lockf() which works on NFS but that call lets a process lock
-// the same file twice. Instead, use Linux's non-standard open file descriptor
-// locks which will block if the process already holds the file lock.
-//
-// constants from /usr/include/bits/fcntl-linux.h
-const (
-	F_OFD_GETLK  = 37
-	F_OFD_SETLK  = 37
-	F_OFD_SETLKW = 38
-)
-
-var (
-	wrlck = syscall.Flock_t{
-		Type:   syscall.F_WRLCK,
-		Whence: int16(io.SeekStart),
-		Start:  0,
-		Len:    0,
-	}
-
-	linuxTryLockFile = flockTryLockFile
-	linuxLockFile    = flockLockFile
-)
-
-func init() {
-	// use open file descriptor locks if the system supports it
-	getlk := syscall.Flock_t{Type: syscall.F_RDLCK}
-	if err := syscall.FcntlFlock(0, F_OFD_GETLK, &getlk); err == nil {
-		linuxTryLockFile = ofdTryLockFile
-		linuxLockFile = ofdLockFile
-	}
-}
-
-func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	return linuxTryLockFile(path, flag, perm)
-}
-
-func ofdTryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-
-	flock := wrlck
-	if err = syscall.FcntlFlock(f.Fd(), F_OFD_SETLK, &flock); err != nil {
-		f.Close()
-		if err == syscall.EWOULDBLOCK {
-			err = ErrLocked
-		}
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
-
-func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	return linuxLockFile(path, flag, perm)
-}
-
-func ofdLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-
-	flock := wrlck
-	err = syscall.FcntlFlock(f.Fd(), F_OFD_SETLKW, &flock)
-
-	if err != nil {
-		f.Close()
-		return nil, err
-	}
-	return &LockedFile{f}, err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go
deleted file mode 100644
index fee6a7c..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-	"time"
-)
-
-func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	if err := os.Chmod(path, syscall.DMEXCL|PrivateFileMode); err != nil {
-		return nil, err
-	}
-	f, err := os.Open(path, flag, perm)
-	if err != nil {
-		return nil, ErrLocked
-	}
-	return &LockedFile{f}, nil
-}
-
-func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	if err := os.Chmod(path, syscall.DMEXCL|PrivateFileMode); err != nil {
-		return nil, err
-	}
-	for {
-		f, err := os.OpenFile(path, flag, perm)
-		if err == nil {
-			return &LockedFile{f}, nil
-		}
-		time.Sleep(10 * time.Millisecond)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go
deleted file mode 100644
index 352ca55..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build solaris
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	var lock syscall.Flock_t
-	lock.Start = 0
-	lock.Len = 0
-	lock.Pid = 0
-	lock.Type = syscall.F_WRLCK
-	lock.Whence = 0
-	lock.Pid = 0
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err := syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &lock); err != nil {
-		f.Close()
-		if err == syscall.EAGAIN {
-			err = ErrLocked
-		}
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
-
-func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	var lock syscall.Flock_t
-	lock.Start = 0
-	lock.Len = 0
-	lock.Pid = 0
-	lock.Type = syscall.F_WRLCK
-	lock.Whence = 0
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err = syscall.FcntlFlock(f.Fd(), syscall.F_SETLKW, &lock); err != nil {
-		f.Close()
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_unix.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_unix.go
deleted file mode 100644
index ed01164..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_unix.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !windows,!plan9,!solaris,!linux
-
-package fileutil
-
-import (
-	"os"
-)
-
-func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	return flockTryLockFile(path, flag, perm)
-}
-
-func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	return flockLockFile(path, flag, perm)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_windows.go b/vendor/github.com/coreos/etcd/pkg/fileutil/lock_windows.go
deleted file mode 100644
index b181723..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/lock_windows.go
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build windows
-
-package fileutil
-
-import (
-	"errors"
-	"fmt"
-	"os"
-	"syscall"
-	"unsafe"
-)
-
-var (
-	modkernel32    = syscall.NewLazyDLL("kernel32.dll")
-	procLockFileEx = modkernel32.NewProc("LockFileEx")
-
-	errLocked = errors.New("The process cannot access the file because another process has locked a portion of the file.")
-)
-
-const (
-	// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx
-	LOCKFILE_EXCLUSIVE_LOCK   = 2
-	LOCKFILE_FAIL_IMMEDIATELY = 1
-
-	// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
-	errLockViolation syscall.Errno = 0x21
-)
-
-func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := open(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err := lockFile(syscall.Handle(f.Fd()), LOCKFILE_FAIL_IMMEDIATELY); err != nil {
-		f.Close()
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
-
-func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := open(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err := lockFile(syscall.Handle(f.Fd()), 0); err != nil {
-		f.Close()
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
-
-func open(path string, flag int, perm os.FileMode) (*os.File, error) {
-	if path == "" {
-		return nil, fmt.Errorf("cannot open empty filename")
-	}
-	var access uint32
-	switch flag {
-	case syscall.O_RDONLY:
-		access = syscall.GENERIC_READ
-	case syscall.O_WRONLY:
-		access = syscall.GENERIC_WRITE
-	case syscall.O_RDWR:
-		access = syscall.GENERIC_READ | syscall.GENERIC_WRITE
-	case syscall.O_WRONLY | syscall.O_CREAT:
-		access = syscall.GENERIC_ALL
-	default:
-		panic(fmt.Errorf("flag %v is not supported", flag))
-	}
-	fd, err := syscall.CreateFile(&(syscall.StringToUTF16(path)[0]),
-		access,
-		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-		nil,
-		syscall.OPEN_ALWAYS,
-		syscall.FILE_ATTRIBUTE_NORMAL,
-		0)
-	if err != nil {
-		return nil, err
-	}
-	return os.NewFile(uintptr(fd), path), nil
-}
-
-func lockFile(fd syscall.Handle, flags uint32) error {
-	var flag uint32 = LOCKFILE_EXCLUSIVE_LOCK
-	flag |= flags
-	if fd == syscall.InvalidHandle {
-		return nil
-	}
-	err := lockFileEx(fd, flag, 1, 0, &syscall.Overlapped{})
-	if err == nil {
-		return nil
-	} else if err.Error() == errLocked.Error() {
-		return ErrLocked
-	} else if err != errLockViolation {
-		return err
-	}
-	return nil
-}
-
-func lockFileEx(h syscall.Handle, flags, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
-	var reserved uint32 = 0
-	r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(h), uintptr(flags), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = syscall.EINVAL
-		}
-	}
-	return err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate.go b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate.go
deleted file mode 100644
index c747b7c..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package fileutil
-
-import (
-	"io"
-	"os"
-)
-
-// Preallocate tries to allocate the space for given
-// file. This operation is only supported on linux by a
-// few filesystems (btrfs, ext4, etc.).
-// If the operation is unsupported, no error will be returned.
-// Otherwise, the error encountered will be returned.
-func Preallocate(f *os.File, sizeInBytes int64, extendFile bool) error {
-	if sizeInBytes == 0 {
-		// fallocate will return EINVAL if length is 0; skip
-		return nil
-	}
-	if extendFile {
-		return preallocExtend(f, sizeInBytes)
-	}
-	return preallocFixed(f, sizeInBytes)
-}
-
-func preallocExtendTrunc(f *os.File, sizeInBytes int64) error {
-	curOff, err := f.Seek(0, io.SeekCurrent)
-	if err != nil {
-		return err
-	}
-	size, err := f.Seek(sizeInBytes, io.SeekEnd)
-	if err != nil {
-		return err
-	}
-	if _, err = f.Seek(curOff, io.SeekStart); err != nil {
-		return err
-	}
-	if sizeInBytes > size {
-		return nil
-	}
-	return f.Truncate(sizeInBytes)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_darwin.go b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_darwin.go
deleted file mode 100644
index 5a6dccf..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_darwin.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build darwin
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-	"unsafe"
-)
-
-func preallocExtend(f *os.File, sizeInBytes int64) error {
-	if err := preallocFixed(f, sizeInBytes); err != nil {
-		return err
-	}
-	return preallocExtendTrunc(f, sizeInBytes)
-}
-
-func preallocFixed(f *os.File, sizeInBytes int64) error {
-	// allocate all requested space or no space at all
-	// TODO: allocate contiguous space on disk with F_ALLOCATECONTIG flag
-	fstore := &syscall.Fstore_t{
-		Flags:   syscall.F_ALLOCATEALL,
-		Posmode: syscall.F_PEOFPOSMODE,
-		Length:  sizeInBytes}
-	p := unsafe.Pointer(fstore)
-	_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_PREALLOCATE), uintptr(p))
-	if errno == 0 || errno == syscall.ENOTSUP {
-		return nil
-	}
-
-	// wrong argument to fallocate syscall
-	if errno == syscall.EINVAL {
-		// filesystem "st_blocks" are allocated in the units of
-		// "Allocation Block Size" (run "diskutil info /" command)
-		var stat syscall.Stat_t
-		syscall.Fstat(int(f.Fd()), &stat)
-
-		// syscall.Statfs_t.Bsize is "optimal transfer block size"
-		// and contains matching 4096 value when latest OS X kernel
-		// supports 4,096 KB filesystem block size
-		var statfs syscall.Statfs_t
-		syscall.Fstatfs(int(f.Fd()), &statfs)
-		blockSize := int64(statfs.Bsize)
-
-		if stat.Blocks*blockSize >= sizeInBytes {
-			// enough blocks are already allocated
-			return nil
-		}
-	}
-	return errno
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unix.go b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unix.go
deleted file mode 100644
index 50bd84f..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unix.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build linux
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-func preallocExtend(f *os.File, sizeInBytes int64) error {
-	// use mode = 0 to change size
-	err := syscall.Fallocate(int(f.Fd()), 0, 0, sizeInBytes)
-	if err != nil {
-		errno, ok := err.(syscall.Errno)
-		// not supported; fallback
-		// fallocate EINTRs frequently in some environments; fallback
-		if ok && (errno == syscall.ENOTSUP || errno == syscall.EINTR) {
-			return preallocExtendTrunc(f, sizeInBytes)
-		}
-	}
-	return err
-}
-
-func preallocFixed(f *os.File, sizeInBytes int64) error {
-	// use mode = 1 to keep size; see FALLOC_FL_KEEP_SIZE
-	err := syscall.Fallocate(int(f.Fd()), 1, 0, sizeInBytes)
-	if err != nil {
-		errno, ok := err.(syscall.Errno)
-		// treat not supported as nil error
-		if ok && errno == syscall.ENOTSUP {
-			return nil
-		}
-	}
-	return err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unsupported.go b/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unsupported.go
deleted file mode 100644
index 162fbc5..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/preallocate_unsupported.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !linux,!darwin
-
-package fileutil
-
-import "os"
-
-func preallocExtend(f *os.File, sizeInBytes int64) error {
-	return preallocExtendTrunc(f, sizeInBytes)
-}
-
-func preallocFixed(f *os.File, sizeInBytes int64) error { return nil }
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go b/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go
deleted file mode 100644
index 92fceab..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/purge.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package fileutil
-
-import (
-	"os"
-	"path/filepath"
-	"sort"
-	"strings"
-	"time"
-)
-
-func PurgeFile(dirname string, suffix string, max uint, interval time.Duration, stop <-chan struct{}) <-chan error {
-	return purgeFile(dirname, suffix, max, interval, stop, nil)
-}
-
-// purgeFile is the internal implementation for PurgeFile which can post purged files to purgec if non-nil.
-func purgeFile(dirname string, suffix string, max uint, interval time.Duration, stop <-chan struct{}, purgec chan<- string) <-chan error {
-	errC := make(chan error, 1)
-	go func() {
-		for {
-			fnames, err := ReadDir(dirname)
-			if err != nil {
-				errC <- err
-				return
-			}
-			newfnames := make([]string, 0)
-			for _, fname := range fnames {
-				if strings.HasSuffix(fname, suffix) {
-					newfnames = append(newfnames, fname)
-				}
-			}
-			sort.Strings(newfnames)
-			fnames = newfnames
-			for len(newfnames) > int(max) {
-				f := filepath.Join(dirname, newfnames[0])
-				l, err := TryLockFile(f, os.O_WRONLY, PrivateFileMode)
-				if err != nil {
-					break
-				}
-				if err = os.Remove(f); err != nil {
-					errC <- err
-					return
-				}
-				if err = l.Close(); err != nil {
-					plog.Errorf("error unlocking %s when purging file (%v)", l.Name(), err)
-					errC <- err
-					return
-				}
-				plog.Infof("purged file %s successfully", f)
-				newfnames = newfnames[1:]
-			}
-			if purgec != nil {
-				for i := 0; i < len(fnames)-len(newfnames); i++ {
-					purgec <- fnames[i]
-				}
-			}
-			select {
-			case <-time.After(interval):
-			case <-stop:
-				return
-			}
-		}
-	}()
-	return errC
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/sync.go b/vendor/github.com/coreos/etcd/pkg/fileutil/sync.go
deleted file mode 100644
index 54dd41f..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/sync.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !linux,!darwin
-
-package fileutil
-
-import "os"
-
-// Fsync is a wrapper around file.Sync(). Special handling is needed on darwin platform.
-func Fsync(f *os.File) error {
-	return f.Sync()
-}
-
-// Fdatasync is a wrapper around file.Sync(). Special handling is needed on linux platform.
-func Fdatasync(f *os.File) error {
-	return f.Sync()
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/sync_darwin.go b/vendor/github.com/coreos/etcd/pkg/fileutil/sync_darwin.go
deleted file mode 100644
index c2f39bf..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/sync_darwin.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build darwin
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-// Fsync on HFS/OSX flushes the data on to the physical drive but the drive
-// may not write it to the persistent media for quite sometime and it may be
-// written in out-of-order sequence. Using F_FULLFSYNC ensures that the
-// physical drive's buffer will also get flushed to the media.
-func Fsync(f *os.File) error {
-	_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_FULLFSYNC), uintptr(0))
-	if errno == 0 {
-		return nil
-	}
-	return errno
-}
-
-// Fdatasync on darwin platform invokes fcntl(F_FULLFSYNC) for actual persistence
-// on physical drive media.
-func Fdatasync(f *os.File) error {
-	return Fsync(f)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/fileutil/sync_linux.go b/vendor/github.com/coreos/etcd/pkg/fileutil/sync_linux.go
deleted file mode 100644
index 1bbced9..0000000
--- a/vendor/github.com/coreos/etcd/pkg/fileutil/sync_linux.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build linux
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-// Fsync is a wrapper around file.Sync(). Special handling is needed on darwin platform.
-func Fsync(f *os.File) error {
-	return f.Sync()
-}
-
-// Fdatasync is similar to fsync(), but does not flush modified metadata
-// unless that metadata is needed in order to allow a subsequent data retrieval
-// to be correctly handled.
-func Fdatasync(f *os.File) error {
-	return syscall.Fdatasync(int(f.Fd()))
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/flags/flag.go b/vendor/github.com/coreos/etcd/pkg/flags/flag.go
deleted file mode 100644
index 69c4641..0000000
--- a/vendor/github.com/coreos/etcd/pkg/flags/flag.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package flags implements command-line flag parsing.
-package flags
-
-import (
-	"flag"
-	"fmt"
-	"net/url"
-	"os"
-	"strings"
-
-	"github.com/coreos/pkg/capnslog"
-	"github.com/spf13/pflag"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "pkg/flags")
-)
-
-// DeprecatedFlag encapsulates a flag that may have been previously valid but
-// is now deprecated. If a DeprecatedFlag is set, an error occurs.
-type DeprecatedFlag struct {
-	Name string
-}
-
-func (f *DeprecatedFlag) Set(_ string) error {
-	return fmt.Errorf(`flag "-%s" is no longer supported.`, f.Name)
-}
-
-func (f *DeprecatedFlag) String() string {
-	return ""
-}
-
-// IgnoredFlag encapsulates a flag that may have been previously valid but is
-// now ignored. If an IgnoredFlag is set, a warning is printed and
-// operation continues.
-type IgnoredFlag struct {
-	Name string
-}
-
-// IsBoolFlag is defined to allow the flag to be defined without an argument
-func (f *IgnoredFlag) IsBoolFlag() bool {
-	return true
-}
-
-func (f *IgnoredFlag) Set(s string) error {
-	plog.Warningf(`flag "-%s" is no longer supported - ignoring.`, f.Name)
-	return nil
-}
-
-func (f *IgnoredFlag) String() string {
-	return ""
-}
-
-// SetFlagsFromEnv parses all registered flags in the given flagset,
-// and if they are not already set it attempts to set their values from
-// environment variables. Environment variables take the name of the flag but
-// are UPPERCASE, have the given prefix  and any dashes are replaced by
-// underscores - for example: some-flag => ETCD_SOME_FLAG
-func SetFlagsFromEnv(prefix string, fs *flag.FlagSet) error {
-	var err error
-	alreadySet := make(map[string]bool)
-	fs.Visit(func(f *flag.Flag) {
-		alreadySet[FlagToEnv(prefix, f.Name)] = true
-	})
-	usedEnvKey := make(map[string]bool)
-	fs.VisitAll(func(f *flag.Flag) {
-		if serr := setFlagFromEnv(fs, prefix, f.Name, usedEnvKey, alreadySet, true); serr != nil {
-			err = serr
-		}
-	})
-	verifyEnv(prefix, usedEnvKey, alreadySet)
-	return err
-}
-
-// SetPflagsFromEnv is similar to SetFlagsFromEnv. However, the accepted flagset type is pflag.FlagSet
-// and it does not do any logging.
-func SetPflagsFromEnv(prefix string, fs *pflag.FlagSet) error {
-	var err error
-	alreadySet := make(map[string]bool)
-	usedEnvKey := make(map[string]bool)
-	fs.VisitAll(func(f *pflag.Flag) {
-		if f.Changed {
-			alreadySet[FlagToEnv(prefix, f.Name)] = true
-		}
-		if serr := setFlagFromEnv(fs, prefix, f.Name, usedEnvKey, alreadySet, false); serr != nil {
-			err = serr
-		}
-	})
-	verifyEnv(prefix, usedEnvKey, alreadySet)
-	return err
-}
-
-// FlagToEnv converts flag string to upper-case environment variable key string.
-func FlagToEnv(prefix, name string) string {
-	return prefix + "_" + strings.ToUpper(strings.Replace(name, "-", "_", -1))
-}
-
-func verifyEnv(prefix string, usedEnvKey, alreadySet map[string]bool) {
-	for _, env := range os.Environ() {
-		kv := strings.SplitN(env, "=", 2)
-		if len(kv) != 2 {
-			plog.Warningf("found invalid env %s", env)
-		}
-		if usedEnvKey[kv[0]] {
-			continue
-		}
-		if alreadySet[kv[0]] {
-			// TODO: exit with error in v3.4
-			plog.Warningf("recognized environment variable %s, but unused: shadowed by corresponding flag", kv[0])
-			continue
-		}
-		if strings.HasPrefix(env, prefix+"_") {
-			plog.Warningf("unrecognized environment variable %s", env)
-		}
-	}
-}
-
-type flagSetter interface {
-	Set(fk string, fv string) error
-}
-
-func setFlagFromEnv(fs flagSetter, prefix, fname string, usedEnvKey, alreadySet map[string]bool, log bool) error {
-	key := FlagToEnv(prefix, fname)
-	if !alreadySet[key] {
-		val := os.Getenv(key)
-		if val != "" {
-			usedEnvKey[key] = true
-			if serr := fs.Set(fname, val); serr != nil {
-				return fmt.Errorf("invalid value %q for %s: %v", val, key, serr)
-			}
-			if log {
-				plog.Infof("recognized and used environment variable %s=%s", key, val)
-			}
-		}
-	}
-	return nil
-}
-
-// URLsFromFlag returns a slices from url got from the flag.
-func URLsFromFlag(fs *flag.FlagSet, urlsFlagName string) []url.URL {
-	return []url.URL(*fs.Lookup(urlsFlagName).Value.(*URLsValue))
-}
-
-func IsSet(fs *flag.FlagSet, name string) bool {
-	set := false
-	fs.Visit(func(f *flag.Flag) {
-		if f.Name == name {
-			set = true
-		}
-	})
-	return set
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/flags/strings.go b/vendor/github.com/coreos/etcd/pkg/flags/strings.go
deleted file mode 100644
index 89bdf95..0000000
--- a/vendor/github.com/coreos/etcd/pkg/flags/strings.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package flags
-
-import (
-	"errors"
-	"flag"
-	"sort"
-	"strings"
-)
-
-// NewStringsFlag creates a new string flag for which any one of the given
-// strings is a valid value, and any other value is an error.
-//
-// valids[0] will be default value. Caller must be sure len(valids)!=0 or
-// it will panic.
-func NewStringsFlag(valids ...string) *StringsFlag {
-	return &StringsFlag{Values: valids, val: valids[0]}
-}
-
-// StringsFlag implements the flag.Value interface.
-type StringsFlag struct {
-	Values []string
-	val    string
-}
-
-// Set verifies the argument to be a valid member of the allowed values
-// before setting the underlying flag value.
-func (ss *StringsFlag) Set(s string) error {
-	for _, v := range ss.Values {
-		if s == v {
-			ss.val = s
-			return nil
-		}
-	}
-	return errors.New("invalid value")
-}
-
-// String returns the set value (if any) of the StringsFlag
-func (ss *StringsFlag) String() string {
-	return ss.val
-}
-
-// StringsValueV2 wraps "sort.StringSlice".
-type StringsValueV2 sort.StringSlice
-
-// Set parses a command line set of strings, separated by comma.
-// Implements "flag.Value" interface.
-func (ss *StringsValueV2) Set(s string) error {
-	*ss = strings.Split(s, ",")
-	return nil
-}
-
-// String implements "flag.Value" interface.
-func (ss *StringsValueV2) String() string { return strings.Join(*ss, ",") }
-
-// NewStringsValueV2 implements string slice as "flag.Value" interface.
-// Given value is to be separated by comma.
-func NewStringsValueV2(s string) (ss *StringsValueV2) {
-	if s == "" {
-		return &StringsValueV2{}
-	}
-	ss = new(StringsValueV2)
-	if err := ss.Set(s); err != nil {
-		plog.Panicf("new StringsValueV2 should never fail: %v", err)
-	}
-	return ss
-}
-
-// StringsFromFlagV2 returns a string slice from the flag.
-func StringsFromFlagV2(fs *flag.FlagSet, flagName string) []string {
-	return []string(*fs.Lookup(flagName).Value.(*StringsValueV2))
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/flags/urls.go b/vendor/github.com/coreos/etcd/pkg/flags/urls.go
deleted file mode 100644
index 6383d7e..0000000
--- a/vendor/github.com/coreos/etcd/pkg/flags/urls.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package flags
-
-import (
-	"strings"
-
-	"github.com/coreos/etcd/pkg/types"
-)
-
-type URLsValue types.URLs
-
-// Set parses a command line set of URLs formatted like:
-// http://127.0.0.1:2380,http://10.1.1.2:80
-func (us *URLsValue) Set(s string) error {
-	strs := strings.Split(s, ",")
-	nus, err := types.NewURLs(strs)
-	if err != nil {
-		return err
-	}
-
-	*us = URLsValue(nus)
-	return nil
-}
-
-func (us *URLsValue) String() string {
-	all := make([]string, len(*us))
-	for i, u := range *us {
-		all[i] = u.String()
-	}
-	return strings.Join(all, ",")
-}
-
-func NewURLsValue(init string) *URLsValue {
-	v := &URLsValue{}
-	if err := v.Set(init); err != nil {
-		plog.Panicf("new URLsValue should never fail: %v", err)
-	}
-	return v
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/httputil/httputil.go b/vendor/github.com/coreos/etcd/pkg/httputil/httputil.go
deleted file mode 100644
index 09f44e7..0000000
--- a/vendor/github.com/coreos/etcd/pkg/httputil/httputil.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// borrowed from golang/net/context/ctxhttp/cancelreq.go
-
-// Package httputil provides HTTP utility functions.
-package httputil
-
-import (
-	"io"
-	"io/ioutil"
-	"net/http"
-)
-
-// GracefulClose drains http.Response.Body until it hits EOF
-// and closes it. This prevents TCP/TLS connections from closing,
-// therefore available for reuse.
-func GracefulClose(resp *http.Response) {
-	io.Copy(ioutil.Discard, resp.Body)
-	resp.Body.Close()
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/idutil/id.go b/vendor/github.com/coreos/etcd/pkg/idutil/id.go
deleted file mode 100644
index 2da2106..0000000
--- a/vendor/github.com/coreos/etcd/pkg/idutil/id.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package idutil implements utility functions for generating unique,
-// randomized ids.
-package idutil
-
-import (
-	"math"
-	"sync"
-	"time"
-)
-
-const (
-	tsLen     = 5 * 8
-	cntLen    = 8
-	suffixLen = tsLen + cntLen
-)
-
-// Generator generates unique identifiers based on counters, timestamps, and
-// a node member ID.
-//
-// The initial id is in this format:
-// High order 2 bytes are from memberID, next 5 bytes are from timestamp,
-// and low order one byte is a counter.
-// | prefix   | suffix              |
-// | 2 bytes  | 5 bytes   | 1 byte  |
-// | memberID | timestamp | cnt     |
-//
-// The timestamp 5 bytes is different when the machine is restart
-// after 1 ms and before 35 years.
-//
-// It increases suffix to generate the next id.
-// The count field may overflow to timestamp field, which is intentional.
-// It helps to extend the event window to 2^56. This doesn't break that
-// id generated after restart is unique because etcd throughput is <<
-// 256req/ms(250k reqs/second).
-type Generator struct {
-	mu sync.Mutex
-	// high order 2 bytes
-	prefix uint64
-	// low order 6 bytes
-	suffix uint64
-}
-
-func NewGenerator(memberID uint16, now time.Time) *Generator {
-	prefix := uint64(memberID) << suffixLen
-	unixMilli := uint64(now.UnixNano()) / uint64(time.Millisecond/time.Nanosecond)
-	suffix := lowbit(unixMilli, tsLen) << cntLen
-	return &Generator{
-		prefix: prefix,
-		suffix: suffix,
-	}
-}
-
-// Next generates a id that is unique.
-func (g *Generator) Next() uint64 {
-	g.mu.Lock()
-	defer g.mu.Unlock()
-	g.suffix++
-	id := g.prefix | lowbit(g.suffix, suffixLen)
-	return id
-}
-
-func lowbit(x uint64, n uint) uint64 {
-	return x & (math.MaxUint64 >> (64 - n))
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/ioutil/pagewriter.go b/vendor/github.com/coreos/etcd/pkg/ioutil/pagewriter.go
deleted file mode 100644
index 72de159..0000000
--- a/vendor/github.com/coreos/etcd/pkg/ioutil/pagewriter.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package ioutil
-
-import (
-	"io"
-)
-
-var defaultBufferBytes = 128 * 1024
-
-// PageWriter implements the io.Writer interface so that writes will
-// either be in page chunks or from flushing.
-type PageWriter struct {
-	w io.Writer
-	// pageOffset tracks the page offset of the base of the buffer
-	pageOffset int
-	// pageBytes is the number of bytes per page
-	pageBytes int
-	// bufferedBytes counts the number of bytes pending for write in the buffer
-	bufferedBytes int
-	// buf holds the write buffer
-	buf []byte
-	// bufWatermarkBytes is the number of bytes the buffer can hold before it needs
-	// to be flushed. It is less than len(buf) so there is space for slack writes
-	// to bring the writer to page alignment.
-	bufWatermarkBytes int
-}
-
-// NewPageWriter creates a new PageWriter. pageBytes is the number of bytes
-// to write per page. pageOffset is the starting offset of io.Writer.
-func NewPageWriter(w io.Writer, pageBytes, pageOffset int) *PageWriter {
-	return &PageWriter{
-		w:                 w,
-		pageOffset:        pageOffset,
-		pageBytes:         pageBytes,
-		buf:               make([]byte, defaultBufferBytes+pageBytes),
-		bufWatermarkBytes: defaultBufferBytes,
-	}
-}
-
-func (pw *PageWriter) Write(p []byte) (n int, err error) {
-	if len(p)+pw.bufferedBytes <= pw.bufWatermarkBytes {
-		// no overflow
-		copy(pw.buf[pw.bufferedBytes:], p)
-		pw.bufferedBytes += len(p)
-		return len(p), nil
-	}
-	// complete the slack page in the buffer if unaligned
-	slack := pw.pageBytes - ((pw.pageOffset + pw.bufferedBytes) % pw.pageBytes)
-	if slack != pw.pageBytes {
-		partial := slack > len(p)
-		if partial {
-			// not enough data to complete the slack page
-			slack = len(p)
-		}
-		// special case: writing to slack page in buffer
-		copy(pw.buf[pw.bufferedBytes:], p[:slack])
-		pw.bufferedBytes += slack
-		n = slack
-		p = p[slack:]
-		if partial {
-			// avoid forcing an unaligned flush
-			return n, nil
-		}
-	}
-	// buffer contents are now page-aligned; clear out
-	if err = pw.Flush(); err != nil {
-		return n, err
-	}
-	// directly write all complete pages without copying
-	if len(p) > pw.pageBytes {
-		pages := len(p) / pw.pageBytes
-		c, werr := pw.w.Write(p[:pages*pw.pageBytes])
-		n += c
-		if werr != nil {
-			return n, werr
-		}
-		p = p[pages*pw.pageBytes:]
-	}
-	// write remaining tail to buffer
-	c, werr := pw.Write(p)
-	n += c
-	return n, werr
-}
-
-func (pw *PageWriter) Flush() error {
-	if pw.bufferedBytes == 0 {
-		return nil
-	}
-	_, err := pw.w.Write(pw.buf[:pw.bufferedBytes])
-	pw.pageOffset = (pw.pageOffset + pw.bufferedBytes) % pw.pageBytes
-	pw.bufferedBytes = 0
-	return err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/ioutil/readcloser.go b/vendor/github.com/coreos/etcd/pkg/ioutil/readcloser.go
deleted file mode 100644
index d3efcfe..0000000
--- a/vendor/github.com/coreos/etcd/pkg/ioutil/readcloser.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package ioutil
-
-import (
-	"fmt"
-	"io"
-)
-
-// ReaderAndCloser implements io.ReadCloser interface by combining
-// reader and closer together.
-type ReaderAndCloser struct {
-	io.Reader
-	io.Closer
-}
-
-var (
-	ErrShortRead = fmt.Errorf("ioutil: short read")
-	ErrExpectEOF = fmt.Errorf("ioutil: expect EOF")
-)
-
-// NewExactReadCloser returns a ReadCloser that returns errors if the underlying
-// reader does not read back exactly the requested number of bytes.
-func NewExactReadCloser(rc io.ReadCloser, totalBytes int64) io.ReadCloser {
-	return &exactReadCloser{rc: rc, totalBytes: totalBytes}
-}
-
-type exactReadCloser struct {
-	rc         io.ReadCloser
-	br         int64
-	totalBytes int64
-}
-
-func (e *exactReadCloser) Read(p []byte) (int, error) {
-	n, err := e.rc.Read(p)
-	e.br += int64(n)
-	if e.br > e.totalBytes {
-		return 0, ErrExpectEOF
-	}
-	if e.br < e.totalBytes && n == 0 {
-		return 0, ErrShortRead
-	}
-	return n, err
-}
-
-func (e *exactReadCloser) Close() error {
-	if err := e.rc.Close(); err != nil {
-		return err
-	}
-	if e.br < e.totalBytes {
-		return ErrShortRead
-	}
-	return nil
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/ioutil/reader.go b/vendor/github.com/coreos/etcd/pkg/ioutil/reader.go
deleted file mode 100644
index 0703ed4..0000000
--- a/vendor/github.com/coreos/etcd/pkg/ioutil/reader.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package ioutil implements I/O utility functions.
-package ioutil
-
-import "io"
-
-// NewLimitedBufferReader returns a reader that reads from the given reader
-// but limits the amount of data returned to at most n bytes.
-func NewLimitedBufferReader(r io.Reader, n int) io.Reader {
-	return &limitedBufferReader{
-		r: r,
-		n: n,
-	}
-}
-
-type limitedBufferReader struct {
-	r io.Reader
-	n int
-}
-
-func (r *limitedBufferReader) Read(p []byte) (n int, err error) {
-	np := p
-	if len(np) > r.n {
-		np = np[:r.n]
-	}
-	return r.r.Read(np)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/ioutil/util.go b/vendor/github.com/coreos/etcd/pkg/ioutil/util.go
deleted file mode 100644
index 192ad88..0000000
--- a/vendor/github.com/coreos/etcd/pkg/ioutil/util.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package ioutil
-
-import (
-	"io"
-	"os"
-
-	"github.com/coreos/etcd/pkg/fileutil"
-)
-
-// WriteAndSyncFile behaves just like ioutil.WriteFile in the standard library,
-// but calls Sync before closing the file. WriteAndSyncFile guarantees the data
-// is synced if there is no error returned.
-func WriteAndSyncFile(filename string, data []byte, perm os.FileMode) error {
-	f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
-	if err != nil {
-		return err
-	}
-	n, err := f.Write(data)
-	if err == nil && n < len(data) {
-		err = io.ErrShortWrite
-	}
-	if err == nil {
-		err = fileutil.Fsync(f)
-	}
-	if err1 := f.Close(); err == nil {
-		err = err1
-	}
-	return err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/logutil/merge_logger.go b/vendor/github.com/coreos/etcd/pkg/logutil/merge_logger.go
deleted file mode 100644
index cc750f4..0000000
--- a/vendor/github.com/coreos/etcd/pkg/logutil/merge_logger.go
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package logutil includes utilities to facilitate logging.
-package logutil
-
-import (
-	"fmt"
-	"sync"
-	"time"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	defaultMergePeriod     = time.Second
-	defaultTimeOutputScale = 10 * time.Millisecond
-
-	outputInterval = time.Second
-)
-
-// line represents a log line that can be printed out
-// through capnslog.PackageLogger.
-type line struct {
-	level capnslog.LogLevel
-	str   string
-}
-
-func (l line) append(s string) line {
-	return line{
-		level: l.level,
-		str:   l.str + " " + s,
-	}
-}
-
-// status represents the merge status of a line.
-type status struct {
-	period time.Duration
-
-	start time.Time // start time of latest merge period
-	count int       // number of merged lines from starting
-}
-
-func (s *status) isInMergePeriod(now time.Time) bool {
-	return s.period == 0 || s.start.Add(s.period).After(now)
-}
-
-func (s *status) isEmpty() bool { return s.count == 0 }
-
-func (s *status) summary(now time.Time) string {
-	ts := s.start.Round(defaultTimeOutputScale)
-	took := now.Round(defaultTimeOutputScale).Sub(ts)
-	return fmt.Sprintf("[merged %d repeated lines in %s]", s.count, took)
-}
-
-func (s *status) reset(now time.Time) {
-	s.start = now
-	s.count = 0
-}
-
-// MergeLogger supports merge logging, which merges repeated log lines
-// and prints summary log lines instead.
-//
-// For merge logging, MergeLogger prints out the line when the line appears
-// at the first time. MergeLogger holds the same log line printed within
-// defaultMergePeriod, and prints out summary log line at the end of defaultMergePeriod.
-// It stops merging when the line doesn't appear within the
-// defaultMergePeriod.
-type MergeLogger struct {
-	*capnslog.PackageLogger
-
-	mu      sync.Mutex // protect statusm
-	statusm map[line]*status
-}
-
-func NewMergeLogger(logger *capnslog.PackageLogger) *MergeLogger {
-	l := &MergeLogger{
-		PackageLogger: logger,
-		statusm:       make(map[line]*status),
-	}
-	go l.outputLoop()
-	return l
-}
-
-func (l *MergeLogger) MergeInfo(entries ...interface{}) {
-	l.merge(line{
-		level: capnslog.INFO,
-		str:   fmt.Sprint(entries...),
-	})
-}
-
-func (l *MergeLogger) MergeInfof(format string, args ...interface{}) {
-	l.merge(line{
-		level: capnslog.INFO,
-		str:   fmt.Sprintf(format, args...),
-	})
-}
-
-func (l *MergeLogger) MergeNotice(entries ...interface{}) {
-	l.merge(line{
-		level: capnslog.NOTICE,
-		str:   fmt.Sprint(entries...),
-	})
-}
-
-func (l *MergeLogger) MergeNoticef(format string, args ...interface{}) {
-	l.merge(line{
-		level: capnslog.NOTICE,
-		str:   fmt.Sprintf(format, args...),
-	})
-}
-
-func (l *MergeLogger) MergeWarning(entries ...interface{}) {
-	l.merge(line{
-		level: capnslog.WARNING,
-		str:   fmt.Sprint(entries...),
-	})
-}
-
-func (l *MergeLogger) MergeWarningf(format string, args ...interface{}) {
-	l.merge(line{
-		level: capnslog.WARNING,
-		str:   fmt.Sprintf(format, args...),
-	})
-}
-
-func (l *MergeLogger) MergeError(entries ...interface{}) {
-	l.merge(line{
-		level: capnslog.ERROR,
-		str:   fmt.Sprint(entries...),
-	})
-}
-
-func (l *MergeLogger) MergeErrorf(format string, args ...interface{}) {
-	l.merge(line{
-		level: capnslog.ERROR,
-		str:   fmt.Sprintf(format, args...),
-	})
-}
-
-func (l *MergeLogger) merge(ln line) {
-	l.mu.Lock()
-
-	// increase count if the logger is merging the line
-	if status, ok := l.statusm[ln]; ok {
-		status.count++
-		l.mu.Unlock()
-		return
-	}
-
-	// initialize status of the line
-	l.statusm[ln] = &status{
-		period: defaultMergePeriod,
-		start:  time.Now(),
-	}
-	// release the lock before IO operation
-	l.mu.Unlock()
-	// print out the line at its first time
-	l.PackageLogger.Logf(ln.level, ln.str)
-}
-
-func (l *MergeLogger) outputLoop() {
-	for now := range time.Tick(outputInterval) {
-		var outputs []line
-
-		l.mu.Lock()
-		for ln, status := range l.statusm {
-			if status.isInMergePeriod(now) {
-				continue
-			}
-			if status.isEmpty() {
-				delete(l.statusm, ln)
-				continue
-			}
-			outputs = append(outputs, ln.append(status.summary(now)))
-			status.reset(now)
-		}
-		l.mu.Unlock()
-
-		for _, o := range outputs {
-			l.PackageLogger.Logf(o.level, o.str)
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/isolate_linux.go b/vendor/github.com/coreos/etcd/pkg/netutil/isolate_linux.go
deleted file mode 100644
index 418580a..0000000
--- a/vendor/github.com/coreos/etcd/pkg/netutil/isolate_linux.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package netutil
-
-import (
-	"fmt"
-	"os/exec"
-)
-
-// DropPort drops all tcp packets that are received from the given port and sent to the given port.
-func DropPort(port int) error {
-	cmdStr := fmt.Sprintf("sudo iptables -A OUTPUT -p tcp --destination-port %d -j DROP", port)
-	if _, err := exec.Command("/bin/sh", "-c", cmdStr).Output(); err != nil {
-		return err
-	}
-	cmdStr = fmt.Sprintf("sudo iptables -A INPUT -p tcp --destination-port %d -j DROP", port)
-	_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
-	return err
-}
-
-// RecoverPort stops dropping tcp packets at given port.
-func RecoverPort(port int) error {
-	cmdStr := fmt.Sprintf("sudo iptables -D OUTPUT -p tcp --destination-port %d -j DROP", port)
-	if _, err := exec.Command("/bin/sh", "-c", cmdStr).Output(); err != nil {
-		return err
-	}
-	cmdStr = fmt.Sprintf("sudo iptables -D INPUT -p tcp --destination-port %d -j DROP", port)
-	_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
-	return err
-}
-
-// SetLatency adds latency in millisecond scale with random variations.
-func SetLatency(ms, rv int) error {
-	ifces, err := GetDefaultInterfaces()
-	if err != nil {
-		return err
-	}
-
-	if rv > ms {
-		rv = 1
-	}
-	for ifce := range ifces {
-		cmdStr := fmt.Sprintf("sudo tc qdisc add dev %s root netem delay %dms %dms distribution normal", ifce, ms, rv)
-		_, err = exec.Command("/bin/sh", "-c", cmdStr).Output()
-		if err != nil {
-			// the rule has already been added. Overwrite it.
-			cmdStr = fmt.Sprintf("sudo tc qdisc change dev %s root netem delay %dms %dms distribution normal", ifce, ms, rv)
-			_, err = exec.Command("/bin/sh", "-c", cmdStr).Output()
-			if err != nil {
-				return err
-			}
-		}
-	}
-	return nil
-}
-
-// RemoveLatency resets latency configurations.
-func RemoveLatency() error {
-	ifces, err := GetDefaultInterfaces()
-	if err != nil {
-		return err
-	}
-	for ifce := range ifces {
-		_, err = exec.Command("/bin/sh", "-c", fmt.Sprintf("sudo tc qdisc del dev %s root netem", ifce)).Output()
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/isolate_stub.go b/vendor/github.com/coreos/etcd/pkg/netutil/isolate_stub.go
deleted file mode 100644
index 7f4c3e6..0000000
--- a/vendor/github.com/coreos/etcd/pkg/netutil/isolate_stub.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !linux
-
-package netutil
-
-func DropPort(port int) error { return nil }
-
-func RecoverPort(port int) error { return nil }
-
-func SetLatency(ms, rv int) error { return nil }
-
-func RemoveLatency() error { return nil }
diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go b/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go
deleted file mode 100644
index e3db8c5..0000000
--- a/vendor/github.com/coreos/etcd/pkg/netutil/netutil.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package netutil implements network-related utility functions.
-package netutil
-
-import (
-	"context"
-	"fmt"
-	"net"
-	"net/url"
-	"reflect"
-	"sort"
-	"time"
-
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "pkg/netutil")
-
-	// indirection for testing
-	resolveTCPAddr = resolveTCPAddrDefault
-)
-
-const retryInterval = time.Second
-
-// taken from go's ResolveTCP code but uses configurable ctx
-func resolveTCPAddrDefault(ctx context.Context, addr string) (*net.TCPAddr, error) {
-	host, port, serr := net.SplitHostPort(addr)
-	if serr != nil {
-		return nil, serr
-	}
-	portnum, perr := net.DefaultResolver.LookupPort(ctx, "tcp", port)
-	if perr != nil {
-		return nil, perr
-	}
-
-	var ips []net.IPAddr
-	if ip := net.ParseIP(host); ip != nil {
-		ips = []net.IPAddr{{IP: ip}}
-	} else {
-		// Try as a DNS name.
-		ipss, err := net.DefaultResolver.LookupIPAddr(ctx, host)
-		if err != nil {
-			return nil, err
-		}
-		ips = ipss
-	}
-	// randomize?
-	ip := ips[0]
-	return &net.TCPAddr{IP: ip.IP, Port: portnum, Zone: ip.Zone}, nil
-}
-
-// resolveTCPAddrs is a convenience wrapper for net.ResolveTCPAddr.
-// resolveTCPAddrs return a new set of url.URLs, in which all DNS hostnames
-// are resolved.
-func resolveTCPAddrs(ctx context.Context, urls [][]url.URL) ([][]url.URL, error) {
-	newurls := make([][]url.URL, 0)
-	for _, us := range urls {
-		nus := make([]url.URL, len(us))
-		for i, u := range us {
-			nu, err := url.Parse(u.String())
-			if err != nil {
-				return nil, fmt.Errorf("failed to parse %q (%v)", u.String(), err)
-			}
-			nus[i] = *nu
-		}
-		for i, u := range nus {
-			h, err := resolveURL(ctx, u)
-			if err != nil {
-				return nil, fmt.Errorf("failed to resolve %q (%v)", u.String(), err)
-			}
-			if h != "" {
-				nus[i].Host = h
-			}
-		}
-		newurls = append(newurls, nus)
-	}
-	return newurls, nil
-}
-
-func resolveURL(ctx context.Context, u url.URL) (string, error) {
-	if u.Scheme == "unix" || u.Scheme == "unixs" {
-		// unix sockets don't resolve over TCP
-		return "", nil
-	}
-	host, _, err := net.SplitHostPort(u.Host)
-	if err != nil {
-		plog.Errorf("could not parse url %s during tcp resolving", u.Host)
-		return "", err
-	}
-	if host == "localhost" || net.ParseIP(host) != nil {
-		return "", nil
-	}
-	for ctx.Err() == nil {
-		tcpAddr, err := resolveTCPAddr(ctx, u.Host)
-		if err == nil {
-			plog.Infof("resolving %s to %s", u.Host, tcpAddr.String())
-			return tcpAddr.String(), nil
-		}
-		plog.Warningf("failed resolving host %s (%v); retrying in %v", u.Host, err, retryInterval)
-		select {
-		case <-ctx.Done():
-			plog.Errorf("could not resolve host %s", u.Host)
-			return "", err
-		case <-time.After(retryInterval):
-		}
-	}
-	return "", ctx.Err()
-}
-
-// urlsEqual checks equality of url.URLS between two arrays.
-// This check pass even if an URL is in hostname and opposite is in IP address.
-func urlsEqual(ctx context.Context, a []url.URL, b []url.URL) (bool, error) {
-	if len(a) != len(b) {
-		return false, fmt.Errorf("len(%q) != len(%q)", urlsToStrings(a), urlsToStrings(b))
-	}
-	urls, err := resolveTCPAddrs(ctx, [][]url.URL{a, b})
-	if err != nil {
-		return false, err
-	}
-	preva, prevb := a, b
-	a, b = urls[0], urls[1]
-	sort.Sort(types.URLs(a))
-	sort.Sort(types.URLs(b))
-	for i := range a {
-		if !reflect.DeepEqual(a[i], b[i]) {
-			return false, fmt.Errorf("%q(resolved from %q) != %q(resolved from %q)",
-				a[i].String(), preva[i].String(),
-				b[i].String(), prevb[i].String(),
-			)
-		}
-	}
-	return true, nil
-}
-
-// URLStringsEqual returns "true" if given URLs are valid
-// and resolved to same IP addresses. Otherwise, return "false"
-// and error, if any.
-func URLStringsEqual(ctx context.Context, a []string, b []string) (bool, error) {
-	if len(a) != len(b) {
-		return false, fmt.Errorf("len(%q) != len(%q)", a, b)
-	}
-	urlsA := make([]url.URL, 0)
-	for _, str := range a {
-		u, err := url.Parse(str)
-		if err != nil {
-			return false, fmt.Errorf("failed to parse %q", str)
-		}
-		urlsA = append(urlsA, *u)
-	}
-	urlsB := make([]url.URL, 0)
-	for _, str := range b {
-		u, err := url.Parse(str)
-		if err != nil {
-			return false, fmt.Errorf("failed to parse %q", str)
-		}
-		urlsB = append(urlsB, *u)
-	}
-	return urlsEqual(ctx, urlsA, urlsB)
-}
-
-func urlsToStrings(us []url.URL) []string {
-	rs := make([]string, len(us))
-	for i := range us {
-		rs[i] = us[i].String()
-	}
-	return rs
-}
-
-func IsNetworkTimeoutError(err error) bool {
-	nerr, ok := err.(net.Error)
-	return ok && nerr.Timeout()
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/routes.go b/vendor/github.com/coreos/etcd/pkg/netutil/routes.go
deleted file mode 100644
index 3eb6a19..0000000
--- a/vendor/github.com/coreos/etcd/pkg/netutil/routes.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !linux
-
-package netutil
-
-import (
-	"fmt"
-	"runtime"
-)
-
-// GetDefaultHost fetches the a resolvable name that corresponds
-// to the machine's default routable interface
-func GetDefaultHost() (string, error) {
-	return "", fmt.Errorf("default host not supported on %s_%s", runtime.GOOS, runtime.GOARCH)
-}
-
-// GetDefaultInterfaces fetches the device name of default routable interface.
-func GetDefaultInterfaces() (map[string]uint8, error) {
-	return nil, fmt.Errorf("default host not supported on %s_%s", runtime.GOOS, runtime.GOARCH)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/netutil/routes_linux.go b/vendor/github.com/coreos/etcd/pkg/netutil/routes_linux.go
deleted file mode 100644
index 797baeb..0000000
--- a/vendor/github.com/coreos/etcd/pkg/netutil/routes_linux.go
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build linux
-
-package netutil
-
-import (
-	"bytes"
-	"encoding/binary"
-	"fmt"
-	"net"
-	"sort"
-	"syscall"
-
-	"github.com/coreos/etcd/pkg/cpuutil"
-)
-
-var errNoDefaultRoute = fmt.Errorf("could not find default route")
-var errNoDefaultHost = fmt.Errorf("could not find default host")
-var errNoDefaultInterface = fmt.Errorf("could not find default interface")
-
-// GetDefaultHost obtains the first IP address of machine from the routing table and returns the IP address as string.
-// An IPv4 address is preferred to an IPv6 address for backward compatibility.
-func GetDefaultHost() (string, error) {
-	rmsgs, rerr := getDefaultRoutes()
-	if rerr != nil {
-		return "", rerr
-	}
-
-	// prioritize IPv4
-	if rmsg, ok := rmsgs[syscall.AF_INET]; ok {
-		if host, err := chooseHost(syscall.AF_INET, rmsg); host != "" || err != nil {
-			return host, err
-		}
-		delete(rmsgs, syscall.AF_INET)
-	}
-
-	// sort so choice is deterministic
-	var families []int
-	for family := range rmsgs {
-		families = append(families, int(family))
-	}
-	sort.Ints(families)
-
-	for _, f := range families {
-		family := uint8(f)
-		if host, err := chooseHost(family, rmsgs[family]); host != "" || err != nil {
-			return host, err
-		}
-	}
-
-	return "", errNoDefaultHost
-}
-
-func chooseHost(family uint8, rmsg *syscall.NetlinkMessage) (string, error) {
-	host, oif, err := parsePREFSRC(rmsg)
-	if host != "" || err != nil {
-		return host, err
-	}
-
-	// prefsrc not detected, fall back to getting address from iface
-	ifmsg, ierr := getIfaceAddr(oif, family)
-	if ierr != nil {
-		return "", ierr
-	}
-
-	attrs, aerr := syscall.ParseNetlinkRouteAttr(ifmsg)
-	if aerr != nil {
-		return "", aerr
-	}
-
-	for _, attr := range attrs {
-		// search for RTA_DST because ipv6 doesn't have RTA_SRC
-		if attr.Attr.Type == syscall.RTA_DST {
-			return net.IP(attr.Value).String(), nil
-		}
-	}
-
-	return "", nil
-}
-
-func getDefaultRoutes() (map[uint8]*syscall.NetlinkMessage, error) {
-	dat, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_UNSPEC)
-	if err != nil {
-		return nil, err
-	}
-
-	msgs, msgErr := syscall.ParseNetlinkMessage(dat)
-	if msgErr != nil {
-		return nil, msgErr
-	}
-
-	routes := make(map[uint8]*syscall.NetlinkMessage)
-	rtmsg := syscall.RtMsg{}
-	for _, m := range msgs {
-		if m.Header.Type != syscall.RTM_NEWROUTE {
-			continue
-		}
-		buf := bytes.NewBuffer(m.Data[:syscall.SizeofRtMsg])
-		if rerr := binary.Read(buf, cpuutil.ByteOrder(), &rtmsg); rerr != nil {
-			continue
-		}
-		if rtmsg.Dst_len == 0 && rtmsg.Table == syscall.RT_TABLE_MAIN {
-			// zero-length Dst_len implies default route
-			msg := m
-			routes[rtmsg.Family] = &msg
-		}
-	}
-
-	if len(routes) > 0 {
-		return routes, nil
-	}
-
-	return nil, errNoDefaultRoute
-}
-
-// Used to get an address of interface.
-func getIfaceAddr(idx uint32, family uint8) (*syscall.NetlinkMessage, error) {
-	dat, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, int(family))
-	if err != nil {
-		return nil, err
-	}
-
-	msgs, msgErr := syscall.ParseNetlinkMessage(dat)
-	if msgErr != nil {
-		return nil, msgErr
-	}
-
-	ifaddrmsg := syscall.IfAddrmsg{}
-	for _, m := range msgs {
-		if m.Header.Type != syscall.RTM_NEWADDR {
-			continue
-		}
-		buf := bytes.NewBuffer(m.Data[:syscall.SizeofIfAddrmsg])
-		if rerr := binary.Read(buf, cpuutil.ByteOrder(), &ifaddrmsg); rerr != nil {
-			continue
-		}
-		if ifaddrmsg.Index == idx {
-			return &m, nil
-		}
-	}
-
-	return nil, fmt.Errorf("could not find address for interface index %v", idx)
-
-}
-
-// Used to get a name of interface.
-func getIfaceLink(idx uint32) (*syscall.NetlinkMessage, error) {
-	dat, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
-	if err != nil {
-		return nil, err
-	}
-
-	msgs, msgErr := syscall.ParseNetlinkMessage(dat)
-	if msgErr != nil {
-		return nil, msgErr
-	}
-
-	ifinfomsg := syscall.IfInfomsg{}
-	for _, m := range msgs {
-		if m.Header.Type != syscall.RTM_NEWLINK {
-			continue
-		}
-		buf := bytes.NewBuffer(m.Data[:syscall.SizeofIfInfomsg])
-		if rerr := binary.Read(buf, cpuutil.ByteOrder(), &ifinfomsg); rerr != nil {
-			continue
-		}
-		if ifinfomsg.Index == int32(idx) {
-			return &m, nil
-		}
-	}
-
-	return nil, fmt.Errorf("could not find link for interface index %v", idx)
-}
-
-// GetDefaultInterfaces gets names of interfaces and returns a map[interface]families.
-func GetDefaultInterfaces() (map[string]uint8, error) {
-	interfaces := make(map[string]uint8)
-	rmsgs, rerr := getDefaultRoutes()
-	if rerr != nil {
-		return interfaces, rerr
-	}
-
-	for family, rmsg := range rmsgs {
-		_, oif, err := parsePREFSRC(rmsg)
-		if err != nil {
-			return interfaces, err
-		}
-
-		ifmsg, ierr := getIfaceLink(oif)
-		if ierr != nil {
-			return interfaces, ierr
-		}
-
-		attrs, aerr := syscall.ParseNetlinkRouteAttr(ifmsg)
-		if aerr != nil {
-			return interfaces, aerr
-		}
-
-		for _, attr := range attrs {
-			if attr.Attr.Type == syscall.IFLA_IFNAME {
-				// key is an interface name
-				// possible values: 2 - AF_INET, 10 - AF_INET6, 12 - dualstack
-				interfaces[string(attr.Value[:len(attr.Value)-1])] += family
-			}
-		}
-	}
-	if len(interfaces) > 0 {
-		return interfaces, nil
-	}
-	return interfaces, errNoDefaultInterface
-}
-
-// parsePREFSRC returns preferred source address and output interface index (RTA_OIF).
-func parsePREFSRC(m *syscall.NetlinkMessage) (host string, oif uint32, err error) {
-	var attrs []syscall.NetlinkRouteAttr
-	attrs, err = syscall.ParseNetlinkRouteAttr(m)
-	if err != nil {
-		return "", 0, err
-	}
-
-	for _, attr := range attrs {
-		if attr.Attr.Type == syscall.RTA_PREFSRC {
-			host = net.IP(attr.Value).String()
-		}
-		if attr.Attr.Type == syscall.RTA_OIF {
-			oif = cpuutil.ByteOrder().Uint32(attr.Value)
-		}
-		if host != "" && oif != uint32(0) {
-			break
-		}
-	}
-
-	if oif == 0 {
-		err = errNoDefaultRoute
-	}
-	return host, oif, err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/osutil/interrupt_unix.go b/vendor/github.com/coreos/etcd/pkg/osutil/interrupt_unix.go
deleted file mode 100644
index b9feaff..0000000
--- a/vendor/github.com/coreos/etcd/pkg/osutil/interrupt_unix.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !windows,!plan9
-
-package osutil
-
-import (
-	"os"
-	"os/signal"
-	"sync"
-	"syscall"
-)
-
-// InterruptHandler is a function that is called on receiving a
-// SIGTERM or SIGINT signal.
-type InterruptHandler func()
-
-var (
-	interruptRegisterMu, interruptExitMu sync.Mutex
-	// interruptHandlers holds all registered InterruptHandlers in order
-	// they will be executed.
-	interruptHandlers = []InterruptHandler{}
-)
-
-// RegisterInterruptHandler registers a new InterruptHandler. Handlers registered
-// after interrupt handing was initiated will not be executed.
-func RegisterInterruptHandler(h InterruptHandler) {
-	interruptRegisterMu.Lock()
-	defer interruptRegisterMu.Unlock()
-	interruptHandlers = append(interruptHandlers, h)
-}
-
-// HandleInterrupts calls the handler functions on receiving a SIGINT or SIGTERM.
-func HandleInterrupts() {
-	notifier := make(chan os.Signal, 1)
-	signal.Notify(notifier, syscall.SIGINT, syscall.SIGTERM)
-
-	go func() {
-		sig := <-notifier
-
-		interruptRegisterMu.Lock()
-		ihs := make([]InterruptHandler, len(interruptHandlers))
-		copy(ihs, interruptHandlers)
-		interruptRegisterMu.Unlock()
-
-		interruptExitMu.Lock()
-
-		plog.Noticef("received %v signal, shutting down...", sig)
-
-		for _, h := range ihs {
-			h()
-		}
-		signal.Stop(notifier)
-		pid := syscall.Getpid()
-		// exit directly if it is the "init" process, since the kernel will not help to kill pid 1.
-		if pid == 1 {
-			os.Exit(0)
-		}
-		setDflSignal(sig.(syscall.Signal))
-		syscall.Kill(pid, sig.(syscall.Signal))
-	}()
-}
-
-// Exit relays to os.Exit if no interrupt handlers are running, blocks otherwise.
-func Exit(code int) {
-	interruptExitMu.Lock()
-	os.Exit(code)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/osutil/interrupt_windows.go b/vendor/github.com/coreos/etcd/pkg/osutil/interrupt_windows.go
deleted file mode 100644
index 013ae88..0000000
--- a/vendor/github.com/coreos/etcd/pkg/osutil/interrupt_windows.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build windows
-
-package osutil
-
-import "os"
-
-type InterruptHandler func()
-
-// RegisterInterruptHandler is a no-op on windows
-func RegisterInterruptHandler(h InterruptHandler) {}
-
-// HandleInterrupts is a no-op on windows
-func HandleInterrupts() {}
-
-// Exit calls os.Exit
-func Exit(code int) {
-	os.Exit(code)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/osutil/osutil.go b/vendor/github.com/coreos/etcd/pkg/osutil/osutil.go
deleted file mode 100644
index ef38280..0000000
--- a/vendor/github.com/coreos/etcd/pkg/osutil/osutil.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package osutil implements operating system-related utility functions.
-package osutil
-
-import (
-	"os"
-	"strings"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "pkg/osutil")
-
-	// support to override setting SIG_DFL so tests don't terminate early
-	setDflSignal = dflSignal
-)
-
-func Unsetenv(key string) error {
-	envs := os.Environ()
-	os.Clearenv()
-	for _, e := range envs {
-		strs := strings.SplitN(e, "=", 2)
-		if strs[0] == key {
-			continue
-		}
-		if err := os.Setenv(strs[0], strs[1]); err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/osutil/signal.go b/vendor/github.com/coreos/etcd/pkg/osutil/signal.go
deleted file mode 100644
index 687397f..0000000
--- a/vendor/github.com/coreos/etcd/pkg/osutil/signal.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !linux cov
-
-package osutil
-
-import "syscall"
-
-func dflSignal(sig syscall.Signal) { /* nop */ }
diff --git a/vendor/github.com/coreos/etcd/pkg/osutil/signal_linux.go b/vendor/github.com/coreos/etcd/pkg/osutil/signal_linux.go
deleted file mode 100644
index b94d80c..0000000
--- a/vendor/github.com/coreos/etcd/pkg/osutil/signal_linux.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build linux,!cov
-
-package osutil
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-// dflSignal sets the given signal to SIG_DFL
-func dflSignal(sig syscall.Signal) {
-	// clearing out the sigact sets the signal to SIG_DFL
-	var sigactBuf [32]uint64
-	ptr := unsafe.Pointer(&sigactBuf)
-	syscall.Syscall6(uintptr(syscall.SYS_RT_SIGACTION), uintptr(sig), uintptr(ptr), 0, 8, 0, 0)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/pathutil/path.go b/vendor/github.com/coreos/etcd/pkg/pathutil/path.go
deleted file mode 100644
index f26254b..0000000
--- a/vendor/github.com/coreos/etcd/pkg/pathutil/path.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package pathutil implements utility functions for handling slash-separated
-// paths.
-package pathutil
-
-import "path"
-
-// CanonicalURLPath returns the canonical url path for p, which follows the rules:
-// 1. the path always starts with "/"
-// 2. replace multiple slashes with a single slash
-// 3. replace each '.' '..' path name element with equivalent one
-// 4. keep the trailing slash
-// The function is borrowed from stdlib http.cleanPath in server.go.
-func CanonicalURLPath(p string) string {
-	if p == "" {
-		return "/"
-	}
-	if p[0] != '/' {
-		p = "/" + p
-	}
-	np := path.Clean(p)
-	// path.Clean removes trailing slash except for root,
-	// put the trailing slash back if necessary.
-	if p[len(p)-1] == '/' && np != "/" {
-		np += "/"
-	}
-	return np
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go b/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go
deleted file mode 100644
index d70f98d..0000000
--- a/vendor/github.com/coreos/etcd/pkg/pbutil/pbutil.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package pbutil defines interfaces for handling Protocol Buffer objects.
-package pbutil
-
-import "github.com/coreos/pkg/capnslog"
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "pkg/pbutil")
-)
-
-type Marshaler interface {
-	Marshal() (data []byte, err error)
-}
-
-type Unmarshaler interface {
-	Unmarshal(data []byte) error
-}
-
-func MustMarshal(m Marshaler) []byte {
-	d, err := m.Marshal()
-	if err != nil {
-		plog.Panicf("marshal should never fail (%v)", err)
-	}
-	return d
-}
-
-func MustUnmarshal(um Unmarshaler, data []byte) {
-	if err := um.Unmarshal(data); err != nil {
-		plog.Panicf("unmarshal should never fail (%v)", err)
-	}
-}
-
-func MaybeUnmarshal(um Unmarshaler, data []byte) bool {
-	if err := um.Unmarshal(data); err != nil {
-		return false
-	}
-	return true
-}
-
-func GetBool(v *bool) (vv bool, set bool) {
-	if v == nil {
-		return false, false
-	}
-	return *v, true
-}
-
-func Boolp(b bool) *bool { return &b }
diff --git a/vendor/github.com/coreos/etcd/pkg/runtime/fds_linux.go b/vendor/github.com/coreos/etcd/pkg/runtime/fds_linux.go
deleted file mode 100644
index 8e9359d..0000000
--- a/vendor/github.com/coreos/etcd/pkg/runtime/fds_linux.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package runtime implements utility functions for runtime systems.
-package runtime
-
-import (
-	"io/ioutil"
-	"syscall"
-)
-
-func FDLimit() (uint64, error) {
-	var rlimit syscall.Rlimit
-	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit); err != nil {
-		return 0, err
-	}
-	return rlimit.Cur, nil
-}
-
-func FDUsage() (uint64, error) {
-	fds, err := ioutil.ReadDir("/proc/self/fd")
-	if err != nil {
-		return 0, err
-	}
-	return uint64(len(fds)), nil
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/runtime/fds_other.go b/vendor/github.com/coreos/etcd/pkg/runtime/fds_other.go
deleted file mode 100644
index 0cbdb88..0000000
--- a/vendor/github.com/coreos/etcd/pkg/runtime/fds_other.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !linux
-
-package runtime
-
-import (
-	"fmt"
-	"runtime"
-)
-
-func FDLimit() (uint64, error) {
-	return 0, fmt.Errorf("cannot get FDLimit on %s", runtime.GOOS)
-}
-
-func FDUsage() (uint64, error) {
-	return 0, fmt.Errorf("cannot get FDUsage on %s", runtime.GOOS)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/schedule/doc.go b/vendor/github.com/coreos/etcd/pkg/schedule/doc.go
deleted file mode 100644
index cca2c75..0000000
--- a/vendor/github.com/coreos/etcd/pkg/schedule/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package schedule provides mechanisms and policies for scheduling units of work.
-package schedule
diff --git a/vendor/github.com/coreos/etcd/pkg/schedule/schedule.go b/vendor/github.com/coreos/etcd/pkg/schedule/schedule.go
deleted file mode 100644
index 234d019..0000000
--- a/vendor/github.com/coreos/etcd/pkg/schedule/schedule.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package schedule
-
-import (
-	"context"
-	"sync"
-)
-
-type Job func(context.Context)
-
-// Scheduler can schedule jobs.
-type Scheduler interface {
-	// Schedule asks the scheduler to schedule a job defined by the given func.
-	// Schedule to a stopped scheduler might panic.
-	Schedule(j Job)
-
-	// Pending returns number of pending jobs
-	Pending() int
-
-	// Scheduled returns the number of scheduled jobs (excluding pending jobs)
-	Scheduled() int
-
-	// Finished returns the number of finished jobs
-	Finished() int
-
-	// WaitFinish waits until at least n job are finished and all pending jobs are finished.
-	WaitFinish(n int)
-
-	// Stop stops the scheduler.
-	Stop()
-}
-
-type fifo struct {
-	mu sync.Mutex
-
-	resume    chan struct{}
-	scheduled int
-	finished  int
-	pendings  []Job
-
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	finishCond *sync.Cond
-	donec      chan struct{}
-}
-
-// NewFIFOScheduler returns a Scheduler that schedules jobs in FIFO
-// order sequentially
-func NewFIFOScheduler() Scheduler {
-	f := &fifo{
-		resume: make(chan struct{}, 1),
-		donec:  make(chan struct{}, 1),
-	}
-	f.finishCond = sync.NewCond(&f.mu)
-	f.ctx, f.cancel = context.WithCancel(context.Background())
-	go f.run()
-	return f
-}
-
-// Schedule schedules a job that will be ran in FIFO order sequentially.
-func (f *fifo) Schedule(j Job) {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-
-	if f.cancel == nil {
-		panic("schedule: schedule to stopped scheduler")
-	}
-
-	if len(f.pendings) == 0 {
-		select {
-		case f.resume <- struct{}{}:
-		default:
-		}
-	}
-	f.pendings = append(f.pendings, j)
-}
-
-func (f *fifo) Pending() int {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	return len(f.pendings)
-}
-
-func (f *fifo) Scheduled() int {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	return f.scheduled
-}
-
-func (f *fifo) Finished() int {
-	f.finishCond.L.Lock()
-	defer f.finishCond.L.Unlock()
-	return f.finished
-}
-
-func (f *fifo) WaitFinish(n int) {
-	f.finishCond.L.Lock()
-	for f.finished < n || len(f.pendings) != 0 {
-		f.finishCond.Wait()
-	}
-	f.finishCond.L.Unlock()
-}
-
-// Stop stops the scheduler and cancels all pending jobs.
-func (f *fifo) Stop() {
-	f.mu.Lock()
-	f.cancel()
-	f.cancel = nil
-	f.mu.Unlock()
-	<-f.donec
-}
-
-func (f *fifo) run() {
-	// TODO: recover from job panic?
-	defer func() {
-		close(f.donec)
-		close(f.resume)
-	}()
-
-	for {
-		var todo Job
-		f.mu.Lock()
-		if len(f.pendings) != 0 {
-			f.scheduled++
-			todo = f.pendings[0]
-		}
-		f.mu.Unlock()
-		if todo == nil {
-			select {
-			case <-f.resume:
-			case <-f.ctx.Done():
-				f.mu.Lock()
-				pendings := f.pendings
-				f.pendings = nil
-				f.mu.Unlock()
-				// clean up pending jobs
-				for _, todo := range pendings {
-					todo(f.ctx)
-				}
-				return
-			}
-		} else {
-			todo(f.ctx)
-			f.finishCond.L.Lock()
-			f.finished++
-			f.pendings = f.pendings[1:]
-			f.finishCond.Broadcast()
-			f.finishCond.L.Unlock()
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/srv/srv.go b/vendor/github.com/coreos/etcd/pkg/srv/srv.go
deleted file mode 100644
index 600061c..0000000
--- a/vendor/github.com/coreos/etcd/pkg/srv/srv.go
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package srv looks up DNS SRV records.
-package srv
-
-import (
-	"fmt"
-	"net"
-	"net/url"
-	"strings"
-
-	"github.com/coreos/etcd/pkg/types"
-)
-
-var (
-	// indirection for testing
-	lookupSRV      = net.LookupSRV // net.DefaultResolver.LookupSRV when ctxs don't conflict
-	resolveTCPAddr = net.ResolveTCPAddr
-)
-
-// GetCluster gets the cluster information via DNS discovery.
-// Also sees each entry as a separate instance.
-func GetCluster(service, name, dns string, apurls types.URLs) ([]string, error) {
-	tempName := int(0)
-	tcp2ap := make(map[string]url.URL)
-
-	// First, resolve the apurls
-	for _, url := range apurls {
-		tcpAddr, err := resolveTCPAddr("tcp", url.Host)
-		if err != nil {
-			return nil, err
-		}
-		tcp2ap[tcpAddr.String()] = url
-	}
-
-	stringParts := []string{}
-	updateNodeMap := func(service, scheme string) error {
-		_, addrs, err := lookupSRV(service, "tcp", dns)
-		if err != nil {
-			return err
-		}
-		for _, srv := range addrs {
-			port := fmt.Sprintf("%d", srv.Port)
-			host := net.JoinHostPort(srv.Target, port)
-			tcpAddr, terr := resolveTCPAddr("tcp", host)
-			if terr != nil {
-				err = terr
-				continue
-			}
-			n := ""
-			url, ok := tcp2ap[tcpAddr.String()]
-			if ok {
-				n = name
-			}
-			if n == "" {
-				n = fmt.Sprintf("%d", tempName)
-				tempName++
-			}
-			// SRV records have a trailing dot but URL shouldn't.
-			shortHost := strings.TrimSuffix(srv.Target, ".")
-			urlHost := net.JoinHostPort(shortHost, port)
-			if ok && url.Scheme != scheme {
-				err = fmt.Errorf("bootstrap at %s from DNS for %s has scheme mismatch with expected peer %s", scheme+"://"+urlHost, service, url.String())
-			} else {
-				stringParts = append(stringParts, fmt.Sprintf("%s=%s://%s", n, scheme, urlHost))
-			}
-		}
-		if len(stringParts) == 0 {
-			return err
-		}
-		return nil
-	}
-
-	failCount := 0
-	err := updateNodeMap(service+"-ssl", "https")
-	srvErr := make([]string, 2)
-	if err != nil {
-		srvErr[0] = fmt.Sprintf("error querying DNS SRV records for _%s-ssl %s", service, err)
-		failCount++
-	}
-	err = updateNodeMap(service, "http")
-	if err != nil {
-		srvErr[1] = fmt.Sprintf("error querying DNS SRV records for _%s %s", service, err)
-		failCount++
-	}
-	if failCount == 2 {
-		return nil, fmt.Errorf("srv: too many errors querying DNS SRV records (%q, %q)", srvErr[0], srvErr[1])
-	}
-	return stringParts, nil
-}
-
-type SRVClients struct {
-	Endpoints []string
-	SRVs      []*net.SRV
-}
-
-// GetClient looks up the client endpoints for a service and domain.
-func GetClient(service, domain string) (*SRVClients, error) {
-	var urls []*url.URL
-	var srvs []*net.SRV
-
-	updateURLs := func(service, scheme string) error {
-		_, addrs, err := lookupSRV(service, "tcp", domain)
-		if err != nil {
-			return err
-		}
-		for _, srv := range addrs {
-			urls = append(urls, &url.URL{
-				Scheme: scheme,
-				Host:   net.JoinHostPort(srv.Target, fmt.Sprintf("%d", srv.Port)),
-			})
-		}
-		srvs = append(srvs, addrs...)
-		return nil
-	}
-
-	errHTTPS := updateURLs(service+"-ssl", "https")
-	errHTTP := updateURLs(service, "http")
-
-	if errHTTPS != nil && errHTTP != nil {
-		return nil, fmt.Errorf("dns lookup errors: %s and %s", errHTTPS, errHTTP)
-	}
-
-	endpoints := make([]string, len(urls))
-	for i := range urls {
-		endpoints[i] = urls[i].String()
-	}
-	return &SRVClients{Endpoints: endpoints, SRVs: srvs}, nil
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/tlsutil/cipher_suites.go b/vendor/github.com/coreos/etcd/pkg/tlsutil/cipher_suites.go
deleted file mode 100644
index b5916bb..0000000
--- a/vendor/github.com/coreos/etcd/pkg/tlsutil/cipher_suites.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package tlsutil
-
-import "crypto/tls"
-
-// cipher suites implemented by Go
-// https://github.com/golang/go/blob/dev.boringcrypto.go1.10/src/crypto/tls/cipher_suites.go
-var cipherSuites = map[string]uint16{
-	"TLS_RSA_WITH_RC4_128_SHA":                tls.TLS_RSA_WITH_RC4_128_SHA,
-	"TLS_RSA_WITH_3DES_EDE_CBC_SHA":           tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
-	"TLS_RSA_WITH_AES_128_CBC_SHA":            tls.TLS_RSA_WITH_AES_128_CBC_SHA,
-	"TLS_RSA_WITH_AES_256_CBC_SHA":            tls.TLS_RSA_WITH_AES_256_CBC_SHA,
-	"TLS_RSA_WITH_AES_128_CBC_SHA256":         tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
-	"TLS_RSA_WITH_AES_128_GCM_SHA256":         tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
-	"TLS_RSA_WITH_AES_256_GCM_SHA384":         tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
-	"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA":        tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
-	"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA":    tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
-	"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA":    tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
-	"TLS_ECDHE_RSA_WITH_RC4_128_SHA":          tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-	"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA":     tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
-	"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA":      tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-	"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA":      tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-	"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
-	"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256":   tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
-	"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256":   tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-	"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
-	"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384":   tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-	"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
-	"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305":    tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-	"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305":  tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
-}
-
-// GetCipherSuite returns the corresponding cipher suite,
-// and boolean value if it is supported.
-func GetCipherSuite(s string) (uint16, bool) {
-	v, ok := cipherSuites[s]
-	return v, ok
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/tlsutil/doc.go b/vendor/github.com/coreos/etcd/pkg/tlsutil/doc.go
deleted file mode 100644
index 3b6aa67..0000000
--- a/vendor/github.com/coreos/etcd/pkg/tlsutil/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package tlsutil provides utility functions for handling TLS.
-package tlsutil
diff --git a/vendor/github.com/coreos/etcd/pkg/tlsutil/tlsutil.go b/vendor/github.com/coreos/etcd/pkg/tlsutil/tlsutil.go
deleted file mode 100644
index 79b1f63..0000000
--- a/vendor/github.com/coreos/etcd/pkg/tlsutil/tlsutil.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package tlsutil
-
-import (
-	"crypto/tls"
-	"crypto/x509"
-	"encoding/pem"
-	"io/ioutil"
-)
-
-// NewCertPool creates x509 certPool with provided CA files.
-func NewCertPool(CAFiles []string) (*x509.CertPool, error) {
-	certPool := x509.NewCertPool()
-
-	for _, CAFile := range CAFiles {
-		pemByte, err := ioutil.ReadFile(CAFile)
-		if err != nil {
-			return nil, err
-		}
-
-		for {
-			var block *pem.Block
-			block, pemByte = pem.Decode(pemByte)
-			if block == nil {
-				break
-			}
-			cert, err := x509.ParseCertificate(block.Bytes)
-			if err != nil {
-				return nil, err
-			}
-			certPool.AddCert(cert)
-		}
-	}
-
-	return certPool, nil
-}
-
-// NewCert generates TLS cert by using the given cert,key and parse function.
-func NewCert(certfile, keyfile string, parseFunc func([]byte, []byte) (tls.Certificate, error)) (*tls.Certificate, error) {
-	cert, err := ioutil.ReadFile(certfile)
-	if err != nil {
-		return nil, err
-	}
-
-	key, err := ioutil.ReadFile(keyfile)
-	if err != nil {
-		return nil, err
-	}
-
-	if parseFunc == nil {
-		parseFunc = tls.X509KeyPair
-	}
-
-	tlsCert, err := parseFunc(cert, key)
-	if err != nil {
-		return nil, err
-	}
-	return &tlsCert, nil
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/doc.go b/vendor/github.com/coreos/etcd/pkg/transport/doc.go
deleted file mode 100644
index 37658ce..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/doc.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package transport implements various HTTP transport utilities based on Go
-// net package.
-package transport
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/keepalive_listener.go b/vendor/github.com/coreos/etcd/pkg/transport/keepalive_listener.go
deleted file mode 100644
index 4ff8e7f..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/keepalive_listener.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
-	"crypto/tls"
-	"fmt"
-	"net"
-	"time"
-)
-
-type keepAliveConn interface {
-	SetKeepAlive(bool) error
-	SetKeepAlivePeriod(d time.Duration) error
-}
-
-// NewKeepAliveListener returns a listener that listens on the given address.
-// Be careful when wrap around KeepAliveListener with another Listener if TLSInfo is not nil.
-// Some pkgs (like go/http) might expect Listener to return TLSConn type to start TLS handshake.
-// http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html
-func NewKeepAliveListener(l net.Listener, scheme string, tlscfg *tls.Config) (net.Listener, error) {
-	if scheme == "https" {
-		if tlscfg == nil {
-			return nil, fmt.Errorf("cannot listen on TLS for given listener: KeyFile and CertFile are not presented")
-		}
-		return newTLSKeepaliveListener(l, tlscfg), nil
-	}
-
-	return &keepaliveListener{
-		Listener: l,
-	}, nil
-}
-
-type keepaliveListener struct{ net.Listener }
-
-func (kln *keepaliveListener) Accept() (net.Conn, error) {
-	c, err := kln.Listener.Accept()
-	if err != nil {
-		return nil, err
-	}
-	kac := c.(keepAliveConn)
-	// detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl
-	// default on linux:  30 + 8 * 30
-	// default on osx:    30 + 8 * 75
-	kac.SetKeepAlive(true)
-	kac.SetKeepAlivePeriod(30 * time.Second)
-	return c, nil
-}
-
-// A tlsKeepaliveListener implements a network listener (net.Listener) for TLS connections.
-type tlsKeepaliveListener struct {
-	net.Listener
-	config *tls.Config
-}
-
-// Accept waits for and returns the next incoming TLS connection.
-// The returned connection c is a *tls.Conn.
-func (l *tlsKeepaliveListener) Accept() (c net.Conn, err error) {
-	c, err = l.Listener.Accept()
-	if err != nil {
-		return
-	}
-	kac := c.(keepAliveConn)
-	// detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl
-	// default on linux:  30 + 8 * 30
-	// default on osx:    30 + 8 * 75
-	kac.SetKeepAlive(true)
-	kac.SetKeepAlivePeriod(30 * time.Second)
-	c = tls.Server(c, l.config)
-	return c, nil
-}
-
-// NewListener creates a Listener which accepts connections from an inner
-// Listener and wraps each connection with Server.
-// The configuration config must be non-nil and must have
-// at least one certificate.
-func newTLSKeepaliveListener(inner net.Listener, config *tls.Config) net.Listener {
-	l := &tlsKeepaliveListener{}
-	l.Listener = inner
-	l.config = config
-	return l
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/limit_listen.go b/vendor/github.com/coreos/etcd/pkg/transport/limit_listen.go
deleted file mode 100644
index 930c542..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/limit_listen.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2013 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package transport provides network utility functions, complementing the more
-// common ones in the net package.
-package transport
-
-import (
-	"errors"
-	"net"
-	"sync"
-	"time"
-)
-
-var (
-	ErrNotTCP = errors.New("only tcp connections have keepalive")
-)
-
-// LimitListener returns a Listener that accepts at most n simultaneous
-// connections from the provided Listener.
-func LimitListener(l net.Listener, n int) net.Listener {
-	return &limitListener{l, make(chan struct{}, n)}
-}
-
-type limitListener struct {
-	net.Listener
-	sem chan struct{}
-}
-
-func (l *limitListener) acquire() { l.sem <- struct{}{} }
-func (l *limitListener) release() { <-l.sem }
-
-func (l *limitListener) Accept() (net.Conn, error) {
-	l.acquire()
-	c, err := l.Listener.Accept()
-	if err != nil {
-		l.release()
-		return nil, err
-	}
-	return &limitListenerConn{Conn: c, release: l.release}, nil
-}
-
-type limitListenerConn struct {
-	net.Conn
-	releaseOnce sync.Once
-	release     func()
-}
-
-func (l *limitListenerConn) Close() error {
-	err := l.Conn.Close()
-	l.releaseOnce.Do(l.release)
-	return err
-}
-
-func (l *limitListenerConn) SetKeepAlive(doKeepAlive bool) error {
-	tcpc, ok := l.Conn.(*net.TCPConn)
-	if !ok {
-		return ErrNotTCP
-	}
-	return tcpc.SetKeepAlive(doKeepAlive)
-}
-
-func (l *limitListenerConn) SetKeepAlivePeriod(d time.Duration) error {
-	tcpc, ok := l.Conn.(*net.TCPConn)
-	if !ok {
-		return ErrNotTCP
-	}
-	return tcpc.SetKeepAlivePeriod(d)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/listener.go b/vendor/github.com/coreos/etcd/pkg/transport/listener.go
deleted file mode 100644
index 4865506..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/listener.go
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
-	"crypto/ecdsa"
-	"crypto/elliptic"
-	"crypto/rand"
-	"crypto/tls"
-	"crypto/x509"
-	"crypto/x509/pkix"
-	"encoding/pem"
-	"errors"
-	"fmt"
-	"math/big"
-	"net"
-	"os"
-	"path/filepath"
-	"strings"
-	"time"
-
-	"github.com/coreos/etcd/pkg/tlsutil"
-)
-
-func NewListener(addr, scheme string, tlsinfo *TLSInfo) (l net.Listener, err error) {
-	if l, err = newListener(addr, scheme); err != nil {
-		return nil, err
-	}
-	return wrapTLS(addr, scheme, tlsinfo, l)
-}
-
-func newListener(addr string, scheme string) (net.Listener, error) {
-	if scheme == "unix" || scheme == "unixs" {
-		// unix sockets via unix://laddr
-		return NewUnixListener(addr)
-	}
-	return net.Listen("tcp", addr)
-}
-
-func wrapTLS(addr, scheme string, tlsinfo *TLSInfo, l net.Listener) (net.Listener, error) {
-	if scheme != "https" && scheme != "unixs" {
-		return l, nil
-	}
-	return newTLSListener(l, tlsinfo, checkSAN)
-}
-
-type TLSInfo struct {
-	CertFile           string
-	KeyFile            string
-	CAFile             string // TODO: deprecate this in v4
-	TrustedCAFile      string
-	ClientCertAuth     bool
-	CRLFile            string
-	InsecureSkipVerify bool
-
-	// ServerName ensures the cert matches the given host in case of discovery / virtual hosting
-	ServerName string
-
-	// HandshakeFailure is optionally called when a connection fails to handshake. The
-	// connection will be closed immediately afterwards.
-	HandshakeFailure func(*tls.Conn, error)
-
-	// CipherSuites is a list of supported cipher suites.
-	// If empty, Go auto-populates it by default.
-	// Note that cipher suites are prioritized in the given order.
-	CipherSuites []uint16
-
-	selfCert bool
-
-	// parseFunc exists to simplify testing. Typically, parseFunc
-	// should be left nil. In that case, tls.X509KeyPair will be used.
-	parseFunc func([]byte, []byte) (tls.Certificate, error)
-
-	// AllowedCN is a CN which must be provided by a client.
-	AllowedCN string
-}
-
-func (info TLSInfo) String() string {
-	return fmt.Sprintf("cert = %s, key = %s, ca = %s, trusted-ca = %s, client-cert-auth = %v, crl-file = %s", info.CertFile, info.KeyFile, info.CAFile, info.TrustedCAFile, info.ClientCertAuth, info.CRLFile)
-}
-
-func (info TLSInfo) Empty() bool {
-	return info.CertFile == "" && info.KeyFile == ""
-}
-
-func SelfCert(dirpath string, hosts []string) (info TLSInfo, err error) {
-	if err = os.MkdirAll(dirpath, 0700); err != nil {
-		return
-	}
-
-	certPath := filepath.Join(dirpath, "cert.pem")
-	keyPath := filepath.Join(dirpath, "key.pem")
-	_, errcert := os.Stat(certPath)
-	_, errkey := os.Stat(keyPath)
-	if errcert == nil && errkey == nil {
-		info.CertFile = certPath
-		info.KeyFile = keyPath
-		info.selfCert = true
-		return
-	}
-
-	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
-	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
-	if err != nil {
-		return
-	}
-
-	tmpl := x509.Certificate{
-		SerialNumber: serialNumber,
-		Subject:      pkix.Name{Organization: []string{"etcd"}},
-		NotBefore:    time.Now(),
-		NotAfter:     time.Now().Add(365 * (24 * time.Hour)),
-
-		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
-		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
-		BasicConstraintsValid: true,
-	}
-
-	for _, host := range hosts {
-		h, _, _ := net.SplitHostPort(host)
-		if ip := net.ParseIP(h); ip != nil {
-			tmpl.IPAddresses = append(tmpl.IPAddresses, ip)
-		} else {
-			tmpl.DNSNames = append(tmpl.DNSNames, h)
-		}
-	}
-
-	priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
-	if err != nil {
-		return
-	}
-
-	derBytes, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, &priv.PublicKey, priv)
-	if err != nil {
-		return
-	}
-
-	certOut, err := os.Create(certPath)
-	if err != nil {
-		return
-	}
-	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
-	certOut.Close()
-
-	b, err := x509.MarshalECPrivateKey(priv)
-	if err != nil {
-		return
-	}
-	keyOut, err := os.OpenFile(keyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
-	if err != nil {
-		return
-	}
-	pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
-	keyOut.Close()
-
-	return SelfCert(dirpath, hosts)
-}
-
-func (info TLSInfo) baseConfig() (*tls.Config, error) {
-	if info.KeyFile == "" || info.CertFile == "" {
-		return nil, fmt.Errorf("KeyFile and CertFile must both be present[key: %v, cert: %v]", info.KeyFile, info.CertFile)
-	}
-
-	_, err := tlsutil.NewCert(info.CertFile, info.KeyFile, info.parseFunc)
-	if err != nil {
-		return nil, err
-	}
-
-	cfg := &tls.Config{
-		MinVersion: tls.VersionTLS12,
-		ServerName: info.ServerName,
-	}
-
-	if len(info.CipherSuites) > 0 {
-		cfg.CipherSuites = info.CipherSuites
-	}
-
-	if info.AllowedCN != "" {
-		cfg.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
-			for _, chains := range verifiedChains {
-				if len(chains) != 0 {
-					if info.AllowedCN == chains[0].Subject.CommonName {
-						return nil
-					}
-				}
-			}
-			return errors.New("CommonName authentication failed")
-		}
-	}
-
-	// this only reloads certs when there's a client request
-	// TODO: support server-side refresh (e.g. inotify, SIGHUP), caching
-	cfg.GetCertificate = func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
-		return tlsutil.NewCert(info.CertFile, info.KeyFile, info.parseFunc)
-	}
-	cfg.GetClientCertificate = func(unused *tls.CertificateRequestInfo) (*tls.Certificate, error) {
-		return tlsutil.NewCert(info.CertFile, info.KeyFile, info.parseFunc)
-	}
-	return cfg, nil
-}
-
-// cafiles returns a list of CA file paths.
-func (info TLSInfo) cafiles() []string {
-	cs := make([]string, 0)
-	if info.CAFile != "" {
-		cs = append(cs, info.CAFile)
-	}
-	if info.TrustedCAFile != "" {
-		cs = append(cs, info.TrustedCAFile)
-	}
-	return cs
-}
-
-// ServerConfig generates a tls.Config object for use by an HTTP server.
-func (info TLSInfo) ServerConfig() (*tls.Config, error) {
-	cfg, err := info.baseConfig()
-	if err != nil {
-		return nil, err
-	}
-
-	cfg.ClientAuth = tls.NoClientCert
-	if info.CAFile != "" || info.ClientCertAuth {
-		cfg.ClientAuth = tls.RequireAndVerifyClientCert
-	}
-
-	CAFiles := info.cafiles()
-	if len(CAFiles) > 0 {
-		cp, err := tlsutil.NewCertPool(CAFiles)
-		if err != nil {
-			return nil, err
-		}
-		cfg.ClientCAs = cp
-	}
-
-	// "h2" NextProtos is necessary for enabling HTTP2 for go's HTTP server
-	cfg.NextProtos = []string{"h2"}
-
-	return cfg, nil
-}
-
-// ClientConfig generates a tls.Config object for use by an HTTP client.
-func (info TLSInfo) ClientConfig() (*tls.Config, error) {
-	var cfg *tls.Config
-	var err error
-
-	if !info.Empty() {
-		cfg, err = info.baseConfig()
-		if err != nil {
-			return nil, err
-		}
-	} else {
-		cfg = &tls.Config{ServerName: info.ServerName}
-	}
-	cfg.InsecureSkipVerify = info.InsecureSkipVerify
-
-	CAFiles := info.cafiles()
-	if len(CAFiles) > 0 {
-		cfg.RootCAs, err = tlsutil.NewCertPool(CAFiles)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	if info.selfCert {
-		cfg.InsecureSkipVerify = true
-	}
-	return cfg, nil
-}
-
-// IsClosedConnError returns true if the error is from closing listener, cmux.
-// copied from golang.org/x/net/http2/http2.go
-func IsClosedConnError(err error) bool {
-	// 'use of closed network connection' (Go <=1.8)
-	// 'use of closed file or network connection' (Go >1.8, internal/poll.ErrClosing)
-	// 'mux: listener closed' (cmux.ErrListenerClosed)
-	return err != nil && strings.Contains(err.Error(), "closed")
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/listener_tls.go b/vendor/github.com/coreos/etcd/pkg/transport/listener_tls.go
deleted file mode 100644
index 6f16009..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/listener_tls.go
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
-	"context"
-	"crypto/tls"
-	"crypto/x509"
-	"fmt"
-	"io/ioutil"
-	"net"
-	"strings"
-	"sync"
-)
-
-// tlsListener overrides a TLS listener so it will reject client
-// certificates with insufficient SAN credentials or CRL revoked
-// certificates.
-type tlsListener struct {
-	net.Listener
-	connc            chan net.Conn
-	donec            chan struct{}
-	err              error
-	handshakeFailure func(*tls.Conn, error)
-	check            tlsCheckFunc
-}
-
-type tlsCheckFunc func(context.Context, *tls.Conn) error
-
-// NewTLSListener handshakes TLS connections and performs optional CRL checking.
-func NewTLSListener(l net.Listener, tlsinfo *TLSInfo) (net.Listener, error) {
-	check := func(context.Context, *tls.Conn) error { return nil }
-	return newTLSListener(l, tlsinfo, check)
-}
-
-func newTLSListener(l net.Listener, tlsinfo *TLSInfo, check tlsCheckFunc) (net.Listener, error) {
-	if tlsinfo == nil || tlsinfo.Empty() {
-		l.Close()
-		return nil, fmt.Errorf("cannot listen on TLS for %s: KeyFile and CertFile are not presented", l.Addr().String())
-	}
-	tlscfg, err := tlsinfo.ServerConfig()
-	if err != nil {
-		return nil, err
-	}
-
-	hf := tlsinfo.HandshakeFailure
-	if hf == nil {
-		hf = func(*tls.Conn, error) {}
-	}
-
-	if len(tlsinfo.CRLFile) > 0 {
-		prevCheck := check
-		check = func(ctx context.Context, tlsConn *tls.Conn) error {
-			if err := prevCheck(ctx, tlsConn); err != nil {
-				return err
-			}
-			st := tlsConn.ConnectionState()
-			if certs := st.PeerCertificates; len(certs) > 0 {
-				return checkCRL(tlsinfo.CRLFile, certs)
-			}
-			return nil
-		}
-	}
-
-	tlsl := &tlsListener{
-		Listener:         tls.NewListener(l, tlscfg),
-		connc:            make(chan net.Conn),
-		donec:            make(chan struct{}),
-		handshakeFailure: hf,
-		check:            check,
-	}
-	go tlsl.acceptLoop()
-	return tlsl, nil
-}
-
-func (l *tlsListener) Accept() (net.Conn, error) {
-	select {
-	case conn := <-l.connc:
-		return conn, nil
-	case <-l.donec:
-		return nil, l.err
-	}
-}
-
-func checkSAN(ctx context.Context, tlsConn *tls.Conn) error {
-	st := tlsConn.ConnectionState()
-	if certs := st.PeerCertificates; len(certs) > 0 {
-		addr := tlsConn.RemoteAddr().String()
-		return checkCertSAN(ctx, certs[0], addr)
-	}
-	return nil
-}
-
-// acceptLoop launches each TLS handshake in a separate goroutine
-// to prevent a hanging TLS connection from blocking other connections.
-func (l *tlsListener) acceptLoop() {
-	var wg sync.WaitGroup
-	var pendingMu sync.Mutex
-
-	pending := make(map[net.Conn]struct{})
-	ctx, cancel := context.WithCancel(context.Background())
-	defer func() {
-		cancel()
-		pendingMu.Lock()
-		for c := range pending {
-			c.Close()
-		}
-		pendingMu.Unlock()
-		wg.Wait()
-		close(l.donec)
-	}()
-
-	for {
-		conn, err := l.Listener.Accept()
-		if err != nil {
-			l.err = err
-			return
-		}
-
-		pendingMu.Lock()
-		pending[conn] = struct{}{}
-		pendingMu.Unlock()
-
-		wg.Add(1)
-		go func() {
-			defer func() {
-				if conn != nil {
-					conn.Close()
-				}
-				wg.Done()
-			}()
-
-			tlsConn := conn.(*tls.Conn)
-			herr := tlsConn.Handshake()
-			pendingMu.Lock()
-			delete(pending, conn)
-			pendingMu.Unlock()
-
-			if herr != nil {
-				l.handshakeFailure(tlsConn, herr)
-				return
-			}
-			if err := l.check(ctx, tlsConn); err != nil {
-				l.handshakeFailure(tlsConn, err)
-				return
-			}
-
-			select {
-			case l.connc <- tlsConn:
-				conn = nil
-			case <-ctx.Done():
-			}
-		}()
-	}
-}
-
-func checkCRL(crlPath string, cert []*x509.Certificate) error {
-	// TODO: cache
-	crlBytes, err := ioutil.ReadFile(crlPath)
-	if err != nil {
-		return err
-	}
-	certList, err := x509.ParseCRL(crlBytes)
-	if err != nil {
-		return err
-	}
-	revokedSerials := make(map[string]struct{})
-	for _, rc := range certList.TBSCertList.RevokedCertificates {
-		revokedSerials[string(rc.SerialNumber.Bytes())] = struct{}{}
-	}
-	for _, c := range cert {
-		serial := string(c.SerialNumber.Bytes())
-		if _, ok := revokedSerials[serial]; ok {
-			return fmt.Errorf("transport: certificate serial %x revoked", serial)
-		}
-	}
-	return nil
-}
-
-func checkCertSAN(ctx context.Context, cert *x509.Certificate, remoteAddr string) error {
-	if len(cert.IPAddresses) == 0 && len(cert.DNSNames) == 0 {
-		return nil
-	}
-	h, _, herr := net.SplitHostPort(remoteAddr)
-	if herr != nil {
-		return herr
-	}
-	if len(cert.IPAddresses) > 0 {
-		cerr := cert.VerifyHostname(h)
-		if cerr == nil {
-			return nil
-		}
-		if len(cert.DNSNames) == 0 {
-			return cerr
-		}
-	}
-	if len(cert.DNSNames) > 0 {
-		ok, err := isHostInDNS(ctx, h, cert.DNSNames)
-		if ok {
-			return nil
-		}
-		errStr := ""
-		if err != nil {
-			errStr = " (" + err.Error() + ")"
-		}
-		return fmt.Errorf("tls: %q does not match any of DNSNames %q"+errStr, h, cert.DNSNames)
-	}
-	return nil
-}
-
-func isHostInDNS(ctx context.Context, host string, dnsNames []string) (ok bool, err error) {
-	// reverse lookup
-	wildcards, names := []string{}, []string{}
-	for _, dns := range dnsNames {
-		if strings.HasPrefix(dns, "*.") {
-			wildcards = append(wildcards, dns[1:])
-		} else {
-			names = append(names, dns)
-		}
-	}
-	lnames, lerr := net.DefaultResolver.LookupAddr(ctx, host)
-	for _, name := range lnames {
-		// strip trailing '.' from PTR record
-		if name[len(name)-1] == '.' {
-			name = name[:len(name)-1]
-		}
-		for _, wc := range wildcards {
-			if strings.HasSuffix(name, wc) {
-				return true, nil
-			}
-		}
-		for _, n := range names {
-			if n == name {
-				return true, nil
-			}
-		}
-	}
-	err = lerr
-
-	// forward lookup
-	for _, dns := range names {
-		addrs, lerr := net.DefaultResolver.LookupHost(ctx, dns)
-		if lerr != nil {
-			err = lerr
-			continue
-		}
-		for _, addr := range addrs {
-			if addr == host {
-				return true, nil
-			}
-		}
-	}
-	return false, err
-}
-
-func (l *tlsListener) Close() error {
-	err := l.Listener.Close()
-	<-l.donec
-	return err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/timeout_conn.go b/vendor/github.com/coreos/etcd/pkg/transport/timeout_conn.go
deleted file mode 100644
index 7e8c020..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_conn.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
-	"net"
-	"time"
-)
-
-type timeoutConn struct {
-	net.Conn
-	wtimeoutd  time.Duration
-	rdtimeoutd time.Duration
-}
-
-func (c timeoutConn) Write(b []byte) (n int, err error) {
-	if c.wtimeoutd > 0 {
-		if err := c.SetWriteDeadline(time.Now().Add(c.wtimeoutd)); err != nil {
-			return 0, err
-		}
-	}
-	return c.Conn.Write(b)
-}
-
-func (c timeoutConn) Read(b []byte) (n int, err error) {
-	if c.rdtimeoutd > 0 {
-		if err := c.SetReadDeadline(time.Now().Add(c.rdtimeoutd)); err != nil {
-			return 0, err
-		}
-	}
-	return c.Conn.Read(b)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/timeout_dialer.go b/vendor/github.com/coreos/etcd/pkg/transport/timeout_dialer.go
deleted file mode 100644
index 6ae39ec..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_dialer.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
-	"net"
-	"time"
-)
-
-type rwTimeoutDialer struct {
-	wtimeoutd  time.Duration
-	rdtimeoutd time.Duration
-	net.Dialer
-}
-
-func (d *rwTimeoutDialer) Dial(network, address string) (net.Conn, error) {
-	conn, err := d.Dialer.Dial(network, address)
-	tconn := &timeoutConn{
-		rdtimeoutd: d.rdtimeoutd,
-		wtimeoutd:  d.wtimeoutd,
-		Conn:       conn,
-	}
-	return tconn, err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/timeout_listener.go b/vendor/github.com/coreos/etcd/pkg/transport/timeout_listener.go
deleted file mode 100644
index b35e049..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_listener.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
-	"net"
-	"time"
-)
-
-// NewTimeoutListener returns a listener that listens on the given address.
-// If read/write on the accepted connection blocks longer than its time limit,
-// it will return timeout error.
-func NewTimeoutListener(addr string, scheme string, tlsinfo *TLSInfo, rdtimeoutd, wtimeoutd time.Duration) (net.Listener, error) {
-	ln, err := newListener(addr, scheme)
-	if err != nil {
-		return nil, err
-	}
-	ln = &rwTimeoutListener{
-		Listener:   ln,
-		rdtimeoutd: rdtimeoutd,
-		wtimeoutd:  wtimeoutd,
-	}
-	if ln, err = wrapTLS(addr, scheme, tlsinfo, ln); err != nil {
-		return nil, err
-	}
-	return ln, nil
-}
-
-type rwTimeoutListener struct {
-	net.Listener
-	wtimeoutd  time.Duration
-	rdtimeoutd time.Duration
-}
-
-func (rwln *rwTimeoutListener) Accept() (net.Conn, error) {
-	c, err := rwln.Listener.Accept()
-	if err != nil {
-		return nil, err
-	}
-	return timeoutConn{
-		Conn:       c,
-		wtimeoutd:  rwln.wtimeoutd,
-		rdtimeoutd: rwln.rdtimeoutd,
-	}, nil
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go b/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go
deleted file mode 100644
index ea16b4c..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/timeout_transport.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
-	"net"
-	"net/http"
-	"time"
-)
-
-// NewTimeoutTransport returns a transport created using the given TLS info.
-// If read/write on the created connection blocks longer than its time limit,
-// it will return timeout error.
-// If read/write timeout is set, transport will not be able to reuse connection.
-func NewTimeoutTransport(info TLSInfo, dialtimeoutd, rdtimeoutd, wtimeoutd time.Duration) (*http.Transport, error) {
-	tr, err := NewTransport(info, dialtimeoutd)
-	if err != nil {
-		return nil, err
-	}
-
-	if rdtimeoutd != 0 || wtimeoutd != 0 {
-		// the timed out connection will timeout soon after it is idle.
-		// it should not be put back to http transport as an idle connection for future usage.
-		tr.MaxIdleConnsPerHost = -1
-	} else {
-		// allow more idle connections between peers to avoid unnecessary port allocation.
-		tr.MaxIdleConnsPerHost = 1024
-	}
-
-	tr.Dial = (&rwTimeoutDialer{
-		Dialer: net.Dialer{
-			Timeout:   dialtimeoutd,
-			KeepAlive: 30 * time.Second,
-		},
-		rdtimeoutd: rdtimeoutd,
-		wtimeoutd:  wtimeoutd,
-	}).Dial
-	return tr, nil
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/tls.go b/vendor/github.com/coreos/etcd/pkg/transport/tls.go
deleted file mode 100644
index 62fe0d3..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/tls.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
-	"fmt"
-	"strings"
-	"time"
-)
-
-// ValidateSecureEndpoints scans the given endpoints against tls info, returning only those
-// endpoints that could be validated as secure.
-func ValidateSecureEndpoints(tlsInfo TLSInfo, eps []string) ([]string, error) {
-	t, err := NewTransport(tlsInfo, 5*time.Second)
-	if err != nil {
-		return nil, err
-	}
-	var errs []string
-	var endpoints []string
-	for _, ep := range eps {
-		if !strings.HasPrefix(ep, "https://") {
-			errs = append(errs, fmt.Sprintf("%q is insecure", ep))
-			continue
-		}
-		conn, cerr := t.Dial("tcp", ep[len("https://"):])
-		if cerr != nil {
-			errs = append(errs, fmt.Sprintf("%q failed to dial (%v)", ep, cerr))
-			continue
-		}
-		conn.Close()
-		endpoints = append(endpoints, ep)
-	}
-	if len(errs) != 0 {
-		err = fmt.Errorf("%s", strings.Join(errs, ","))
-	}
-	return endpoints, err
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/transport.go b/vendor/github.com/coreos/etcd/pkg/transport/transport.go
deleted file mode 100644
index 4a7fe69..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/transport.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
-	"net"
-	"net/http"
-	"strings"
-	"time"
-)
-
-type unixTransport struct{ *http.Transport }
-
-func NewTransport(info TLSInfo, dialtimeoutd time.Duration) (*http.Transport, error) {
-	cfg, err := info.ClientConfig()
-	if err != nil {
-		return nil, err
-	}
-
-	t := &http.Transport{
-		Proxy: http.ProxyFromEnvironment,
-		Dial: (&net.Dialer{
-			Timeout: dialtimeoutd,
-			// value taken from http.DefaultTransport
-			KeepAlive: 30 * time.Second,
-		}).Dial,
-		// value taken from http.DefaultTransport
-		TLSHandshakeTimeout: 10 * time.Second,
-		TLSClientConfig:     cfg,
-	}
-
-	dialer := (&net.Dialer{
-		Timeout:   dialtimeoutd,
-		KeepAlive: 30 * time.Second,
-	})
-	dial := func(net, addr string) (net.Conn, error) {
-		return dialer.Dial("unix", addr)
-	}
-
-	tu := &http.Transport{
-		Proxy:               http.ProxyFromEnvironment,
-		Dial:                dial,
-		TLSHandshakeTimeout: 10 * time.Second,
-		TLSClientConfig:     cfg,
-	}
-	ut := &unixTransport{tu}
-
-	t.RegisterProtocol("unix", ut)
-	t.RegisterProtocol("unixs", ut)
-
-	return t, nil
-}
-
-func (urt *unixTransport) RoundTrip(req *http.Request) (*http.Response, error) {
-	url := *req.URL
-	req.URL = &url
-	req.URL.Scheme = strings.Replace(req.URL.Scheme, "unix", "http", 1)
-	return urt.Transport.RoundTrip(req)
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/transport/unix_listener.go b/vendor/github.com/coreos/etcd/pkg/transport/unix_listener.go
deleted file mode 100644
index 123e203..0000000
--- a/vendor/github.com/coreos/etcd/pkg/transport/unix_listener.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
-	"net"
-	"os"
-)
-
-type unixListener struct{ net.Listener }
-
-func NewUnixListener(addr string) (net.Listener, error) {
-	if err := os.Remove(addr); err != nil && !os.IsNotExist(err) {
-		return nil, err
-	}
-	l, err := net.Listen("unix", addr)
-	if err != nil {
-		return nil, err
-	}
-	return &unixListener{l}, nil
-}
-
-func (ul *unixListener) Close() error {
-	if err := os.Remove(ul.Addr().String()); err != nil && !os.IsNotExist(err) {
-		return err
-	}
-	return ul.Listener.Close()
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/wait/wait.go b/vendor/github.com/coreos/etcd/pkg/wait/wait.go
deleted file mode 100644
index 9b1df41..0000000
--- a/vendor/github.com/coreos/etcd/pkg/wait/wait.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package wait provides utility functions for polling, listening using Go
-// channel.
-package wait
-
-import (
-	"log"
-	"sync"
-)
-
-// Wait is an interface that provides the ability to wait and trigger events that
-// are associated with IDs.
-type Wait interface {
-	// Register waits returns a chan that waits on the given ID.
-	// The chan will be triggered when Trigger is called with
-	// the same ID.
-	Register(id uint64) <-chan interface{}
-	// Trigger triggers the waiting chans with the given ID.
-	Trigger(id uint64, x interface{})
-	IsRegistered(id uint64) bool
-}
-
-type list struct {
-	l sync.RWMutex
-	m map[uint64]chan interface{}
-}
-
-// New creates a Wait.
-func New() Wait {
-	return &list{m: make(map[uint64]chan interface{})}
-}
-
-func (w *list) Register(id uint64) <-chan interface{} {
-	w.l.Lock()
-	defer w.l.Unlock()
-	ch := w.m[id]
-	if ch == nil {
-		ch = make(chan interface{}, 1)
-		w.m[id] = ch
-	} else {
-		log.Panicf("dup id %x", id)
-	}
-	return ch
-}
-
-func (w *list) Trigger(id uint64, x interface{}) {
-	w.l.Lock()
-	ch := w.m[id]
-	delete(w.m, id)
-	w.l.Unlock()
-	if ch != nil {
-		ch <- x
-		close(ch)
-	}
-}
-
-func (w *list) IsRegistered(id uint64) bool {
-	w.l.RLock()
-	defer w.l.RUnlock()
-	_, ok := w.m[id]
-	return ok
-}
-
-type waitWithResponse struct {
-	ch <-chan interface{}
-}
-
-func NewWithResponse(ch <-chan interface{}) Wait {
-	return &waitWithResponse{ch: ch}
-}
-
-func (w *waitWithResponse) Register(id uint64) <-chan interface{} {
-	return w.ch
-}
-func (w *waitWithResponse) Trigger(id uint64, x interface{}) {}
-func (w *waitWithResponse) IsRegistered(id uint64) bool {
-	panic("waitWithResponse.IsRegistered() shouldn't be called")
-}
diff --git a/vendor/github.com/coreos/etcd/pkg/wait/wait_time.go b/vendor/github.com/coreos/etcd/pkg/wait/wait_time.go
deleted file mode 100644
index 297e48a..0000000
--- a/vendor/github.com/coreos/etcd/pkg/wait/wait_time.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package wait
-
-import "sync"
-
-type WaitTime interface {
-	// Wait returns a chan that waits on the given logical deadline.
-	// The chan will be triggered when Trigger is called with a
-	// deadline that is later than the one it is waiting for.
-	Wait(deadline uint64) <-chan struct{}
-	// Trigger triggers all the waiting chans with an earlier logical deadline.
-	Trigger(deadline uint64)
-}
-
-var closec chan struct{}
-
-func init() { closec = make(chan struct{}); close(closec) }
-
-type timeList struct {
-	l                   sync.Mutex
-	lastTriggerDeadline uint64
-	m                   map[uint64]chan struct{}
-}
-
-func NewTimeList() *timeList {
-	return &timeList{m: make(map[uint64]chan struct{})}
-}
-
-func (tl *timeList) Wait(deadline uint64) <-chan struct{} {
-	tl.l.Lock()
-	defer tl.l.Unlock()
-	if tl.lastTriggerDeadline >= deadline {
-		return closec
-	}
-	ch := tl.m[deadline]
-	if ch == nil {
-		ch = make(chan struct{})
-		tl.m[deadline] = ch
-	}
-	return ch
-}
-
-func (tl *timeList) Trigger(deadline uint64) {
-	tl.l.Lock()
-	defer tl.l.Unlock()
-	tl.lastTriggerDeadline = deadline
-	for t, ch := range tl.m {
-		if t <= deadline {
-			delete(tl.m, t)
-			close(ch)
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/auth_client_adapter.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/auth_client_adapter.go
deleted file mode 100644
index 33dc91f..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/auth_client_adapter.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
-	"context"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	grpc "google.golang.org/grpc"
-)
-
-type as2ac struct{ as pb.AuthServer }
-
-func AuthServerToAuthClient(as pb.AuthServer) pb.AuthClient {
-	return &as2ac{as}
-}
-
-func (s *as2ac) AuthEnable(ctx context.Context, in *pb.AuthEnableRequest, opts ...grpc.CallOption) (*pb.AuthEnableResponse, error) {
-	return s.as.AuthEnable(ctx, in)
-}
-
-func (s *as2ac) AuthDisable(ctx context.Context, in *pb.AuthDisableRequest, opts ...grpc.CallOption) (*pb.AuthDisableResponse, error) {
-	return s.as.AuthDisable(ctx, in)
-}
-
-func (s *as2ac) Authenticate(ctx context.Context, in *pb.AuthenticateRequest, opts ...grpc.CallOption) (*pb.AuthenticateResponse, error) {
-	return s.as.Authenticate(ctx, in)
-}
-
-func (s *as2ac) RoleAdd(ctx context.Context, in *pb.AuthRoleAddRequest, opts ...grpc.CallOption) (*pb.AuthRoleAddResponse, error) {
-	return s.as.RoleAdd(ctx, in)
-}
-
-func (s *as2ac) RoleDelete(ctx context.Context, in *pb.AuthRoleDeleteRequest, opts ...grpc.CallOption) (*pb.AuthRoleDeleteResponse, error) {
-	return s.as.RoleDelete(ctx, in)
-}
-
-func (s *as2ac) RoleGet(ctx context.Context, in *pb.AuthRoleGetRequest, opts ...grpc.CallOption) (*pb.AuthRoleGetResponse, error) {
-	return s.as.RoleGet(ctx, in)
-}
-
-func (s *as2ac) RoleList(ctx context.Context, in *pb.AuthRoleListRequest, opts ...grpc.CallOption) (*pb.AuthRoleListResponse, error) {
-	return s.as.RoleList(ctx, in)
-}
-
-func (s *as2ac) RoleRevokePermission(ctx context.Context, in *pb.AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (*pb.AuthRoleRevokePermissionResponse, error) {
-	return s.as.RoleRevokePermission(ctx, in)
-}
-
-func (s *as2ac) RoleGrantPermission(ctx context.Context, in *pb.AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (*pb.AuthRoleGrantPermissionResponse, error) {
-	return s.as.RoleGrantPermission(ctx, in)
-}
-
-func (s *as2ac) UserDelete(ctx context.Context, in *pb.AuthUserDeleteRequest, opts ...grpc.CallOption) (*pb.AuthUserDeleteResponse, error) {
-	return s.as.UserDelete(ctx, in)
-}
-
-func (s *as2ac) UserAdd(ctx context.Context, in *pb.AuthUserAddRequest, opts ...grpc.CallOption) (*pb.AuthUserAddResponse, error) {
-	return s.as.UserAdd(ctx, in)
-}
-
-func (s *as2ac) UserGet(ctx context.Context, in *pb.AuthUserGetRequest, opts ...grpc.CallOption) (*pb.AuthUserGetResponse, error) {
-	return s.as.UserGet(ctx, in)
-}
-
-func (s *as2ac) UserList(ctx context.Context, in *pb.AuthUserListRequest, opts ...grpc.CallOption) (*pb.AuthUserListResponse, error) {
-	return s.as.UserList(ctx, in)
-}
-
-func (s *as2ac) UserGrantRole(ctx context.Context, in *pb.AuthUserGrantRoleRequest, opts ...grpc.CallOption) (*pb.AuthUserGrantRoleResponse, error) {
-	return s.as.UserGrantRole(ctx, in)
-}
-
-func (s *as2ac) UserRevokeRole(ctx context.Context, in *pb.AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (*pb.AuthUserRevokeRoleResponse, error) {
-	return s.as.UserRevokeRole(ctx, in)
-}
-
-func (s *as2ac) UserChangePassword(ctx context.Context, in *pb.AuthUserChangePasswordRequest, opts ...grpc.CallOption) (*pb.AuthUserChangePasswordResponse, error) {
-	return s.as.UserChangePassword(ctx, in)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/chan_stream.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/chan_stream.go
deleted file mode 100644
index 82e3411..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/chan_stream.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
-	"context"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/metadata"
-)
-
-// chanServerStream implements grpc.ServerStream with a chanStream
-type chanServerStream struct {
-	headerc  chan<- metadata.MD
-	trailerc chan<- metadata.MD
-	grpc.Stream
-
-	headers []metadata.MD
-}
-
-func (ss *chanServerStream) SendHeader(md metadata.MD) error {
-	if ss.headerc == nil {
-		return errAlreadySentHeader
-	}
-	outmd := make(map[string][]string)
-	for _, h := range append(ss.headers, md) {
-		for k, v := range h {
-			outmd[k] = v
-		}
-	}
-	select {
-	case ss.headerc <- outmd:
-		ss.headerc = nil
-		ss.headers = nil
-		return nil
-	case <-ss.Context().Done():
-	}
-	return ss.Context().Err()
-}
-
-func (ss *chanServerStream) SetHeader(md metadata.MD) error {
-	if ss.headerc == nil {
-		return errAlreadySentHeader
-	}
-	ss.headers = append(ss.headers, md)
-	return nil
-}
-
-func (ss *chanServerStream) SetTrailer(md metadata.MD) {
-	ss.trailerc <- md
-}
-
-// chanClientStream implements grpc.ClientStream with a chanStream
-type chanClientStream struct {
-	headerc  <-chan metadata.MD
-	trailerc <-chan metadata.MD
-	*chanStream
-}
-
-func (cs *chanClientStream) Header() (metadata.MD, error) {
-	select {
-	case md := <-cs.headerc:
-		return md, nil
-	case <-cs.Context().Done():
-	}
-	return nil, cs.Context().Err()
-}
-
-func (cs *chanClientStream) Trailer() metadata.MD {
-	select {
-	case md := <-cs.trailerc:
-		return md
-	case <-cs.Context().Done():
-		return nil
-	}
-}
-
-func (cs *chanClientStream) CloseSend() error {
-	close(cs.chanStream.sendc)
-	return nil
-}
-
-// chanStream implements grpc.Stream using channels
-type chanStream struct {
-	recvc  <-chan interface{}
-	sendc  chan<- interface{}
-	ctx    context.Context
-	cancel context.CancelFunc
-}
-
-func (s *chanStream) Context() context.Context { return s.ctx }
-
-func (s *chanStream) SendMsg(m interface{}) error {
-	select {
-	case s.sendc <- m:
-		if err, ok := m.(error); ok {
-			return err
-		}
-		return nil
-	case <-s.ctx.Done():
-	}
-	return s.ctx.Err()
-}
-
-func (s *chanStream) RecvMsg(m interface{}) error {
-	v := m.(*interface{})
-	for {
-		select {
-		case msg, ok := <-s.recvc:
-			if !ok {
-				return grpc.ErrClientConnClosing
-			}
-			if err, ok := msg.(error); ok {
-				return err
-			}
-			*v = msg
-			return nil
-		case <-s.ctx.Done():
-		}
-		if len(s.recvc) == 0 {
-			// prioritize any pending recv messages over canceled context
-			break
-		}
-	}
-	return s.ctx.Err()
-}
-
-func newPipeStream(ctx context.Context, ssHandler func(chanServerStream) error) chanClientStream {
-	// ch1 is buffered so server can send error on close
-	ch1, ch2 := make(chan interface{}, 1), make(chan interface{})
-	headerc, trailerc := make(chan metadata.MD, 1), make(chan metadata.MD, 1)
-
-	cctx, ccancel := context.WithCancel(ctx)
-	cli := &chanStream{recvc: ch1, sendc: ch2, ctx: cctx, cancel: ccancel}
-	cs := chanClientStream{headerc, trailerc, cli}
-
-	sctx, scancel := context.WithCancel(ctx)
-	srv := &chanStream{recvc: ch2, sendc: ch1, ctx: sctx, cancel: scancel}
-	ss := chanServerStream{headerc, trailerc, srv, nil}
-
-	go func() {
-		if err := ssHandler(ss); err != nil {
-			select {
-			case srv.sendc <- err:
-			case <-sctx.Done():
-			case <-cctx.Done():
-			}
-		}
-		scancel()
-		ccancel()
-	}()
-	return cs
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/cluster_client_adapter.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/cluster_client_adapter.go
deleted file mode 100644
index 6c03409..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/cluster_client_adapter.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
-	"context"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-)
-
-type cls2clc struct{ cls pb.ClusterServer }
-
-func ClusterServerToClusterClient(cls pb.ClusterServer) pb.ClusterClient {
-	return &cls2clc{cls}
-}
-
-func (s *cls2clc) MemberList(ctx context.Context, r *pb.MemberListRequest, opts ...grpc.CallOption) (*pb.MemberListResponse, error) {
-	return s.cls.MemberList(ctx, r)
-}
-
-func (s *cls2clc) MemberAdd(ctx context.Context, r *pb.MemberAddRequest, opts ...grpc.CallOption) (*pb.MemberAddResponse, error) {
-	return s.cls.MemberAdd(ctx, r)
-}
-
-func (s *cls2clc) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest, opts ...grpc.CallOption) (*pb.MemberUpdateResponse, error) {
-	return s.cls.MemberUpdate(ctx, r)
-}
-
-func (s *cls2clc) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest, opts ...grpc.CallOption) (*pb.MemberRemoveResponse, error) {
-	return s.cls.MemberRemove(ctx, r)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/doc.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/doc.go
deleted file mode 100644
index 7170be2..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/doc.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package adapter provides gRPC adapters between client and server
-// gRPC interfaces without needing to go through a gRPC connection.
-package adapter
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/election_client_adapter.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/election_client_adapter.go
deleted file mode 100644
index a2ebf13..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/election_client_adapter.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb"
-
-	"google.golang.org/grpc"
-)
-
-type es2ec struct{ es v3electionpb.ElectionServer }
-
-func ElectionServerToElectionClient(es v3electionpb.ElectionServer) v3electionpb.ElectionClient {
-	return &es2ec{es}
-}
-
-func (s *es2ec) Campaign(ctx context.Context, r *v3electionpb.CampaignRequest, opts ...grpc.CallOption) (*v3electionpb.CampaignResponse, error) {
-	return s.es.Campaign(ctx, r)
-}
-
-func (s *es2ec) Proclaim(ctx context.Context, r *v3electionpb.ProclaimRequest, opts ...grpc.CallOption) (*v3electionpb.ProclaimResponse, error) {
-	return s.es.Proclaim(ctx, r)
-}
-
-func (s *es2ec) Leader(ctx context.Context, r *v3electionpb.LeaderRequest, opts ...grpc.CallOption) (*v3electionpb.LeaderResponse, error) {
-	return s.es.Leader(ctx, r)
-}
-
-func (s *es2ec) Resign(ctx context.Context, r *v3electionpb.ResignRequest, opts ...grpc.CallOption) (*v3electionpb.ResignResponse, error) {
-	return s.es.Resign(ctx, r)
-}
-
-func (s *es2ec) Observe(ctx context.Context, in *v3electionpb.LeaderRequest, opts ...grpc.CallOption) (v3electionpb.Election_ObserveClient, error) {
-	cs := newPipeStream(ctx, func(ss chanServerStream) error {
-		return s.es.Observe(in, &es2ecServerStream{ss})
-	})
-	return &es2ecClientStream{cs}, nil
-}
-
-// es2ecClientStream implements Election_ObserveClient
-type es2ecClientStream struct{ chanClientStream }
-
-// es2ecServerStream implements Election_ObserveServer
-type es2ecServerStream struct{ chanServerStream }
-
-func (s *es2ecClientStream) Send(rr *v3electionpb.LeaderRequest) error {
-	return s.SendMsg(rr)
-}
-func (s *es2ecClientStream) Recv() (*v3electionpb.LeaderResponse, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*v3electionpb.LeaderResponse), nil
-}
-
-func (s *es2ecServerStream) Send(rr *v3electionpb.LeaderResponse) error {
-	return s.SendMsg(rr)
-}
-func (s *es2ecServerStream) Recv() (*v3electionpb.LeaderRequest, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*v3electionpb.LeaderRequest), nil
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/kv_client_adapter.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/kv_client_adapter.go
deleted file mode 100644
index acd5673..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/kv_client_adapter.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
-	"context"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	grpc "google.golang.org/grpc"
-)
-
-type kvs2kvc struct{ kvs pb.KVServer }
-
-func KvServerToKvClient(kvs pb.KVServer) pb.KVClient {
-	return &kvs2kvc{kvs}
-}
-
-func (s *kvs2kvc) Range(ctx context.Context, in *pb.RangeRequest, opts ...grpc.CallOption) (*pb.RangeResponse, error) {
-	return s.kvs.Range(ctx, in)
-}
-
-func (s *kvs2kvc) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (*pb.PutResponse, error) {
-	return s.kvs.Put(ctx, in)
-}
-
-func (s *kvs2kvc) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (*pb.DeleteRangeResponse, error) {
-	return s.kvs.DeleteRange(ctx, in)
-}
-
-func (s *kvs2kvc) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (*pb.TxnResponse, error) {
-	return s.kvs.Txn(ctx, in)
-}
-
-func (s *kvs2kvc) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (*pb.CompactionResponse, error) {
-	return s.kvs.Compact(ctx, in)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/lease_client_adapter.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/lease_client_adapter.go
deleted file mode 100644
index 84c48b5..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/lease_client_adapter.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
-	"context"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-)
-
-type ls2lc struct {
-	leaseServer pb.LeaseServer
-}
-
-func LeaseServerToLeaseClient(ls pb.LeaseServer) pb.LeaseClient {
-	return &ls2lc{ls}
-}
-
-func (c *ls2lc) LeaseGrant(ctx context.Context, in *pb.LeaseGrantRequest, opts ...grpc.CallOption) (*pb.LeaseGrantResponse, error) {
-	return c.leaseServer.LeaseGrant(ctx, in)
-}
-
-func (c *ls2lc) LeaseRevoke(ctx context.Context, in *pb.LeaseRevokeRequest, opts ...grpc.CallOption) (*pb.LeaseRevokeResponse, error) {
-	return c.leaseServer.LeaseRevoke(ctx, in)
-}
-
-func (c *ls2lc) LeaseKeepAlive(ctx context.Context, opts ...grpc.CallOption) (pb.Lease_LeaseKeepAliveClient, error) {
-	cs := newPipeStream(ctx, func(ss chanServerStream) error {
-		return c.leaseServer.LeaseKeepAlive(&ls2lcServerStream{ss})
-	})
-	return &ls2lcClientStream{cs}, nil
-}
-
-func (c *ls2lc) LeaseTimeToLive(ctx context.Context, in *pb.LeaseTimeToLiveRequest, opts ...grpc.CallOption) (*pb.LeaseTimeToLiveResponse, error) {
-	return c.leaseServer.LeaseTimeToLive(ctx, in)
-}
-
-func (c *ls2lc) LeaseLeases(ctx context.Context, in *pb.LeaseLeasesRequest, opts ...grpc.CallOption) (*pb.LeaseLeasesResponse, error) {
-	return c.leaseServer.LeaseLeases(ctx, in)
-}
-
-// ls2lcClientStream implements Lease_LeaseKeepAliveClient
-type ls2lcClientStream struct{ chanClientStream }
-
-// ls2lcServerStream implements Lease_LeaseKeepAliveServer
-type ls2lcServerStream struct{ chanServerStream }
-
-func (s *ls2lcClientStream) Send(rr *pb.LeaseKeepAliveRequest) error {
-	return s.SendMsg(rr)
-}
-func (s *ls2lcClientStream) Recv() (*pb.LeaseKeepAliveResponse, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.LeaseKeepAliveResponse), nil
-}
-
-func (s *ls2lcServerStream) Send(rr *pb.LeaseKeepAliveResponse) error {
-	return s.SendMsg(rr)
-}
-func (s *ls2lcServerStream) Recv() (*pb.LeaseKeepAliveRequest, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.LeaseKeepAliveRequest), nil
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/lock_client_adapter.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/lock_client_adapter.go
deleted file mode 100644
index 9ce7913..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/lock_client_adapter.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb"
-
-	"google.golang.org/grpc"
-)
-
-type ls2lsc struct{ ls v3lockpb.LockServer }
-
-func LockServerToLockClient(ls v3lockpb.LockServer) v3lockpb.LockClient {
-	return &ls2lsc{ls}
-}
-
-func (s *ls2lsc) Lock(ctx context.Context, r *v3lockpb.LockRequest, opts ...grpc.CallOption) (*v3lockpb.LockResponse, error) {
-	return s.ls.Lock(ctx, r)
-}
-
-func (s *ls2lsc) Unlock(ctx context.Context, r *v3lockpb.UnlockRequest, opts ...grpc.CallOption) (*v3lockpb.UnlockResponse, error) {
-	return s.ls.Unlock(ctx, r)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/maintenance_client_adapter.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/maintenance_client_adapter.go
deleted file mode 100644
index 92d9dfd..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/maintenance_client_adapter.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
-	"context"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-)
-
-type mts2mtc struct{ mts pb.MaintenanceServer }
-
-func MaintenanceServerToMaintenanceClient(mts pb.MaintenanceServer) pb.MaintenanceClient {
-	return &mts2mtc{mts}
-}
-
-func (s *mts2mtc) Alarm(ctx context.Context, r *pb.AlarmRequest, opts ...grpc.CallOption) (*pb.AlarmResponse, error) {
-	return s.mts.Alarm(ctx, r)
-}
-
-func (s *mts2mtc) Status(ctx context.Context, r *pb.StatusRequest, opts ...grpc.CallOption) (*pb.StatusResponse, error) {
-	return s.mts.Status(ctx, r)
-}
-
-func (s *mts2mtc) Defragment(ctx context.Context, dr *pb.DefragmentRequest, opts ...grpc.CallOption) (*pb.DefragmentResponse, error) {
-	return s.mts.Defragment(ctx, dr)
-}
-
-func (s *mts2mtc) Hash(ctx context.Context, r *pb.HashRequest, opts ...grpc.CallOption) (*pb.HashResponse, error) {
-	return s.mts.Hash(ctx, r)
-}
-
-func (s *mts2mtc) HashKV(ctx context.Context, r *pb.HashKVRequest, opts ...grpc.CallOption) (*pb.HashKVResponse, error) {
-	return s.mts.HashKV(ctx, r)
-}
-
-func (s *mts2mtc) MoveLeader(ctx context.Context, r *pb.MoveLeaderRequest, opts ...grpc.CallOption) (*pb.MoveLeaderResponse, error) {
-	return s.mts.MoveLeader(ctx, r)
-}
-
-func (s *mts2mtc) Snapshot(ctx context.Context, in *pb.SnapshotRequest, opts ...grpc.CallOption) (pb.Maintenance_SnapshotClient, error) {
-	cs := newPipeStream(ctx, func(ss chanServerStream) error {
-		return s.mts.Snapshot(in, &ss2scServerStream{ss})
-	})
-	return &ss2scClientStream{cs}, nil
-}
-
-// ss2scClientStream implements Maintenance_SnapshotClient
-type ss2scClientStream struct{ chanClientStream }
-
-// ss2scServerStream implements Maintenance_SnapshotServer
-type ss2scServerStream struct{ chanServerStream }
-
-func (s *ss2scClientStream) Send(rr *pb.SnapshotRequest) error {
-	return s.SendMsg(rr)
-}
-func (s *ss2scClientStream) Recv() (*pb.SnapshotResponse, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.SnapshotResponse), nil
-}
-
-func (s *ss2scServerStream) Send(rr *pb.SnapshotResponse) error {
-	return s.SendMsg(rr)
-}
-func (s *ss2scServerStream) Recv() (*pb.SnapshotRequest, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.SnapshotRequest), nil
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/watch_client_adapter.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/watch_client_adapter.go
deleted file mode 100644
index afe61e8..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/adapter/watch_client_adapter.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package adapter
-
-import (
-	"context"
-	"errors"
-
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"google.golang.org/grpc"
-)
-
-var errAlreadySentHeader = errors.New("adapter: already sent header")
-
-type ws2wc struct{ wserv pb.WatchServer }
-
-func WatchServerToWatchClient(wserv pb.WatchServer) pb.WatchClient {
-	return &ws2wc{wserv}
-}
-
-func (s *ws2wc) Watch(ctx context.Context, opts ...grpc.CallOption) (pb.Watch_WatchClient, error) {
-	cs := newPipeStream(ctx, func(ss chanServerStream) error {
-		return s.wserv.Watch(&ws2wcServerStream{ss})
-	})
-	return &ws2wcClientStream{cs}, nil
-}
-
-// ws2wcClientStream implements Watch_WatchClient
-type ws2wcClientStream struct{ chanClientStream }
-
-// ws2wcServerStream implements Watch_WatchServer
-type ws2wcServerStream struct{ chanServerStream }
-
-func (s *ws2wcClientStream) Send(wr *pb.WatchRequest) error {
-	return s.SendMsg(wr)
-}
-func (s *ws2wcClientStream) Recv() (*pb.WatchResponse, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.WatchResponse), nil
-}
-
-func (s *ws2wcServerStream) Send(wr *pb.WatchResponse) error {
-	return s.SendMsg(wr)
-}
-func (s *ws2wcServerStream) Recv() (*pb.WatchRequest, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.WatchRequest), nil
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/auth.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/auth.go
deleted file mode 100644
index 0ed8d24..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/auth.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/clientv3"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-type AuthProxy struct {
-	client *clientv3.Client
-}
-
-func NewAuthProxy(c *clientv3.Client) pb.AuthServer {
-	return &AuthProxy{client: c}
-}
-
-func (ap *AuthProxy) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).AuthEnable(ctx, r)
-}
-
-func (ap *AuthProxy) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).AuthDisable(ctx, r)
-}
-
-func (ap *AuthProxy) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).Authenticate(ctx, r)
-}
-
-func (ap *AuthProxy) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).RoleAdd(ctx, r)
-}
-
-func (ap *AuthProxy) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).RoleDelete(ctx, r)
-}
-
-func (ap *AuthProxy) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).RoleGet(ctx, r)
-}
-
-func (ap *AuthProxy) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).RoleList(ctx, r)
-}
-
-func (ap *AuthProxy) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).RoleRevokePermission(ctx, r)
-}
-
-func (ap *AuthProxy) RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).RoleGrantPermission(ctx, r)
-}
-
-func (ap *AuthProxy) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).UserAdd(ctx, r)
-}
-
-func (ap *AuthProxy) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).UserDelete(ctx, r)
-}
-
-func (ap *AuthProxy) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).UserGet(ctx, r)
-}
-
-func (ap *AuthProxy) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).UserList(ctx, r)
-}
-
-func (ap *AuthProxy) UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).UserGrantRole(ctx, r)
-}
-
-func (ap *AuthProxy) UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).UserRevokeRole(ctx, r)
-}
-
-func (ap *AuthProxy) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
-	conn := ap.client.ActiveConnection()
-	return pb.NewAuthClient(conn).UserChangePassword(ctx, r)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/cache/store.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/cache/store.go
deleted file mode 100644
index 5765228..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/cache/store.go
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package cache exports functionality for efficiently caching and mapping
-// `RangeRequest`s to corresponding `RangeResponse`s.
-package cache
-
-import (
-	"errors"
-	"sync"
-
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/pkg/adt"
-	"github.com/golang/groupcache/lru"
-)
-
-var (
-	DefaultMaxEntries = 2048
-	ErrCompacted      = rpctypes.ErrGRPCCompacted
-)
-
-type Cache interface {
-	Add(req *pb.RangeRequest, resp *pb.RangeResponse)
-	Get(req *pb.RangeRequest) (*pb.RangeResponse, error)
-	Compact(revision int64)
-	Invalidate(key []byte, endkey []byte)
-	Size() int
-	Close()
-}
-
-// keyFunc returns the key of a request, which is used to look up its caching response in the cache.
-func keyFunc(req *pb.RangeRequest) string {
-	// TODO: use marshalTo to reduce allocation
-	b, err := req.Marshal()
-	if err != nil {
-		panic(err)
-	}
-	return string(b)
-}
-
-func NewCache(maxCacheEntries int) Cache {
-	return &cache{
-		lru:          lru.New(maxCacheEntries),
-		compactedRev: -1,
-	}
-}
-
-func (c *cache) Close() {}
-
-// cache implements Cache
-type cache struct {
-	mu  sync.RWMutex
-	lru *lru.Cache
-
-	// a reverse index for cache invalidation
-	cachedRanges adt.IntervalTree
-
-	compactedRev int64
-}
-
-// Add adds the response of a request to the cache if its revision is larger than the compacted revision of the cache.
-func (c *cache) Add(req *pb.RangeRequest, resp *pb.RangeResponse) {
-	key := keyFunc(req)
-
-	c.mu.Lock()
-	defer c.mu.Unlock()
-
-	if req.Revision > c.compactedRev {
-		c.lru.Add(key, resp)
-	}
-	// we do not need to invalidate a request with a revision specified.
-	// so we do not need to add it into the reverse index.
-	if req.Revision != 0 {
-		return
-	}
-
-	var (
-		iv  *adt.IntervalValue
-		ivl adt.Interval
-	)
-	if len(req.RangeEnd) != 0 {
-		ivl = adt.NewStringAffineInterval(string(req.Key), string(req.RangeEnd))
-	} else {
-		ivl = adt.NewStringAffinePoint(string(req.Key))
-	}
-
-	iv = c.cachedRanges.Find(ivl)
-
-	if iv == nil {
-		val := map[string]struct{}{key: {}}
-		c.cachedRanges.Insert(ivl, val)
-	} else {
-		val := iv.Val.(map[string]struct{})
-		val[key] = struct{}{}
-		iv.Val = val
-	}
-}
-
-// Get looks up the caching response for a given request.
-// Get is also responsible for lazy eviction when accessing compacted entries.
-func (c *cache) Get(req *pb.RangeRequest) (*pb.RangeResponse, error) {
-	key := keyFunc(req)
-
-	c.mu.Lock()
-	defer c.mu.Unlock()
-
-	if req.Revision > 0 && req.Revision < c.compactedRev {
-		c.lru.Remove(key)
-		return nil, ErrCompacted
-	}
-
-	if resp, ok := c.lru.Get(key); ok {
-		return resp.(*pb.RangeResponse), nil
-	}
-	return nil, errors.New("not exist")
-}
-
-// Invalidate invalidates the cache entries that intersecting with the given range from key to endkey.
-func (c *cache) Invalidate(key, endkey []byte) {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-
-	var (
-		ivs []*adt.IntervalValue
-		ivl adt.Interval
-	)
-	if len(endkey) == 0 {
-		ivl = adt.NewStringAffinePoint(string(key))
-	} else {
-		ivl = adt.NewStringAffineInterval(string(key), string(endkey))
-	}
-
-	ivs = c.cachedRanges.Stab(ivl)
-	for _, iv := range ivs {
-		keys := iv.Val.(map[string]struct{})
-		for key := range keys {
-			c.lru.Remove(key)
-		}
-	}
-	// delete after removing all keys since it is destructive to 'ivs'
-	c.cachedRanges.Delete(ivl)
-}
-
-// Compact invalidate all caching response before the given rev.
-// Replace with the invalidation is lazy. The actual removal happens when the entries is accessed.
-func (c *cache) Compact(revision int64) {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-
-	if revision > c.compactedRev {
-		c.compactedRev = revision
-	}
-}
-
-func (c *cache) Size() int {
-	c.mu.RLock()
-	defer c.mu.RUnlock()
-	return c.lru.Len()
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/cluster.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/cluster.go
deleted file mode 100644
index 6e8d3c8..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/cluster.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-	"fmt"
-	"os"
-	"sync"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/clientv3/naming"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"golang.org/x/time/rate"
-	gnaming "google.golang.org/grpc/naming"
-)
-
-// allow maximum 1 retry per second
-const resolveRetryRate = 1
-
-type clusterProxy struct {
-	clus clientv3.Cluster
-	ctx  context.Context
-	gr   *naming.GRPCResolver
-
-	// advertise client URL
-	advaddr string
-	prefix  string
-
-	umu  sync.RWMutex
-	umap map[string]gnaming.Update
-}
-
-// NewClusterProxy takes optional prefix to fetch grpc-proxy member endpoints.
-// The returned channel is closed when there is grpc-proxy endpoint registered
-// and the client's context is canceled so the 'register' loop returns.
-func NewClusterProxy(c *clientv3.Client, advaddr string, prefix string) (pb.ClusterServer, <-chan struct{}) {
-	cp := &clusterProxy{
-		clus: c.Cluster,
-		ctx:  c.Ctx(),
-		gr:   &naming.GRPCResolver{Client: c},
-
-		advaddr: advaddr,
-		prefix:  prefix,
-		umap:    make(map[string]gnaming.Update),
-	}
-
-	donec := make(chan struct{})
-	if advaddr != "" && prefix != "" {
-		go func() {
-			defer close(donec)
-			cp.resolve(prefix)
-		}()
-		return cp, donec
-	}
-
-	close(donec)
-	return cp, donec
-}
-
-func (cp *clusterProxy) resolve(prefix string) {
-	rm := rate.NewLimiter(rate.Limit(resolveRetryRate), resolveRetryRate)
-	for rm.Wait(cp.ctx) == nil {
-		wa, err := cp.gr.Resolve(prefix)
-		if err != nil {
-			plog.Warningf("failed to resolve %q (%v)", prefix, err)
-			continue
-		}
-		cp.monitor(wa)
-	}
-}
-
-func (cp *clusterProxy) monitor(wa gnaming.Watcher) {
-	for cp.ctx.Err() == nil {
-		ups, err := wa.Next()
-		if err != nil {
-			plog.Warningf("clusterProxy watcher error (%v)", err)
-			if rpctypes.ErrorDesc(err) == naming.ErrWatcherClosed.Error() {
-				return
-			}
-		}
-
-		cp.umu.Lock()
-		for i := range ups {
-			switch ups[i].Op {
-			case gnaming.Add:
-				cp.umap[ups[i].Addr] = *ups[i]
-			case gnaming.Delete:
-				delete(cp.umap, ups[i].Addr)
-			}
-		}
-		cp.umu.Unlock()
-	}
-}
-
-func (cp *clusterProxy) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) (*pb.MemberAddResponse, error) {
-	mresp, err := cp.clus.MemberAdd(ctx, r.PeerURLs)
-	if err != nil {
-		return nil, err
-	}
-	resp := (pb.MemberAddResponse)(*mresp)
-	return &resp, err
-}
-
-func (cp *clusterProxy) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest) (*pb.MemberRemoveResponse, error) {
-	mresp, err := cp.clus.MemberRemove(ctx, r.ID)
-	if err != nil {
-		return nil, err
-	}
-	resp := (pb.MemberRemoveResponse)(*mresp)
-	return &resp, err
-}
-
-func (cp *clusterProxy) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest) (*pb.MemberUpdateResponse, error) {
-	mresp, err := cp.clus.MemberUpdate(ctx, r.ID, r.PeerURLs)
-	if err != nil {
-		return nil, err
-	}
-	resp := (pb.MemberUpdateResponse)(*mresp)
-	return &resp, err
-}
-
-func (cp *clusterProxy) membersFromUpdates() ([]*pb.Member, error) {
-	cp.umu.RLock()
-	defer cp.umu.RUnlock()
-	mbs := make([]*pb.Member, 0, len(cp.umap))
-	for addr, upt := range cp.umap {
-		m, err := decodeMeta(fmt.Sprint(upt.Metadata))
-		if err != nil {
-			return nil, err
-		}
-		mbs = append(mbs, &pb.Member{Name: m.Name, ClientURLs: []string{addr}})
-	}
-	return mbs, nil
-}
-
-// MemberList wraps member list API with following rules:
-// - If 'advaddr' is not empty and 'prefix' is not empty, return registered member lists via resolver
-// - If 'advaddr' is not empty and 'prefix' is not empty and registered grpc-proxy members haven't been fetched, return the 'advaddr'
-// - If 'advaddr' is not empty and 'prefix' is empty, return 'advaddr' without forcing it to 'register'
-// - If 'advaddr' is empty, forward to member list API
-func (cp *clusterProxy) MemberList(ctx context.Context, r *pb.MemberListRequest) (*pb.MemberListResponse, error) {
-	if cp.advaddr != "" {
-		if cp.prefix != "" {
-			mbs, err := cp.membersFromUpdates()
-			if err != nil {
-				return nil, err
-			}
-			if len(mbs) > 0 {
-				return &pb.MemberListResponse{Members: mbs}, nil
-			}
-		}
-		// prefix is empty or no grpc-proxy members haven't been registered
-		hostname, _ := os.Hostname()
-		return &pb.MemberListResponse{Members: []*pb.Member{{Name: hostname, ClientURLs: []string{cp.advaddr}}}}, nil
-	}
-	mresp, err := cp.clus.MemberList(ctx)
-	if err != nil {
-		return nil, err
-	}
-	resp := (pb.MemberListResponse)(*mresp)
-	return &resp, err
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/doc.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/doc.go
deleted file mode 100644
index fc022e3..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package grpcproxy is an OSI level 7 proxy for etcd v3 API requests.
-package grpcproxy
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/election.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/election.go
deleted file mode 100644
index 4b4a4cc..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/election.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2017 The etcd Lockors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb"
-)
-
-type electionProxy struct {
-	client *clientv3.Client
-}
-
-func NewElectionProxy(client *clientv3.Client) v3electionpb.ElectionServer {
-	return &electionProxy{client: client}
-}
-
-func (ep *electionProxy) Campaign(ctx context.Context, req *v3electionpb.CampaignRequest) (*v3electionpb.CampaignResponse, error) {
-	return v3electionpb.NewElectionClient(ep.client.ActiveConnection()).Campaign(ctx, req)
-}
-
-func (ep *electionProxy) Proclaim(ctx context.Context, req *v3electionpb.ProclaimRequest) (*v3electionpb.ProclaimResponse, error) {
-	return v3electionpb.NewElectionClient(ep.client.ActiveConnection()).Proclaim(ctx, req)
-}
-
-func (ep *electionProxy) Leader(ctx context.Context, req *v3electionpb.LeaderRequest) (*v3electionpb.LeaderResponse, error) {
-	return v3electionpb.NewElectionClient(ep.client.ActiveConnection()).Leader(ctx, req)
-}
-
-func (ep *electionProxy) Observe(req *v3electionpb.LeaderRequest, s v3electionpb.Election_ObserveServer) error {
-	conn := ep.client.ActiveConnection()
-	ctx, cancel := context.WithCancel(s.Context())
-	defer cancel()
-	sc, err := v3electionpb.NewElectionClient(conn).Observe(ctx, req)
-	if err != nil {
-		return err
-	}
-	for {
-		rr, err := sc.Recv()
-		if err != nil {
-			return err
-		}
-		if err = s.Send(rr); err != nil {
-			return err
-		}
-	}
-}
-
-func (ep *electionProxy) Resign(ctx context.Context, req *v3electionpb.ResignRequest) (*v3electionpb.ResignResponse, error) {
-	return v3electionpb.NewElectionClient(ep.client.ActiveConnection()).Resign(ctx, req)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/health.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/health.go
deleted file mode 100644
index e5e91f2..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/health.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-	"net/http"
-	"time"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/etcdserver/api/etcdhttp"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-)
-
-// HandleHealth registers health handler on '/health'.
-func HandleHealth(mux *http.ServeMux, c *clientv3.Client) {
-	mux.Handle(etcdhttp.PathHealth, etcdhttp.NewHealthHandler(func() etcdhttp.Health { return checkHealth(c) }))
-}
-
-func checkHealth(c *clientv3.Client) etcdhttp.Health {
-	h := etcdhttp.Health{Health: "false"}
-	ctx, cancel := context.WithTimeout(c.Ctx(), time.Second)
-	_, err := c.Get(ctx, "a")
-	cancel()
-	if err == nil || err == rpctypes.ErrPermissionDenied {
-		h.Health = "true"
-	}
-	return h
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/kv.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/kv.go
deleted file mode 100644
index 1c9860f..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/kv.go
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/clientv3"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/proxy/grpcproxy/cache"
-)
-
-type kvProxy struct {
-	kv    clientv3.KV
-	cache cache.Cache
-}
-
-func NewKvProxy(c *clientv3.Client) (pb.KVServer, <-chan struct{}) {
-	kv := &kvProxy{
-		kv:    c.KV,
-		cache: cache.NewCache(cache.DefaultMaxEntries),
-	}
-	donec := make(chan struct{})
-	close(donec)
-	return kv, donec
-}
-
-func (p *kvProxy) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) {
-	if r.Serializable {
-		resp, err := p.cache.Get(r)
-		switch err {
-		case nil:
-			cacheHits.Inc()
-			return resp, nil
-		case cache.ErrCompacted:
-			cacheHits.Inc()
-			return nil, err
-		}
-
-		cachedMisses.Inc()
-	}
-
-	resp, err := p.kv.Do(ctx, RangeRequestToOp(r))
-	if err != nil {
-		return nil, err
-	}
-
-	// cache linearizable as serializable
-	req := *r
-	req.Serializable = true
-	gresp := (*pb.RangeResponse)(resp.Get())
-	p.cache.Add(&req, gresp)
-	cacheKeys.Set(float64(p.cache.Size()))
-
-	return gresp, nil
-}
-
-func (p *kvProxy) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) {
-	p.cache.Invalidate(r.Key, nil)
-	cacheKeys.Set(float64(p.cache.Size()))
-
-	resp, err := p.kv.Do(ctx, PutRequestToOp(r))
-	return (*pb.PutResponse)(resp.Put()), err
-}
-
-func (p *kvProxy) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	p.cache.Invalidate(r.Key, r.RangeEnd)
-	cacheKeys.Set(float64(p.cache.Size()))
-
-	resp, err := p.kv.Do(ctx, DelRequestToOp(r))
-	return (*pb.DeleteRangeResponse)(resp.Del()), err
-}
-
-func (p *kvProxy) txnToCache(reqs []*pb.RequestOp, resps []*pb.ResponseOp) {
-	for i := range resps {
-		switch tv := resps[i].Response.(type) {
-		case *pb.ResponseOp_ResponsePut:
-			p.cache.Invalidate(reqs[i].GetRequestPut().Key, nil)
-		case *pb.ResponseOp_ResponseDeleteRange:
-			rdr := reqs[i].GetRequestDeleteRange()
-			p.cache.Invalidate(rdr.Key, rdr.RangeEnd)
-		case *pb.ResponseOp_ResponseRange:
-			req := *(reqs[i].GetRequestRange())
-			req.Serializable = true
-			p.cache.Add(&req, tv.ResponseRange)
-		}
-	}
-}
-
-func (p *kvProxy) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) {
-	op := TxnRequestToOp(r)
-	opResp, err := p.kv.Do(ctx, op)
-	if err != nil {
-		return nil, err
-	}
-	resp := opResp.Txn()
-
-	// txn may claim an outdated key is updated; be safe and invalidate
-	for _, cmp := range r.Compare {
-		p.cache.Invalidate(cmp.Key, cmp.RangeEnd)
-	}
-	// update any fetched keys
-	if resp.Succeeded {
-		p.txnToCache(r.Success, resp.Responses)
-	} else {
-		p.txnToCache(r.Failure, resp.Responses)
-	}
-
-	cacheKeys.Set(float64(p.cache.Size()))
-
-	return (*pb.TxnResponse)(resp), nil
-}
-
-func (p *kvProxy) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) {
-	var opts []clientv3.CompactOption
-	if r.Physical {
-		opts = append(opts, clientv3.WithCompactPhysical())
-	}
-
-	resp, err := p.kv.Compact(ctx, r.Revision, opts...)
-	if err == nil {
-		p.cache.Compact(r.Revision)
-	}
-
-	cacheKeys.Set(float64(p.cache.Size()))
-
-	return (*pb.CompactionResponse)(resp), err
-}
-
-func requestOpToOp(union *pb.RequestOp) clientv3.Op {
-	switch tv := union.Request.(type) {
-	case *pb.RequestOp_RequestRange:
-		if tv.RequestRange != nil {
-			return RangeRequestToOp(tv.RequestRange)
-		}
-	case *pb.RequestOp_RequestPut:
-		if tv.RequestPut != nil {
-			return PutRequestToOp(tv.RequestPut)
-		}
-	case *pb.RequestOp_RequestDeleteRange:
-		if tv.RequestDeleteRange != nil {
-			return DelRequestToOp(tv.RequestDeleteRange)
-		}
-	case *pb.RequestOp_RequestTxn:
-		if tv.RequestTxn != nil {
-			return TxnRequestToOp(tv.RequestTxn)
-		}
-	}
-	panic("unknown request")
-}
-
-func RangeRequestToOp(r *pb.RangeRequest) clientv3.Op {
-	opts := []clientv3.OpOption{}
-	if len(r.RangeEnd) != 0 {
-		opts = append(opts, clientv3.WithRange(string(r.RangeEnd)))
-	}
-	opts = append(opts, clientv3.WithRev(r.Revision))
-	opts = append(opts, clientv3.WithLimit(r.Limit))
-	opts = append(opts, clientv3.WithSort(
-		clientv3.SortTarget(r.SortTarget),
-		clientv3.SortOrder(r.SortOrder)),
-	)
-	opts = append(opts, clientv3.WithMaxCreateRev(r.MaxCreateRevision))
-	opts = append(opts, clientv3.WithMinCreateRev(r.MinCreateRevision))
-	opts = append(opts, clientv3.WithMaxModRev(r.MaxModRevision))
-	opts = append(opts, clientv3.WithMinModRev(r.MinModRevision))
-	if r.CountOnly {
-		opts = append(opts, clientv3.WithCountOnly())
-	}
-	if r.KeysOnly {
-		opts = append(opts, clientv3.WithKeysOnly())
-	}
-	if r.Serializable {
-		opts = append(opts, clientv3.WithSerializable())
-	}
-
-	return clientv3.OpGet(string(r.Key), opts...)
-}
-
-func PutRequestToOp(r *pb.PutRequest) clientv3.Op {
-	opts := []clientv3.OpOption{}
-	opts = append(opts, clientv3.WithLease(clientv3.LeaseID(r.Lease)))
-	if r.IgnoreValue {
-		opts = append(opts, clientv3.WithIgnoreValue())
-	}
-	if r.IgnoreLease {
-		opts = append(opts, clientv3.WithIgnoreLease())
-	}
-	if r.PrevKv {
-		opts = append(opts, clientv3.WithPrevKV())
-	}
-	return clientv3.OpPut(string(r.Key), string(r.Value), opts...)
-}
-
-func DelRequestToOp(r *pb.DeleteRangeRequest) clientv3.Op {
-	opts := []clientv3.OpOption{}
-	if len(r.RangeEnd) != 0 {
-		opts = append(opts, clientv3.WithRange(string(r.RangeEnd)))
-	}
-	if r.PrevKv {
-		opts = append(opts, clientv3.WithPrevKV())
-	}
-	return clientv3.OpDelete(string(r.Key), opts...)
-}
-
-func TxnRequestToOp(r *pb.TxnRequest) clientv3.Op {
-	cmps := make([]clientv3.Cmp, len(r.Compare))
-	thenops := make([]clientv3.Op, len(r.Success))
-	elseops := make([]clientv3.Op, len(r.Failure))
-	for i := range r.Compare {
-		cmps[i] = (clientv3.Cmp)(*r.Compare[i])
-	}
-	for i := range r.Success {
-		thenops[i] = requestOpToOp(r.Success[i])
-	}
-	for i := range r.Failure {
-		elseops[i] = requestOpToOp(r.Failure[i])
-	}
-	return clientv3.OpTxn(cmps, thenops, elseops)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/leader.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/leader.go
deleted file mode 100644
index 042c949..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/leader.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-	"math"
-	"sync"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-
-	"golang.org/x/time/rate"
-	"google.golang.org/grpc"
-)
-
-const (
-	lostLeaderKey  = "__lostleader" // watched to detect leader loss
-	retryPerSecond = 10
-)
-
-type leader struct {
-	ctx context.Context
-	w   clientv3.Watcher
-	// mu protects leaderc updates.
-	mu       sync.RWMutex
-	leaderc  chan struct{}
-	disconnc chan struct{}
-	donec    chan struct{}
-}
-
-func newLeader(ctx context.Context, w clientv3.Watcher) *leader {
-	l := &leader{
-		ctx:      clientv3.WithRequireLeader(ctx),
-		w:        w,
-		leaderc:  make(chan struct{}),
-		disconnc: make(chan struct{}),
-		donec:    make(chan struct{}),
-	}
-	// begin assuming leader is lost
-	close(l.leaderc)
-	go l.recvLoop()
-	return l
-}
-
-func (l *leader) recvLoop() {
-	defer close(l.donec)
-
-	limiter := rate.NewLimiter(rate.Limit(retryPerSecond), retryPerSecond)
-	rev := int64(math.MaxInt64 - 2)
-	for limiter.Wait(l.ctx) == nil {
-		wch := l.w.Watch(l.ctx, lostLeaderKey, clientv3.WithRev(rev), clientv3.WithCreatedNotify())
-		cresp, ok := <-wch
-		if !ok {
-			l.loseLeader()
-			continue
-		}
-		if cresp.Err() != nil {
-			l.loseLeader()
-			if rpctypes.ErrorDesc(cresp.Err()) == grpc.ErrClientConnClosing.Error() {
-				close(l.disconnc)
-				return
-			}
-			continue
-		}
-		l.gotLeader()
-		<-wch
-		l.loseLeader()
-	}
-}
-
-func (l *leader) loseLeader() {
-	l.mu.RLock()
-	defer l.mu.RUnlock()
-	select {
-	case <-l.leaderc:
-	default:
-		close(l.leaderc)
-	}
-}
-
-// gotLeader will force update the leadership status to having a leader.
-func (l *leader) gotLeader() {
-	l.mu.Lock()
-	defer l.mu.Unlock()
-	select {
-	case <-l.leaderc:
-		l.leaderc = make(chan struct{})
-	default:
-	}
-}
-
-func (l *leader) disconnectNotify() <-chan struct{} { return l.disconnc }
-
-func (l *leader) stopNotify() <-chan struct{} { return l.donec }
-
-// lostNotify returns a channel that is closed if there has been
-// a leader loss not yet followed by a leader reacquire.
-func (l *leader) lostNotify() <-chan struct{} {
-	l.mu.RLock()
-	defer l.mu.RUnlock()
-	return l.leaderc
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/lease.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/lease.go
deleted file mode 100644
index 65f68b0..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/lease.go
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-	"io"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/metadata"
-)
-
-type leaseProxy struct {
-	// leaseClient handles req from LeaseGrant() that requires a lease ID.
-	leaseClient pb.LeaseClient
-
-	lessor clientv3.Lease
-
-	ctx context.Context
-
-	leader *leader
-
-	// mu protects adding outstanding leaseProxyStream through wg.
-	mu sync.RWMutex
-
-	// wg waits until all outstanding leaseProxyStream quit.
-	wg sync.WaitGroup
-}
-
-func NewLeaseProxy(c *clientv3.Client) (pb.LeaseServer, <-chan struct{}) {
-	cctx, cancel := context.WithCancel(c.Ctx())
-	lp := &leaseProxy{
-		leaseClient: pb.NewLeaseClient(c.ActiveConnection()),
-		lessor:      c.Lease,
-		ctx:         cctx,
-		leader:      newLeader(c.Ctx(), c.Watcher),
-	}
-	ch := make(chan struct{})
-	go func() {
-		defer close(ch)
-		<-lp.leader.stopNotify()
-		lp.mu.Lock()
-		select {
-		case <-lp.ctx.Done():
-		case <-lp.leader.disconnectNotify():
-			cancel()
-		}
-		<-lp.ctx.Done()
-		lp.mu.Unlock()
-		lp.wg.Wait()
-	}()
-	return lp, ch
-}
-
-func (lp *leaseProxy) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	rp, err := lp.leaseClient.LeaseGrant(ctx, cr, grpc.FailFast(false))
-	if err != nil {
-		return nil, err
-	}
-	lp.leader.gotLeader()
-	return rp, nil
-}
-
-func (lp *leaseProxy) LeaseRevoke(ctx context.Context, rr *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	r, err := lp.lessor.Revoke(ctx, clientv3.LeaseID(rr.ID))
-	if err != nil {
-		return nil, err
-	}
-	lp.leader.gotLeader()
-	return (*pb.LeaseRevokeResponse)(r), nil
-}
-
-func (lp *leaseProxy) LeaseTimeToLive(ctx context.Context, rr *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) {
-	var (
-		r   *clientv3.LeaseTimeToLiveResponse
-		err error
-	)
-	if rr.Keys {
-		r, err = lp.lessor.TimeToLive(ctx, clientv3.LeaseID(rr.ID), clientv3.WithAttachedKeys())
-	} else {
-		r, err = lp.lessor.TimeToLive(ctx, clientv3.LeaseID(rr.ID))
-	}
-	if err != nil {
-		return nil, err
-	}
-	rp := &pb.LeaseTimeToLiveResponse{
-		Header:     r.ResponseHeader,
-		ID:         int64(r.ID),
-		TTL:        r.TTL,
-		GrantedTTL: r.GrantedTTL,
-		Keys:       r.Keys,
-	}
-	return rp, err
-}
-
-func (lp *leaseProxy) LeaseLeases(ctx context.Context, rr *pb.LeaseLeasesRequest) (*pb.LeaseLeasesResponse, error) {
-	r, err := lp.lessor.Leases(ctx)
-	if err != nil {
-		return nil, err
-	}
-	leases := make([]*pb.LeaseStatus, len(r.Leases))
-	for i := range r.Leases {
-		leases[i] = &pb.LeaseStatus{ID: int64(r.Leases[i].ID)}
-	}
-	rp := &pb.LeaseLeasesResponse{
-		Header: r.ResponseHeader,
-		Leases: leases,
-	}
-	return rp, err
-}
-
-func (lp *leaseProxy) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) error {
-	lp.mu.Lock()
-	select {
-	case <-lp.ctx.Done():
-		lp.mu.Unlock()
-		return lp.ctx.Err()
-	default:
-		lp.wg.Add(1)
-	}
-	lp.mu.Unlock()
-
-	ctx, cancel := context.WithCancel(stream.Context())
-	lps := leaseProxyStream{
-		stream:          stream,
-		lessor:          lp.lessor,
-		keepAliveLeases: make(map[int64]*atomicCounter),
-		respc:           make(chan *pb.LeaseKeepAliveResponse),
-		ctx:             ctx,
-		cancel:          cancel,
-	}
-
-	errc := make(chan error, 2)
-
-	var lostLeaderC <-chan struct{}
-	if md, ok := metadata.FromOutgoingContext(stream.Context()); ok {
-		v := md[rpctypes.MetadataRequireLeaderKey]
-		if len(v) > 0 && v[0] == rpctypes.MetadataHasLeader {
-			lostLeaderC = lp.leader.lostNotify()
-			// if leader is known to be lost at creation time, avoid
-			// letting events through at all
-			select {
-			case <-lostLeaderC:
-				lp.wg.Done()
-				return rpctypes.ErrNoLeader
-			default:
-			}
-		}
-	}
-	stopc := make(chan struct{}, 3)
-	go func() {
-		defer func() { stopc <- struct{}{} }()
-		if err := lps.recvLoop(); err != nil {
-			errc <- err
-		}
-	}()
-
-	go func() {
-		defer func() { stopc <- struct{}{} }()
-		if err := lps.sendLoop(); err != nil {
-			errc <- err
-		}
-	}()
-
-	// tears down LeaseKeepAlive stream if leader goes down or entire leaseProxy is terminated.
-	go func() {
-		defer func() { stopc <- struct{}{} }()
-		select {
-		case <-lostLeaderC:
-		case <-ctx.Done():
-		case <-lp.ctx.Done():
-		}
-	}()
-
-	var err error
-	select {
-	case <-stopc:
-		stopc <- struct{}{}
-	case err = <-errc:
-	}
-	cancel()
-
-	// recv/send may only shutdown after function exits;
-	// this goroutine notifies lease proxy that the stream is through
-	go func() {
-		<-stopc
-		<-stopc
-		<-stopc
-		lps.close()
-		close(errc)
-		lp.wg.Done()
-	}()
-
-	select {
-	case <-lostLeaderC:
-		return rpctypes.ErrNoLeader
-	case <-lp.leader.disconnectNotify():
-		return grpc.ErrClientConnClosing
-	default:
-		if err != nil {
-			return err
-		}
-		return ctx.Err()
-	}
-}
-
-type leaseProxyStream struct {
-	stream pb.Lease_LeaseKeepAliveServer
-
-	lessor clientv3.Lease
-	// wg tracks keepAliveLoop goroutines
-	wg sync.WaitGroup
-	// mu protects keepAliveLeases
-	mu sync.RWMutex
-	// keepAliveLeases tracks how many outstanding keepalive requests which need responses are on a lease.
-	keepAliveLeases map[int64]*atomicCounter
-	// respc receives lease keepalive responses from etcd backend
-	respc chan *pb.LeaseKeepAliveResponse
-
-	ctx    context.Context
-	cancel context.CancelFunc
-}
-
-func (lps *leaseProxyStream) recvLoop() error {
-	for {
-		rr, err := lps.stream.Recv()
-		if err == io.EOF {
-			return nil
-		}
-		if err != nil {
-			return err
-		}
-		lps.mu.Lock()
-		neededResps, ok := lps.keepAliveLeases[rr.ID]
-		if !ok {
-			neededResps = &atomicCounter{}
-			lps.keepAliveLeases[rr.ID] = neededResps
-			lps.wg.Add(1)
-			go func() {
-				defer lps.wg.Done()
-				if err := lps.keepAliveLoop(rr.ID, neededResps); err != nil {
-					lps.cancel()
-				}
-			}()
-		}
-		neededResps.add(1)
-		lps.mu.Unlock()
-	}
-}
-
-func (lps *leaseProxyStream) keepAliveLoop(leaseID int64, neededResps *atomicCounter) error {
-	cctx, ccancel := context.WithCancel(lps.ctx)
-	defer ccancel()
-	respc, err := lps.lessor.KeepAlive(cctx, clientv3.LeaseID(leaseID))
-	if err != nil {
-		return err
-	}
-	// ticker expires when loop hasn't received keepalive within TTL
-	var ticker <-chan time.Time
-	for {
-		select {
-		case <-ticker:
-			lps.mu.Lock()
-			// if there are outstanding keepAlive reqs at the moment of ticker firing,
-			// don't close keepAliveLoop(), let it continuing to process the KeepAlive reqs.
-			if neededResps.get() > 0 {
-				lps.mu.Unlock()
-				ticker = nil
-				continue
-			}
-			delete(lps.keepAliveLeases, leaseID)
-			lps.mu.Unlock()
-			return nil
-		case rp, ok := <-respc:
-			if !ok {
-				lps.mu.Lock()
-				delete(lps.keepAliveLeases, leaseID)
-				lps.mu.Unlock()
-				if neededResps.get() == 0 {
-					return nil
-				}
-				ttlResp, err := lps.lessor.TimeToLive(cctx, clientv3.LeaseID(leaseID))
-				if err != nil {
-					return err
-				}
-				r := &pb.LeaseKeepAliveResponse{
-					Header: ttlResp.ResponseHeader,
-					ID:     int64(ttlResp.ID),
-					TTL:    ttlResp.TTL,
-				}
-				for neededResps.get() > 0 {
-					select {
-					case lps.respc <- r:
-						neededResps.add(-1)
-					case <-lps.ctx.Done():
-						return nil
-					}
-				}
-				return nil
-			}
-			if neededResps.get() == 0 {
-				continue
-			}
-			ticker = time.After(time.Duration(rp.TTL) * time.Second)
-			r := &pb.LeaseKeepAliveResponse{
-				Header: rp.ResponseHeader,
-				ID:     int64(rp.ID),
-				TTL:    rp.TTL,
-			}
-			lps.replyToClient(r, neededResps)
-		}
-	}
-}
-
-func (lps *leaseProxyStream) replyToClient(r *pb.LeaseKeepAliveResponse, neededResps *atomicCounter) {
-	timer := time.After(500 * time.Millisecond)
-	for neededResps.get() > 0 {
-		select {
-		case lps.respc <- r:
-			neededResps.add(-1)
-		case <-timer:
-			return
-		case <-lps.ctx.Done():
-			return
-		}
-	}
-}
-
-func (lps *leaseProxyStream) sendLoop() error {
-	for {
-		select {
-		case lrp, ok := <-lps.respc:
-			if !ok {
-				return nil
-			}
-			if err := lps.stream.Send(lrp); err != nil {
-				return err
-			}
-		case <-lps.ctx.Done():
-			return lps.ctx.Err()
-		}
-	}
-}
-
-func (lps *leaseProxyStream) close() {
-	lps.cancel()
-	lps.wg.Wait()
-	// only close respc channel if all the keepAliveLoop() goroutines have finished
-	// this ensures those goroutines don't send resp to a closed resp channel
-	close(lps.respc)
-}
-
-type atomicCounter struct {
-	counter int64
-}
-
-func (ac *atomicCounter) add(delta int64) {
-	atomic.AddInt64(&ac.counter, delta)
-}
-
-func (ac *atomicCounter) get() int64 {
-	return atomic.LoadInt64(&ac.counter)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/lock.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/lock.go
deleted file mode 100644
index ceef26f..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/lock.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The etcd Lockors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb"
-)
-
-type lockProxy struct {
-	client *clientv3.Client
-}
-
-func NewLockProxy(client *clientv3.Client) v3lockpb.LockServer {
-	return &lockProxy{client: client}
-}
-
-func (lp *lockProxy) Lock(ctx context.Context, req *v3lockpb.LockRequest) (*v3lockpb.LockResponse, error) {
-	return v3lockpb.NewLockClient(lp.client.ActiveConnection()).Lock(ctx, req)
-}
-
-func (lp *lockProxy) Unlock(ctx context.Context, req *v3lockpb.UnlockRequest) (*v3lockpb.UnlockResponse, error) {
-	return v3lockpb.NewLockClient(lp.client.ActiveConnection()).Unlock(ctx, req)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/logger.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/logger.go
deleted file mode 100644
index c2d8180..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/logger.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import "github.com/coreos/pkg/capnslog"
-
-var plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "grpcproxy")
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/maintenance.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/maintenance.go
deleted file mode 100644
index 291e8e3..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/maintenance.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-	"io"
-
-	"github.com/coreos/etcd/clientv3"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-type maintenanceProxy struct {
-	client *clientv3.Client
-}
-
-func NewMaintenanceProxy(c *clientv3.Client) pb.MaintenanceServer {
-	return &maintenanceProxy{
-		client: c,
-	}
-}
-
-func (mp *maintenanceProxy) Defragment(ctx context.Context, dr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) {
-	conn := mp.client.ActiveConnection()
-	return pb.NewMaintenanceClient(conn).Defragment(ctx, dr)
-}
-
-func (mp *maintenanceProxy) Snapshot(sr *pb.SnapshotRequest, stream pb.Maintenance_SnapshotServer) error {
-	conn := mp.client.ActiveConnection()
-	ctx, cancel := context.WithCancel(stream.Context())
-	defer cancel()
-
-	ctx = withClientAuthToken(ctx, stream.Context())
-
-	sc, err := pb.NewMaintenanceClient(conn).Snapshot(ctx, sr)
-	if err != nil {
-		return err
-	}
-
-	for {
-		rr, err := sc.Recv()
-		if err != nil {
-			if err == io.EOF {
-				return nil
-			}
-			return err
-		}
-		err = stream.Send(rr)
-		if err != nil {
-			return err
-		}
-	}
-}
-
-func (mp *maintenanceProxy) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) {
-	conn := mp.client.ActiveConnection()
-	return pb.NewMaintenanceClient(conn).Hash(ctx, r)
-}
-
-func (mp *maintenanceProxy) HashKV(ctx context.Context, r *pb.HashKVRequest) (*pb.HashKVResponse, error) {
-	conn := mp.client.ActiveConnection()
-	return pb.NewMaintenanceClient(conn).HashKV(ctx, r)
-}
-
-func (mp *maintenanceProxy) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb.AlarmResponse, error) {
-	conn := mp.client.ActiveConnection()
-	return pb.NewMaintenanceClient(conn).Alarm(ctx, r)
-}
-
-func (mp *maintenanceProxy) Status(ctx context.Context, r *pb.StatusRequest) (*pb.StatusResponse, error) {
-	conn := mp.client.ActiveConnection()
-	return pb.NewMaintenanceClient(conn).Status(ctx, r)
-}
-
-func (mp *maintenanceProxy) MoveLeader(ctx context.Context, r *pb.MoveLeaderRequest) (*pb.MoveLeaderResponse, error) {
-	conn := mp.client.ActiveConnection()
-	return pb.NewMaintenanceClient(conn).MoveLeader(ctx, r)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/metrics.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/metrics.go
deleted file mode 100644
index 864fa16..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/metrics.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	watchersCoalescing = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "grpc_proxy",
-		Name:      "watchers_coalescing_total",
-		Help:      "Total number of current watchers coalescing",
-	})
-	eventsCoalescing = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "grpc_proxy",
-		Name:      "events_coalescing_total",
-		Help:      "Total number of events coalescing",
-	})
-	cacheKeys = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "grpc_proxy",
-		Name:      "cache_keys_total",
-		Help:      "Total number of keys/ranges cached",
-	})
-	cacheHits = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "grpc_proxy",
-		Name:      "cache_hits_total",
-		Help:      "Total number of cache hits",
-	})
-	cachedMisses = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "grpc_proxy",
-		Name:      "cache_misses_total",
-		Help:      "Total number of cache misses",
-	})
-)
-
-func init() {
-	prometheus.MustRegister(watchersCoalescing)
-	prometheus.MustRegister(eventsCoalescing)
-	prometheus.MustRegister(cacheKeys)
-	prometheus.MustRegister(cacheHits)
-	prometheus.MustRegister(cachedMisses)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/register.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/register.go
deleted file mode 100644
index 598c71f..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/register.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"encoding/json"
-	"os"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/clientv3/concurrency"
-	"github.com/coreos/etcd/clientv3/naming"
-
-	"golang.org/x/time/rate"
-	gnaming "google.golang.org/grpc/naming"
-)
-
-// allow maximum 1 retry per second
-const registerRetryRate = 1
-
-// Register registers itself as a grpc-proxy server by writing prefixed-key
-// with session of specified TTL (in seconds). The returned channel is closed
-// when the client's context is canceled.
-func Register(c *clientv3.Client, prefix string, addr string, ttl int) <-chan struct{} {
-	rm := rate.NewLimiter(rate.Limit(registerRetryRate), registerRetryRate)
-
-	donec := make(chan struct{})
-	go func() {
-		defer close(donec)
-
-		for rm.Wait(c.Ctx()) == nil {
-			ss, err := registerSession(c, prefix, addr, ttl)
-			if err != nil {
-				plog.Warningf("failed to create a session %v", err)
-				continue
-			}
-			select {
-			case <-c.Ctx().Done():
-				ss.Close()
-				return
-
-			case <-ss.Done():
-				plog.Warning("session expired; possible network partition or server restart")
-				plog.Warning("creating a new session to rejoin")
-				continue
-			}
-		}
-	}()
-
-	return donec
-}
-
-func registerSession(c *clientv3.Client, prefix string, addr string, ttl int) (*concurrency.Session, error) {
-	ss, err := concurrency.NewSession(c, concurrency.WithTTL(ttl))
-	if err != nil {
-		return nil, err
-	}
-
-	gr := &naming.GRPCResolver{Client: c}
-	if err = gr.Update(c.Ctx(), prefix, gnaming.Update{Op: gnaming.Add, Addr: addr, Metadata: getMeta()}, clientv3.WithLease(ss.Lease())); err != nil {
-		return nil, err
-	}
-
-	plog.Infof("registered %q with %d-second lease", addr, ttl)
-	return ss, nil
-}
-
-// meta represents metadata of proxy register.
-type meta struct {
-	Name string `json:"name"`
-}
-
-func getMeta() string {
-	hostname, _ := os.Hostname()
-	bts, _ := json.Marshal(meta{Name: hostname})
-	return string(bts)
-}
-
-func decodeMeta(s string) (meta, error) {
-	m := meta{}
-	err := json.Unmarshal([]byte(s), &m)
-	return m, err
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/util.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/util.go
deleted file mode 100644
index 2b226fa..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/util.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2017 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/metadata"
-)
-
-func getAuthTokenFromClient(ctx context.Context) string {
-	md, ok := metadata.FromIncomingContext(ctx)
-	if ok {
-		ts, ok := md["token"]
-		if ok {
-			return ts[0]
-		}
-	}
-	return ""
-}
-
-func withClientAuthToken(ctx context.Context, ctxWithToken context.Context) context.Context {
-	token := getAuthTokenFromClient(ctxWithToken)
-	if token != "" {
-		ctx = context.WithValue(ctx, "token", token)
-	}
-	return ctx
-}
-
-type proxyTokenCredential struct {
-	token string
-}
-
-func (cred *proxyTokenCredential) RequireTransportSecurity() bool {
-	return false
-}
-
-func (cred *proxyTokenCredential) GetRequestMetadata(ctx context.Context, s ...string) (map[string]string, error) {
-	return map[string]string{
-		"token": cred.token,
-	}, nil
-}
-
-func AuthUnaryClientInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
-	token := getAuthTokenFromClient(ctx)
-	if token != "" {
-		tokenCred := &proxyTokenCredential{token}
-		opts = append(opts, grpc.PerRPCCredentials(tokenCred))
-	}
-	return invoker(ctx, method, req, reply, cc, opts...)
-}
-
-func AuthStreamClientInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
-	tokenif := ctx.Value("token")
-	if tokenif != nil {
-		tokenCred := &proxyTokenCredential{tokenif.(string)}
-		opts = append(opts, grpc.PerRPCCredentials(tokenCred))
-	}
-	return streamer(ctx, desc, cc, method, opts...)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch.go
deleted file mode 100644
index 603095f..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch.go
+++ /dev/null
@@ -1,298 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-	"sync"
-
-	"github.com/coreos/etcd/clientv3"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc"
-	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/metadata"
-)
-
-type watchProxy struct {
-	cw  clientv3.Watcher
-	ctx context.Context
-
-	leader *leader
-
-	ranges *watchRanges
-
-	// mu protects adding outstanding watch servers through wg.
-	mu sync.Mutex
-
-	// wg waits until all outstanding watch servers quit.
-	wg sync.WaitGroup
-
-	// kv is used for permission checking
-	kv clientv3.KV
-}
-
-func NewWatchProxy(c *clientv3.Client) (pb.WatchServer, <-chan struct{}) {
-	cctx, cancel := context.WithCancel(c.Ctx())
-	wp := &watchProxy{
-		cw:     c.Watcher,
-		ctx:    cctx,
-		leader: newLeader(c.Ctx(), c.Watcher),
-
-		kv: c.KV, // for permission checking
-	}
-	wp.ranges = newWatchRanges(wp)
-	ch := make(chan struct{})
-	go func() {
-		defer close(ch)
-		<-wp.leader.stopNotify()
-		wp.mu.Lock()
-		select {
-		case <-wp.ctx.Done():
-		case <-wp.leader.disconnectNotify():
-			cancel()
-		}
-		<-wp.ctx.Done()
-		wp.mu.Unlock()
-		wp.wg.Wait()
-		wp.ranges.stop()
-	}()
-	return wp, ch
-}
-
-func (wp *watchProxy) Watch(stream pb.Watch_WatchServer) (err error) {
-	wp.mu.Lock()
-	select {
-	case <-wp.ctx.Done():
-		wp.mu.Unlock()
-		select {
-		case <-wp.leader.disconnectNotify():
-			return grpc.ErrClientConnClosing
-		default:
-			return wp.ctx.Err()
-		}
-	default:
-		wp.wg.Add(1)
-	}
-	wp.mu.Unlock()
-
-	ctx, cancel := context.WithCancel(stream.Context())
-	wps := &watchProxyStream{
-		ranges:   wp.ranges,
-		watchers: make(map[int64]*watcher),
-		stream:   stream,
-		watchCh:  make(chan *pb.WatchResponse, 1024),
-		ctx:      ctx,
-		cancel:   cancel,
-		kv:       wp.kv,
-	}
-
-	var lostLeaderC <-chan struct{}
-	if md, ok := metadata.FromOutgoingContext(stream.Context()); ok {
-		v := md[rpctypes.MetadataRequireLeaderKey]
-		if len(v) > 0 && v[0] == rpctypes.MetadataHasLeader {
-			lostLeaderC = wp.leader.lostNotify()
-			// if leader is known to be lost at creation time, avoid
-			// letting events through at all
-			select {
-			case <-lostLeaderC:
-				wp.wg.Done()
-				return rpctypes.ErrNoLeader
-			default:
-			}
-		}
-	}
-
-	// post to stopc => terminate server stream; can't use a waitgroup
-	// since all goroutines will only terminate after Watch() exits.
-	stopc := make(chan struct{}, 3)
-	go func() {
-		defer func() { stopc <- struct{}{} }()
-		wps.recvLoop()
-	}()
-	go func() {
-		defer func() { stopc <- struct{}{} }()
-		wps.sendLoop()
-	}()
-	// tear down watch if leader goes down or entire watch proxy is terminated
-	go func() {
-		defer func() { stopc <- struct{}{} }()
-		select {
-		case <-lostLeaderC:
-		case <-ctx.Done():
-		case <-wp.ctx.Done():
-		}
-	}()
-
-	<-stopc
-	cancel()
-
-	// recv/send may only shutdown after function exits;
-	// goroutine notifies proxy that stream is through
-	go func() {
-		<-stopc
-		<-stopc
-		wps.close()
-		wp.wg.Done()
-	}()
-
-	select {
-	case <-lostLeaderC:
-		return rpctypes.ErrNoLeader
-	case <-wp.leader.disconnectNotify():
-		return grpc.ErrClientConnClosing
-	default:
-		return wps.ctx.Err()
-	}
-}
-
-// watchProxyStream forwards etcd watch events to a proxied client stream.
-type watchProxyStream struct {
-	ranges *watchRanges
-
-	// mu protects watchers and nextWatcherID
-	mu sync.Mutex
-	// watchers receive events from watch broadcast.
-	watchers map[int64]*watcher
-	// nextWatcherID is the id to assign the next watcher on this stream.
-	nextWatcherID int64
-
-	stream pb.Watch_WatchServer
-
-	// watchCh receives watch responses from the watchers.
-	watchCh chan *pb.WatchResponse
-
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	// kv is used for permission checking
-	kv clientv3.KV
-}
-
-func (wps *watchProxyStream) close() {
-	var wg sync.WaitGroup
-	wps.cancel()
-	wps.mu.Lock()
-	wg.Add(len(wps.watchers))
-	for _, wpsw := range wps.watchers {
-		go func(w *watcher) {
-			wps.ranges.delete(w)
-			wg.Done()
-		}(wpsw)
-	}
-	wps.watchers = nil
-	wps.mu.Unlock()
-
-	wg.Wait()
-
-	close(wps.watchCh)
-}
-
-func (wps *watchProxyStream) checkPermissionForWatch(key, rangeEnd []byte) error {
-	if len(key) == 0 {
-		// If the length of the key is 0, we need to obtain full range.
-		// look at clientv3.WithPrefix()
-		key = []byte{0}
-		rangeEnd = []byte{0}
-	}
-	req := &pb.RangeRequest{
-		Serializable: true,
-		Key:          key,
-		RangeEnd:     rangeEnd,
-		CountOnly:    true,
-		Limit:        1,
-	}
-	_, err := wps.kv.Do(wps.ctx, RangeRequestToOp(req))
-	return err
-}
-
-func (wps *watchProxyStream) recvLoop() error {
-	for {
-		req, err := wps.stream.Recv()
-		if err != nil {
-			return err
-		}
-		switch uv := req.RequestUnion.(type) {
-		case *pb.WatchRequest_CreateRequest:
-			cr := uv.CreateRequest
-
-			if err = wps.checkPermissionForWatch(cr.Key, cr.RangeEnd); err != nil && err == rpctypes.ErrPermissionDenied {
-				// Return WatchResponse which is caused by permission checking if and only if
-				// the error is permission denied. For other errors (e.g. timeout or connection closed),
-				// the permission checking mechanism should do nothing for preserving error code.
-				wps.watchCh <- &pb.WatchResponse{Header: &pb.ResponseHeader{}, WatchId: -1, Created: true, Canceled: true}
-				continue
-			}
-
-			w := &watcher{
-				wr:  watchRange{string(cr.Key), string(cr.RangeEnd)},
-				id:  wps.nextWatcherID,
-				wps: wps,
-
-				nextrev:  cr.StartRevision,
-				progress: cr.ProgressNotify,
-				prevKV:   cr.PrevKv,
-				filters:  v3rpc.FiltersFromRequest(cr),
-			}
-			if !w.wr.valid() {
-				w.post(&pb.WatchResponse{WatchId: -1, Created: true, Canceled: true})
-				continue
-			}
-			wps.nextWatcherID++
-			w.nextrev = cr.StartRevision
-			wps.watchers[w.id] = w
-			wps.ranges.add(w)
-		case *pb.WatchRequest_CancelRequest:
-			wps.delete(uv.CancelRequest.WatchId)
-		default:
-			panic("not implemented")
-		}
-	}
-}
-
-func (wps *watchProxyStream) sendLoop() {
-	for {
-		select {
-		case wresp, ok := <-wps.watchCh:
-			if !ok {
-				return
-			}
-			if err := wps.stream.Send(wresp); err != nil {
-				return
-			}
-		case <-wps.ctx.Done():
-			return
-		}
-	}
-}
-
-func (wps *watchProxyStream) delete(id int64) {
-	wps.mu.Lock()
-	defer wps.mu.Unlock()
-
-	w, ok := wps.watchers[id]
-	if !ok {
-		return
-	}
-	wps.ranges.delete(w)
-	delete(wps.watchers, id)
-	resp := &pb.WatchResponse{
-		Header:   &w.lastHeader,
-		WatchId:  id,
-		Canceled: true,
-	}
-	wps.watchCh <- resp
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcast.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcast.go
deleted file mode 100644
index 46e56c7..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcast.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"context"
-	"sync"
-
-	"github.com/coreos/etcd/clientv3"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-)
-
-// watchBroadcast broadcasts a server watcher to many client watchers.
-type watchBroadcast struct {
-	// cancel stops the underlying etcd server watcher and closes ch.
-	cancel context.CancelFunc
-	donec  chan struct{}
-
-	// mu protects rev and receivers.
-	mu sync.RWMutex
-	// nextrev is the minimum expected next revision of the watcher on ch.
-	nextrev int64
-	// receivers contains all the client-side watchers to serve.
-	receivers map[*watcher]struct{}
-	// responses counts the number of responses
-	responses int
-}
-
-func newWatchBroadcast(wp *watchProxy, w *watcher, update func(*watchBroadcast)) *watchBroadcast {
-	cctx, cancel := context.WithCancel(wp.ctx)
-	wb := &watchBroadcast{
-		cancel:    cancel,
-		nextrev:   w.nextrev,
-		receivers: make(map[*watcher]struct{}),
-		donec:     make(chan struct{}),
-	}
-	wb.add(w)
-	go func() {
-		defer close(wb.donec)
-
-		opts := []clientv3.OpOption{
-			clientv3.WithRange(w.wr.end),
-			clientv3.WithProgressNotify(),
-			clientv3.WithRev(wb.nextrev),
-			clientv3.WithPrevKV(),
-			clientv3.WithCreatedNotify(),
-		}
-
-		cctx = withClientAuthToken(cctx, w.wps.stream.Context())
-
-		wch := wp.cw.Watch(cctx, w.wr.key, opts...)
-
-		for wr := range wch {
-			wb.bcast(wr)
-			update(wb)
-		}
-	}()
-	return wb
-}
-
-func (wb *watchBroadcast) bcast(wr clientv3.WatchResponse) {
-	wb.mu.Lock()
-	defer wb.mu.Unlock()
-	// watchers start on the given revision, if any; ignore header rev on create
-	if wb.responses > 0 || wb.nextrev == 0 {
-		wb.nextrev = wr.Header.Revision + 1
-	}
-	wb.responses++
-	for r := range wb.receivers {
-		r.send(wr)
-	}
-	if len(wb.receivers) > 0 {
-		eventsCoalescing.Add(float64(len(wb.receivers) - 1))
-	}
-}
-
-// add puts a watcher into receiving a broadcast if its revision at least
-// meets the broadcast revision. Returns true if added.
-func (wb *watchBroadcast) add(w *watcher) bool {
-	wb.mu.Lock()
-	defer wb.mu.Unlock()
-	if wb.nextrev > w.nextrev || (wb.nextrev == 0 && w.nextrev != 0) {
-		// wb is too far ahead, w will miss events
-		// or wb is being established with a current watcher
-		return false
-	}
-	if wb.responses == 0 {
-		// Newly created; create event will be sent by etcd.
-		wb.receivers[w] = struct{}{}
-		return true
-	}
-	// already sent by etcd; emulate create event
-	ok := w.post(&pb.WatchResponse{
-		Header: &pb.ResponseHeader{
-			// todo: fill in ClusterId
-			// todo: fill in MemberId:
-			Revision: w.nextrev,
-			// todo: fill in RaftTerm:
-		},
-		WatchId: w.id,
-		Created: true,
-	})
-	if !ok {
-		return false
-	}
-	wb.receivers[w] = struct{}{}
-	watchersCoalescing.Inc()
-
-	return true
-}
-func (wb *watchBroadcast) delete(w *watcher) {
-	wb.mu.Lock()
-	defer wb.mu.Unlock()
-	if _, ok := wb.receivers[w]; !ok {
-		panic("deleting missing watcher from broadcast")
-	}
-	delete(wb.receivers, w)
-	if len(wb.receivers) > 0 {
-		// do not dec the only left watcher for coalescing.
-		watchersCoalescing.Dec()
-	}
-}
-
-func (wb *watchBroadcast) size() int {
-	wb.mu.RLock()
-	defer wb.mu.RUnlock()
-	return len(wb.receivers)
-}
-
-func (wb *watchBroadcast) empty() bool { return wb.size() == 0 }
-
-func (wb *watchBroadcast) stop() {
-	if !wb.empty() {
-		// do not dec the only left watcher for coalescing.
-		watchersCoalescing.Sub(float64(wb.size() - 1))
-	}
-
-	wb.cancel()
-	<-wb.donec
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcasts.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcasts.go
deleted file mode 100644
index 8fe9e5f..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_broadcasts.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"sync"
-)
-
-type watchBroadcasts struct {
-	wp *watchProxy
-
-	// mu protects bcasts and watchers from the coalesce loop.
-	mu       sync.Mutex
-	bcasts   map[*watchBroadcast]struct{}
-	watchers map[*watcher]*watchBroadcast
-
-	updatec chan *watchBroadcast
-	donec   chan struct{}
-}
-
-// maxCoalesceRecievers prevents a popular watchBroadcast from being coalseced.
-const maxCoalesceReceivers = 5
-
-func newWatchBroadcasts(wp *watchProxy) *watchBroadcasts {
-	wbs := &watchBroadcasts{
-		wp:       wp,
-		bcasts:   make(map[*watchBroadcast]struct{}),
-		watchers: make(map[*watcher]*watchBroadcast),
-		updatec:  make(chan *watchBroadcast, 1),
-		donec:    make(chan struct{}),
-	}
-	go func() {
-		defer close(wbs.donec)
-		for wb := range wbs.updatec {
-			wbs.coalesce(wb)
-		}
-	}()
-	return wbs
-}
-
-func (wbs *watchBroadcasts) coalesce(wb *watchBroadcast) {
-	if wb.size() >= maxCoalesceReceivers {
-		return
-	}
-	wbs.mu.Lock()
-	for wbswb := range wbs.bcasts {
-		if wbswb == wb {
-			continue
-		}
-		wb.mu.Lock()
-		wbswb.mu.Lock()
-		// 1. check if wbswb is behind wb so it won't skip any events in wb
-		// 2. ensure wbswb started; nextrev == 0 may mean wbswb is waiting
-		// for a current watcher and expects a create event from the server.
-		if wb.nextrev >= wbswb.nextrev && wbswb.responses > 0 {
-			for w := range wb.receivers {
-				wbswb.receivers[w] = struct{}{}
-				wbs.watchers[w] = wbswb
-			}
-			wb.receivers = nil
-		}
-		wbswb.mu.Unlock()
-		wb.mu.Unlock()
-		if wb.empty() {
-			delete(wbs.bcasts, wb)
-			wb.stop()
-			break
-		}
-	}
-	wbs.mu.Unlock()
-}
-
-func (wbs *watchBroadcasts) add(w *watcher) {
-	wbs.mu.Lock()
-	defer wbs.mu.Unlock()
-	// find fitting bcast
-	for wb := range wbs.bcasts {
-		if wb.add(w) {
-			wbs.watchers[w] = wb
-			return
-		}
-	}
-	// no fit; create a bcast
-	wb := newWatchBroadcast(wbs.wp, w, wbs.update)
-	wbs.watchers[w] = wb
-	wbs.bcasts[wb] = struct{}{}
-}
-
-// delete removes a watcher and returns the number of remaining watchers.
-func (wbs *watchBroadcasts) delete(w *watcher) int {
-	wbs.mu.Lock()
-	defer wbs.mu.Unlock()
-
-	wb, ok := wbs.watchers[w]
-	if !ok {
-		panic("deleting missing watcher from broadcasts")
-	}
-	delete(wbs.watchers, w)
-	wb.delete(w)
-	if wb.empty() {
-		delete(wbs.bcasts, wb)
-		wb.stop()
-	}
-	return len(wbs.bcasts)
-}
-
-func (wbs *watchBroadcasts) stop() {
-	wbs.mu.Lock()
-	for wb := range wbs.bcasts {
-		wb.stop()
-	}
-	wbs.bcasts = nil
-	close(wbs.updatec)
-	wbs.mu.Unlock()
-	<-wbs.donec
-}
-
-func (wbs *watchBroadcasts) update(wb *watchBroadcast) {
-	select {
-	case wbs.updatec <- wb:
-	default:
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_ranges.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_ranges.go
deleted file mode 100644
index 31c6b59..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watch_ranges.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"sync"
-)
-
-// watchRanges tracks all open watches for the proxy.
-type watchRanges struct {
-	wp *watchProxy
-
-	mu     sync.Mutex
-	bcasts map[watchRange]*watchBroadcasts
-}
-
-func newWatchRanges(wp *watchProxy) *watchRanges {
-	return &watchRanges{
-		wp:     wp,
-		bcasts: make(map[watchRange]*watchBroadcasts),
-	}
-}
-
-func (wrs *watchRanges) add(w *watcher) {
-	wrs.mu.Lock()
-	defer wrs.mu.Unlock()
-
-	if wbs := wrs.bcasts[w.wr]; wbs != nil {
-		wbs.add(w)
-		return
-	}
-	wbs := newWatchBroadcasts(wrs.wp)
-	wrs.bcasts[w.wr] = wbs
-	wbs.add(w)
-}
-
-func (wrs *watchRanges) delete(w *watcher) {
-	wrs.mu.Lock()
-	defer wrs.mu.Unlock()
-	wbs, ok := wrs.bcasts[w.wr]
-	if !ok {
-		panic("deleting missing range")
-	}
-	if wbs.delete(w) == 0 {
-		wbs.stop()
-		delete(wrs.bcasts, w.wr)
-	}
-}
-
-func (wrs *watchRanges) stop() {
-	wrs.mu.Lock()
-	defer wrs.mu.Unlock()
-	for _, wb := range wrs.bcasts {
-		wb.stop()
-	}
-	wrs.bcasts = nil
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watcher.go b/vendor/github.com/coreos/etcd/proxy/grpcproxy/watcher.go
deleted file mode 100644
index 1a49746..0000000
--- a/vendor/github.com/coreos/etcd/proxy/grpcproxy/watcher.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package grpcproxy
-
-import (
-	"time"
-
-	"github.com/coreos/etcd/clientv3"
-	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
-	"github.com/coreos/etcd/mvcc"
-	"github.com/coreos/etcd/mvcc/mvccpb"
-)
-
-type watchRange struct {
-	key, end string
-}
-
-func (wr *watchRange) valid() bool {
-	return len(wr.end) == 0 || wr.end > wr.key || (wr.end[0] == 0 && len(wr.end) == 1)
-}
-
-type watcher struct {
-	// user configuration
-
-	wr       watchRange
-	filters  []mvcc.FilterFunc
-	progress bool
-	prevKV   bool
-
-	// id is the id returned to the client on its watch stream.
-	id int64
-	// nextrev is the minimum expected next event revision.
-	nextrev int64
-	// lastHeader has the last header sent over the stream.
-	lastHeader pb.ResponseHeader
-
-	// wps is the parent.
-	wps *watchProxyStream
-}
-
-// send filters out repeated events by discarding revisions older
-// than the last one sent over the watch channel.
-func (w *watcher) send(wr clientv3.WatchResponse) {
-	if wr.IsProgressNotify() && !w.progress {
-		return
-	}
-	if w.nextrev > wr.Header.Revision && len(wr.Events) > 0 {
-		return
-	}
-	if w.nextrev == 0 {
-		// current watch; expect updates following this revision
-		w.nextrev = wr.Header.Revision + 1
-	}
-
-	events := make([]*mvccpb.Event, 0, len(wr.Events))
-
-	var lastRev int64
-	for i := range wr.Events {
-		ev := (*mvccpb.Event)(wr.Events[i])
-		if ev.Kv.ModRevision < w.nextrev {
-			continue
-		} else {
-			// We cannot update w.rev here.
-			// txn can have multiple events with the same rev.
-			// If w.nextrev updates here, it would skip events in the same txn.
-			lastRev = ev.Kv.ModRevision
-		}
-
-		filtered := false
-		for _, filter := range w.filters {
-			if filter(*ev) {
-				filtered = true
-				break
-			}
-		}
-		if filtered {
-			continue
-		}
-
-		if !w.prevKV {
-			evCopy := *ev
-			evCopy.PrevKv = nil
-			ev = &evCopy
-		}
-		events = append(events, ev)
-	}
-
-	if lastRev >= w.nextrev {
-		w.nextrev = lastRev + 1
-	}
-
-	// all events are filtered out?
-	if !wr.IsProgressNotify() && !wr.Created && len(events) == 0 && wr.CompactRevision == 0 {
-		return
-	}
-
-	w.lastHeader = wr.Header
-	w.post(&pb.WatchResponse{
-		Header:          &wr.Header,
-		Created:         wr.Created,
-		CompactRevision: wr.CompactRevision,
-		Canceled:        wr.Canceled,
-		WatchId:         w.id,
-		Events:          events,
-	})
-}
-
-// post puts a watch response on the watcher's proxy stream channel
-func (w *watcher) post(wr *pb.WatchResponse) bool {
-	select {
-	case w.wps.watchCh <- wr:
-	case <-time.After(50 * time.Millisecond):
-		w.wps.cancel()
-		return false
-	}
-	return true
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/httpproxy/director.go b/vendor/github.com/coreos/etcd/proxy/httpproxy/director.go
deleted file mode 100644
index d414501..0000000
--- a/vendor/github.com/coreos/etcd/proxy/httpproxy/director.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package httpproxy
-
-import (
-	"math/rand"
-	"net/url"
-	"sync"
-	"time"
-)
-
-// defaultRefreshInterval is the default proxyRefreshIntervalMs value
-// as in etcdmain/config.go.
-const defaultRefreshInterval = 30000 * time.Millisecond
-
-var once sync.Once
-
-func init() {
-	rand.Seed(time.Now().UnixNano())
-}
-
-func newDirector(urlsFunc GetProxyURLs, failureWait time.Duration, refreshInterval time.Duration) *director {
-	d := &director{
-		uf:          urlsFunc,
-		failureWait: failureWait,
-	}
-	d.refresh()
-	go func() {
-		// In order to prevent missing proxy endpoints in the first try:
-		// when given refresh interval of defaultRefreshInterval or greater
-		// and whenever there is no available proxy endpoints,
-		// give 1-second refreshInterval.
-		for {
-			es := d.endpoints()
-			ri := refreshInterval
-			if ri >= defaultRefreshInterval {
-				if len(es) == 0 {
-					ri = time.Second
-				}
-			}
-			if len(es) > 0 {
-				once.Do(func() {
-					var sl []string
-					for _, e := range es {
-						sl = append(sl, e.URL.String())
-					}
-					plog.Infof("endpoints found %q", sl)
-				})
-			}
-			time.Sleep(ri)
-			d.refresh()
-		}
-	}()
-	return d
-}
-
-type director struct {
-	sync.Mutex
-	ep          []*endpoint
-	uf          GetProxyURLs
-	failureWait time.Duration
-}
-
-func (d *director) refresh() {
-	urls := d.uf()
-	d.Lock()
-	defer d.Unlock()
-	var endpoints []*endpoint
-	for _, u := range urls {
-		uu, err := url.Parse(u)
-		if err != nil {
-			plog.Printf("upstream URL invalid: %v", err)
-			continue
-		}
-		endpoints = append(endpoints, newEndpoint(*uu, d.failureWait))
-	}
-
-	// shuffle array to avoid connections being "stuck" to a single endpoint
-	for i := range endpoints {
-		j := rand.Intn(i + 1)
-		endpoints[i], endpoints[j] = endpoints[j], endpoints[i]
-	}
-
-	d.ep = endpoints
-}
-
-func (d *director) endpoints() []*endpoint {
-	d.Lock()
-	defer d.Unlock()
-	filtered := make([]*endpoint, 0)
-	for _, ep := range d.ep {
-		if ep.Available {
-			filtered = append(filtered, ep)
-		}
-	}
-
-	return filtered
-}
-
-func newEndpoint(u url.URL, failureWait time.Duration) *endpoint {
-	ep := endpoint{
-		URL:       u,
-		Available: true,
-		failFunc:  timedUnavailabilityFunc(failureWait),
-	}
-
-	return &ep
-}
-
-type endpoint struct {
-	sync.Mutex
-
-	URL       url.URL
-	Available bool
-
-	failFunc func(ep *endpoint)
-}
-
-func (ep *endpoint) Failed() {
-	ep.Lock()
-	if !ep.Available {
-		ep.Unlock()
-		return
-	}
-
-	ep.Available = false
-	ep.Unlock()
-
-	plog.Printf("marked endpoint %s unavailable", ep.URL.String())
-
-	if ep.failFunc == nil {
-		plog.Printf("no failFunc defined, endpoint %s will be unavailable forever.", ep.URL.String())
-		return
-	}
-
-	ep.failFunc(ep)
-}
-
-func timedUnavailabilityFunc(wait time.Duration) func(*endpoint) {
-	return func(ep *endpoint) {
-		time.AfterFunc(wait, func() {
-			ep.Available = true
-			plog.Printf("marked endpoint %s available, to retest connectivity", ep.URL.String())
-		})
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/httpproxy/doc.go b/vendor/github.com/coreos/etcd/proxy/httpproxy/doc.go
deleted file mode 100644
index 7a45099..0000000
--- a/vendor/github.com/coreos/etcd/proxy/httpproxy/doc.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package httpproxy implements etcd httpproxy. The etcd proxy acts as a reverse
-// http proxy forwarding client requests to active etcd cluster members, and does
-// not participate in consensus.
-package httpproxy
diff --git a/vendor/github.com/coreos/etcd/proxy/httpproxy/metrics.go b/vendor/github.com/coreos/etcd/proxy/httpproxy/metrics.go
deleted file mode 100644
index f71258c..0000000
--- a/vendor/github.com/coreos/etcd/proxy/httpproxy/metrics.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package httpproxy
-
-import (
-	"net/http"
-	"strconv"
-	"time"
-
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-var (
-	requestsIncoming = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "proxy",
-			Name:      "requests_total",
-			Help:      "Counter requests incoming by method.",
-		}, []string{"method"})
-
-	requestsHandled = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "proxy",
-			Name:      "handled_total",
-			Help:      "Counter of requests fully handled (by authoratitave servers)",
-		}, []string{"method", "code"})
-
-	requestsDropped = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "proxy",
-			Name:      "dropped_total",
-			Help:      "Counter of requests dropped on the proxy.",
-		}, []string{"method", "proxying_error"})
-
-	requestsHandlingTime = prometheus.NewHistogramVec(
-		prometheus.HistogramOpts{
-			Namespace: "etcd",
-			Subsystem: "proxy",
-			Name:      "handling_duration_seconds",
-			Help: "Bucketed histogram of handling time of successful events (non-watches), by method " +
-				"(GET/PUT etc.).",
-			Buckets: prometheus.ExponentialBuckets(0.0005, 2, 13),
-		}, []string{"method"})
-)
-
-type forwardingError string
-
-const (
-	zeroEndpoints         forwardingError = "zero_endpoints"
-	failedSendingRequest  forwardingError = "failed_sending_request"
-	failedGettingResponse forwardingError = "failed_getting_response"
-)
-
-func init() {
-	prometheus.MustRegister(requestsIncoming)
-	prometheus.MustRegister(requestsHandled)
-	prometheus.MustRegister(requestsDropped)
-	prometheus.MustRegister(requestsHandlingTime)
-}
-
-func reportIncomingRequest(request *http.Request) {
-	requestsIncoming.WithLabelValues(request.Method).Inc()
-}
-
-func reportRequestHandled(request *http.Request, response *http.Response, startTime time.Time) {
-	method := request.Method
-	requestsHandled.WithLabelValues(method, strconv.Itoa(response.StatusCode)).Inc()
-	requestsHandlingTime.WithLabelValues(method).Observe(time.Since(startTime).Seconds())
-}
-
-func reportRequestDropped(request *http.Request, err forwardingError) {
-	requestsDropped.WithLabelValues(request.Method, string(err)).Inc()
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/httpproxy/proxy.go b/vendor/github.com/coreos/etcd/proxy/httpproxy/proxy.go
deleted file mode 100644
index 3cd3161..0000000
--- a/vendor/github.com/coreos/etcd/proxy/httpproxy/proxy.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package httpproxy
-
-import (
-	"encoding/json"
-	"net/http"
-	"strings"
-	"time"
-
-	"golang.org/x/net/http2"
-)
-
-const (
-	// DefaultMaxIdleConnsPerHost indicates the default maximum idle connection
-	// count maintained between proxy and each member. We set it to 128 to
-	// let proxy handle 128 concurrent requests in long term smoothly.
-	// If the number of concurrent requests is bigger than this value,
-	// proxy needs to create one new connection when handling each request in
-	// the delta, which is bad because the creation consumes resource and
-	// may eat up ephemeral ports.
-	DefaultMaxIdleConnsPerHost = 128
-)
-
-// GetProxyURLs is a function which should return the current set of URLs to
-// which client requests should be proxied. This function will be queried
-// periodically by the proxy Handler to refresh the set of available
-// backends.
-type GetProxyURLs func() []string
-
-// NewHandler creates a new HTTP handler, listening on the given transport,
-// which will proxy requests to an etcd cluster.
-// The handler will periodically update its view of the cluster.
-func NewHandler(t *http.Transport, urlsFunc GetProxyURLs, failureWait time.Duration, refreshInterval time.Duration) http.Handler {
-	if t.TLSClientConfig != nil {
-		// Enable http2, see Issue 5033.
-		err := http2.ConfigureTransport(t)
-		if err != nil {
-			plog.Infof("Error enabling Transport HTTP/2 support: %v", err)
-		}
-	}
-
-	p := &reverseProxy{
-		director:  newDirector(urlsFunc, failureWait, refreshInterval),
-		transport: t,
-	}
-
-	mux := http.NewServeMux()
-	mux.Handle("/", p)
-	mux.HandleFunc("/v2/config/local/proxy", p.configHandler)
-
-	return mux
-}
-
-// NewReadonlyHandler wraps the given HTTP handler to allow only GET requests
-func NewReadonlyHandler(hdlr http.Handler) http.Handler {
-	readonly := readonlyHandlerFunc(hdlr)
-	return http.HandlerFunc(readonly)
-}
-
-func readonlyHandlerFunc(next http.Handler) func(http.ResponseWriter, *http.Request) {
-	return func(w http.ResponseWriter, req *http.Request) {
-		if req.Method != "GET" {
-			w.WriteHeader(http.StatusNotImplemented)
-			return
-		}
-
-		next.ServeHTTP(w, req)
-	}
-}
-
-func (p *reverseProxy) configHandler(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-
-	eps := p.director.endpoints()
-	epstr := make([]string, len(eps))
-	for i, e := range eps {
-		epstr[i] = e.URL.String()
-	}
-
-	proxyConfig := struct {
-		Endpoints []string `json:"endpoints"`
-	}{
-		Endpoints: epstr,
-	}
-
-	json.NewEncoder(w).Encode(proxyConfig)
-}
-
-// allowMethod verifies that the given method is one of the allowed methods,
-// and if not, it writes an error to w.  A boolean is returned indicating
-// whether or not the method is allowed.
-func allowMethod(w http.ResponseWriter, m string, ms ...string) bool {
-	for _, meth := range ms {
-		if m == meth {
-			return true
-		}
-	}
-	w.Header().Set("Allow", strings.Join(ms, ","))
-	http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-	return false
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/httpproxy/reverse.go b/vendor/github.com/coreos/etcd/proxy/httpproxy/reverse.go
deleted file mode 100644
index 2ecff3a..0000000
--- a/vendor/github.com/coreos/etcd/proxy/httpproxy/reverse.go
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package httpproxy
-
-import (
-	"bytes"
-	"context"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net"
-	"net/http"
-	"net/url"
-	"strings"
-	"sync/atomic"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "proxy/httpproxy")
-
-	// Hop-by-hop headers. These are removed when sent to the backend.
-	// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
-	// This list of headers borrowed from stdlib httputil.ReverseProxy
-	singleHopHeaders = []string{
-		"Connection",
-		"Keep-Alive",
-		"Proxy-Authenticate",
-		"Proxy-Authorization",
-		"Te", // canonicalized version of "TE"
-		"Trailers",
-		"Transfer-Encoding",
-		"Upgrade",
-	}
-)
-
-func removeSingleHopHeaders(hdrs *http.Header) {
-	for _, h := range singleHopHeaders {
-		hdrs.Del(h)
-	}
-}
-
-type reverseProxy struct {
-	director  *director
-	transport http.RoundTripper
-}
-
-func (p *reverseProxy) ServeHTTP(rw http.ResponseWriter, clientreq *http.Request) {
-	reportIncomingRequest(clientreq)
-	proxyreq := new(http.Request)
-	*proxyreq = *clientreq
-	startTime := time.Now()
-
-	var (
-		proxybody []byte
-		err       error
-	)
-
-	if clientreq.Body != nil {
-		proxybody, err = ioutil.ReadAll(clientreq.Body)
-		if err != nil {
-			msg := fmt.Sprintf("failed to read request body: %v", err)
-			plog.Println(msg)
-			e := httptypes.NewHTTPError(http.StatusInternalServerError, "httpproxy: "+msg)
-			if we := e.WriteTo(rw); we != nil {
-				plog.Debugf("error writing HTTPError (%v) to %s", we, clientreq.RemoteAddr)
-			}
-			return
-		}
-	}
-
-	// deep-copy the headers, as these will be modified below
-	proxyreq.Header = make(http.Header)
-	copyHeader(proxyreq.Header, clientreq.Header)
-
-	normalizeRequest(proxyreq)
-	removeSingleHopHeaders(&proxyreq.Header)
-	maybeSetForwardedFor(proxyreq)
-
-	endpoints := p.director.endpoints()
-	if len(endpoints) == 0 {
-		msg := "zero endpoints currently available"
-		reportRequestDropped(clientreq, zeroEndpoints)
-
-		// TODO: limit the rate of the error logging.
-		plog.Println(msg)
-		e := httptypes.NewHTTPError(http.StatusServiceUnavailable, "httpproxy: "+msg)
-		if we := e.WriteTo(rw); we != nil {
-			plog.Debugf("error writing HTTPError (%v) to %s", we, clientreq.RemoteAddr)
-		}
-		return
-	}
-
-	var requestClosed int32
-	completeCh := make(chan bool, 1)
-	closeNotifier, ok := rw.(http.CloseNotifier)
-	ctx, cancel := context.WithCancel(context.Background())
-	proxyreq = proxyreq.WithContext(ctx)
-	defer cancel()
-	if ok {
-		closeCh := closeNotifier.CloseNotify()
-		go func() {
-			select {
-			case <-closeCh:
-				atomic.StoreInt32(&requestClosed, 1)
-				plog.Printf("client %v closed request prematurely", clientreq.RemoteAddr)
-				cancel()
-			case <-completeCh:
-			}
-		}()
-
-		defer func() {
-			completeCh <- true
-		}()
-	}
-
-	var res *http.Response
-
-	for _, ep := range endpoints {
-		if proxybody != nil {
-			proxyreq.Body = ioutil.NopCloser(bytes.NewBuffer(proxybody))
-		}
-		redirectRequest(proxyreq, ep.URL)
-
-		res, err = p.transport.RoundTrip(proxyreq)
-		if atomic.LoadInt32(&requestClosed) == 1 {
-			return
-		}
-		if err != nil {
-			reportRequestDropped(clientreq, failedSendingRequest)
-			plog.Printf("failed to direct request to %s: %v", ep.URL.String(), err)
-			ep.Failed()
-			continue
-		}
-
-		break
-	}
-
-	if res == nil {
-		// TODO: limit the rate of the error logging.
-		msg := fmt.Sprintf("unable to get response from %d endpoint(s)", len(endpoints))
-		reportRequestDropped(clientreq, failedGettingResponse)
-		plog.Println(msg)
-		e := httptypes.NewHTTPError(http.StatusBadGateway, "httpproxy: "+msg)
-		if we := e.WriteTo(rw); we != nil {
-			plog.Debugf("error writing HTTPError (%v) to %s", we, clientreq.RemoteAddr)
-		}
-		return
-	}
-
-	defer res.Body.Close()
-	reportRequestHandled(clientreq, res, startTime)
-	removeSingleHopHeaders(&res.Header)
-	copyHeader(rw.Header(), res.Header)
-
-	rw.WriteHeader(res.StatusCode)
-	io.Copy(rw, res.Body)
-}
-
-func copyHeader(dst, src http.Header) {
-	for k, vv := range src {
-		for _, v := range vv {
-			dst.Add(k, v)
-		}
-	}
-}
-
-func redirectRequest(req *http.Request, loc url.URL) {
-	req.URL.Scheme = loc.Scheme
-	req.URL.Host = loc.Host
-}
-
-func normalizeRequest(req *http.Request) {
-	req.Proto = "HTTP/1.1"
-	req.ProtoMajor = 1
-	req.ProtoMinor = 1
-	req.Close = false
-}
-
-func maybeSetForwardedFor(req *http.Request) {
-	clientIP, _, err := net.SplitHostPort(req.RemoteAddr)
-	if err != nil {
-		return
-	}
-
-	// If we aren't the first proxy retain prior
-	// X-Forwarded-For information as a comma+space
-	// separated list and fold multiple headers into one.
-	if prior, ok := req.Header["X-Forwarded-For"]; ok {
-		clientIP = strings.Join(prior, ", ") + ", " + clientIP
-	}
-	req.Header.Set("X-Forwarded-For", clientIP)
-}
diff --git a/vendor/github.com/coreos/etcd/proxy/tcpproxy/doc.go b/vendor/github.com/coreos/etcd/proxy/tcpproxy/doc.go
deleted file mode 100644
index 6889cac..0000000
--- a/vendor/github.com/coreos/etcd/proxy/tcpproxy/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package tcpproxy is an OSI level 4 proxy for routing etcd clients to etcd servers.
-package tcpproxy
diff --git a/vendor/github.com/coreos/etcd/proxy/tcpproxy/userspace.go b/vendor/github.com/coreos/etcd/proxy/tcpproxy/userspace.go
deleted file mode 100644
index 6dc1d1d..0000000
--- a/vendor/github.com/coreos/etcd/proxy/tcpproxy/userspace.go
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package tcpproxy
-
-import (
-	"fmt"
-	"io"
-	"math/rand"
-	"net"
-	"sync"
-	"time"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "proxy/tcpproxy")
-)
-
-type remote struct {
-	mu       sync.Mutex
-	srv      *net.SRV
-	addr     string
-	inactive bool
-}
-
-func (r *remote) inactivate() {
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	r.inactive = true
-}
-
-func (r *remote) tryReactivate() error {
-	conn, err := net.Dial("tcp", r.addr)
-	if err != nil {
-		return err
-	}
-	conn.Close()
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	r.inactive = false
-	return nil
-}
-
-func (r *remote) isActive() bool {
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	return !r.inactive
-}
-
-type TCPProxy struct {
-	Listener        net.Listener
-	Endpoints       []*net.SRV
-	MonitorInterval time.Duration
-
-	donec chan struct{}
-
-	mu        sync.Mutex // guards the following fields
-	remotes   []*remote
-	pickCount int // for round robin
-}
-
-func (tp *TCPProxy) Run() error {
-	tp.donec = make(chan struct{})
-	if tp.MonitorInterval == 0 {
-		tp.MonitorInterval = 5 * time.Minute
-	}
-	for _, srv := range tp.Endpoints {
-		addr := fmt.Sprintf("%s:%d", srv.Target, srv.Port)
-		tp.remotes = append(tp.remotes, &remote{srv: srv, addr: addr})
-	}
-
-	eps := []string{}
-	for _, ep := range tp.Endpoints {
-		eps = append(eps, fmt.Sprintf("%s:%d", ep.Target, ep.Port))
-	}
-	plog.Printf("ready to proxy client requests to %+v", eps)
-
-	go tp.runMonitor()
-	for {
-		in, err := tp.Listener.Accept()
-		if err != nil {
-			return err
-		}
-
-		go tp.serve(in)
-	}
-}
-
-func (tp *TCPProxy) pick() *remote {
-	var weighted []*remote
-	var unweighted []*remote
-
-	bestPr := uint16(65535)
-	w := 0
-	// find best priority class
-	for _, r := range tp.remotes {
-		switch {
-		case !r.isActive():
-		case r.srv.Priority < bestPr:
-			bestPr = r.srv.Priority
-			w = 0
-			weighted = nil
-			unweighted = []*remote{r}
-			fallthrough
-		case r.srv.Priority == bestPr:
-			if r.srv.Weight > 0 {
-				weighted = append(weighted, r)
-				w += int(r.srv.Weight)
-			} else {
-				unweighted = append(unweighted, r)
-			}
-		}
-	}
-	if weighted != nil {
-		if len(unweighted) > 0 && rand.Intn(100) == 1 {
-			// In the presence of records containing weights greater
-			// than 0, records with weight 0 should have a very small
-			// chance of being selected.
-			r := unweighted[tp.pickCount%len(unweighted)]
-			tp.pickCount++
-			return r
-		}
-		// choose a uniform random number between 0 and the sum computed
-		// (inclusive), and select the RR whose running sum value is the
-		// first in the selected order
-		choose := rand.Intn(w)
-		for i := 0; i < len(weighted); i++ {
-			choose -= int(weighted[i].srv.Weight)
-			if choose <= 0 {
-				return weighted[i]
-			}
-		}
-	}
-	if unweighted != nil {
-		for i := 0; i < len(tp.remotes); i++ {
-			picked := tp.remotes[tp.pickCount%len(tp.remotes)]
-			tp.pickCount++
-			if picked.isActive() {
-				return picked
-			}
-		}
-	}
-	return nil
-}
-
-func (tp *TCPProxy) serve(in net.Conn) {
-	var (
-		err error
-		out net.Conn
-	)
-
-	for {
-		tp.mu.Lock()
-		remote := tp.pick()
-		tp.mu.Unlock()
-		if remote == nil {
-			break
-		}
-		// TODO: add timeout
-		out, err = net.Dial("tcp", remote.addr)
-		if err == nil {
-			break
-		}
-		remote.inactivate()
-		plog.Warningf("deactivated endpoint [%s] due to %v for %v", remote.addr, err, tp.MonitorInterval)
-	}
-
-	if out == nil {
-		in.Close()
-		return
-	}
-
-	go func() {
-		io.Copy(in, out)
-		in.Close()
-		out.Close()
-	}()
-
-	io.Copy(out, in)
-	out.Close()
-	in.Close()
-}
-
-func (tp *TCPProxy) runMonitor() {
-	for {
-		select {
-		case <-time.After(tp.MonitorInterval):
-			tp.mu.Lock()
-			for _, rem := range tp.remotes {
-				if rem.isActive() {
-					continue
-				}
-				go func(r *remote) {
-					if err := r.tryReactivate(); err != nil {
-						plog.Warningf("failed to activate endpoint [%s] due to %v (stay inactive for another %v)", r.addr, err, tp.MonitorInterval)
-					} else {
-						plog.Printf("activated %s", r.addr)
-					}
-				}(rem)
-			}
-			tp.mu.Unlock()
-		case <-tp.donec:
-			return
-		}
-	}
-}
-
-func (tp *TCPProxy) Stop() {
-	// graceful shutdown?
-	// shutdown current connections?
-	tp.Listener.Close()
-	close(tp.donec)
-}
diff --git a/vendor/github.com/coreos/etcd/raft/README.md b/vendor/github.com/coreos/etcd/raft/README.md
deleted file mode 100644
index fde22b1..0000000
--- a/vendor/github.com/coreos/etcd/raft/README.md
+++ /dev/null
@@ -1,196 +0,0 @@
-# Raft library
-
-Raft is a protocol with which a cluster of nodes can maintain a replicated state machine.
-The state machine is kept in sync through the use of a replicated log.
-For more details on Raft, see "In Search of an Understandable Consensus Algorithm"
-(https://ramcloud.stanford.edu/raft.pdf) by Diego Ongaro and John Ousterhout.
-
-This Raft library is stable and feature complete. As of 2016, it is **the most widely used** Raft library in production, serving tens of thousands clusters each day. It powers distributed systems such as etcd, Kubernetes, Docker Swarm, Cloud Foundry Diego, CockroachDB, TiDB, Project Calico, Flannel, and more.
-
-Most Raft implementations have a monolithic design, including storage handling, messaging serialization, and network transport. This library instead follows a minimalistic design philosophy by only implementing the core raft algorithm. This minimalism buys flexibility, determinism, and performance.
-
-To keep the codebase small as well as provide flexibility, the library only implements the Raft algorithm; both network and disk IO are left to the user. Library users must implement their own transportation layer for message passing between Raft peers over the wire. Similarly, users must implement their own storage layer to persist the Raft log and state.
-
-In order to easily test the Raft library, its behavior should be deterministic. To achieve this determinism, the library models Raft as a state machine.  The state machine takes a `Message` as input. A message can either be a local timer update or a network message sent from a remote peer. The state machine's output is a 3-tuple `{[]Messages, []LogEntries, NextState}` consisting of an array of `Messages`, `log entries`, and `Raft state changes`. For state machines with the same state, the same state machine input should always generate the same state machine output.
-
-A simple example application, _raftexample_, is also available to help illustrate how to use this package in practice: https://github.com/coreos/etcd/tree/master/contrib/raftexample
-
-# Features
-
-This raft implementation is a full feature implementation of Raft protocol. Features includes:
-
-- Leader election
-- Log replication
-- Log compaction 
-- Membership changes
-- Leadership transfer extension
-- Efficient linearizable read-only queries served by both the leader and followers
-  - leader checks with quorum and bypasses Raft log before processing read-only queries
-  - followers asks leader to get a safe read index before processing read-only queries
-- More efficient lease-based linearizable read-only queries served by both the leader and followers
-  - leader bypasses Raft log and processing read-only queries locally
-  - followers asks leader to get a safe read index before processing read-only queries
-  - this approach relies on the clock of the all the machines in raft group
-
-This raft implementation also includes a few optional enhancements:
-
-- Optimistic pipelining to reduce log replication latency
-- Flow control for log replication
-- Batching Raft messages to reduce synchronized network I/O calls
-- Batching log entries to reduce disk synchronized I/O
-- Writing to leader's disk in parallel
-- Internal proposal redirection from followers to leader
-- Automatic stepping down when the leader loses quorum 
-
-## Notable Users
-
-- [cockroachdb](https://github.com/cockroachdb/cockroach) A Scalable, Survivable, Strongly-Consistent SQL Database
-- [dgraph](https://github.com/dgraph-io/dgraph) A Scalable, Distributed, Low Latency, High Throughput Graph Database
-- [etcd](https://github.com/coreos/etcd) A distributed reliable key-value store
-- [tikv](https://github.com/pingcap/tikv) A Distributed transactional key value database powered by Rust and Raft
-- [swarmkit](https://github.com/docker/swarmkit) A toolkit for orchestrating distributed systems at any scale.
-- [chain core](https://github.com/chain/chain) Software for operating permissioned, multi-asset blockchain networks
-
-## Usage
-
-The primary object in raft is a Node. Either start a Node from scratch using raft.StartNode or start a Node from some initial state using raft.RestartNode.
-
-To start a three-node cluster
-```go
-  storage := raft.NewMemoryStorage()
-  c := &Config{
-    ID:              0x01,
-    ElectionTick:    10,
-    HeartbeatTick:   1,
-    Storage:         storage,
-    MaxSizePerMsg:   4096,
-    MaxInflightMsgs: 256,
-  }
-  // Set peer list to the other nodes in the cluster.
-  // Note that they need to be started separately as well.
-  n := raft.StartNode(c, []raft.Peer{{ID: 0x02}, {ID: 0x03}})
-```
-
-Start a single node cluster, like so:
-```go
-  // Create storage and config as shown above.
-  // Set peer list to itself, so this node can become the leader of this single-node cluster.
-  peers := []raft.Peer{{ID: 0x01}}
-  n := raft.StartNode(c, peers)
-```
-
-To allow a new node to join this cluster, do not pass in any peers. First, add the node to the existing cluster by calling `ProposeConfChange` on any existing node inside the cluster. Then, start the node with an empty peer list, like so:
-```go
-  // Create storage and config as shown above.
-  n := raft.StartNode(c, nil)
-```
-
-To restart a node from previous state:
-```go
-  storage := raft.NewMemoryStorage()
-
-  // Recover the in-memory storage from persistent snapshot, state and entries.
-  storage.ApplySnapshot(snapshot)
-  storage.SetHardState(state)
-  storage.Append(entries)
-
-  c := &Config{
-    ID:              0x01,
-    ElectionTick:    10,
-    HeartbeatTick:   1,
-    Storage:         storage,
-    MaxSizePerMsg:   4096,
-    MaxInflightMsgs: 256,
-  }
-
-  // Restart raft without peer information.
-  // Peer information is already included in the storage.
-  n := raft.RestartNode(c)
-```
-
-After creating a Node, the user has a few responsibilities:
-
-First, read from the Node.Ready() channel and process the updates it contains. These steps may be performed in parallel, except as noted in step 2.
-
-1. Write Entries, HardState and Snapshot to persistent storage in order, i.e. Entries first, then HardState and Snapshot if they are not empty. If persistent storage supports atomic writes then all of them can be written together. Note that when writing an Entry with Index i, any previously-persisted entries with Index >= i must be discarded.
-
-2. Send all Messages to the nodes named in the To field. It is important that no messages be sent until the latest HardState has been persisted to disk, and all Entries written by any previous Ready batch (Messages may be sent while entries from the same batch are being persisted). To reduce the I/O latency, an optimization can be applied to make leader write to disk in parallel with its followers (as explained at section 10.2.1 in Raft thesis). If any Message has type MsgSnap, call Node.ReportSnapshot() after it has been sent (these messages may be large). Note: Marshalling messages is not thread-safe; it is important to make sure that no new entries are persisted while marshalling. The easiest way to achieve this is to serialise the messages directly inside the main raft loop.
-
-3. Apply Snapshot (if any) and CommittedEntries to the state machine. If any committed Entry has Type EntryConfChange, call Node.ApplyConfChange() to apply it to the node. The configuration change may be cancelled at this point by setting the NodeID field to zero before calling ApplyConfChange (but ApplyConfChange must be called one way or the other, and the decision to cancel must be based solely on the state machine and not external information such as the observed health of the node).
-
-4. Call Node.Advance() to signal readiness for the next batch of updates. This may be done at any time after step 1, although all updates must be processed in the order they were returned by Ready.
-
-Second, all persisted log entries must be made available via an implementation of the Storage interface. The provided MemoryStorage type can be used for this (if repopulating its state upon a restart), or a custom disk-backed implementation can be supplied.
-
-Third, after receiving a message from another node, pass it to Node.Step:
-
-```go
-	func recvRaftRPC(ctx context.Context, m raftpb.Message) {
-		n.Step(ctx, m)
-	}
-```
-
-Finally, call `Node.Tick()` at regular intervals (probably via a `time.Ticker`). Raft has two important timeouts: heartbeat and the election timeout. However, internally to the raft package time is represented by an abstract "tick".
-
-The total state machine handling loop will look something like this:
-
-```go
-  for {
-    select {
-    case <-s.Ticker:
-      n.Tick()
-    case rd := <-s.Node.Ready():
-      saveToStorage(rd.State, rd.Entries, rd.Snapshot)
-      send(rd.Messages)
-      if !raft.IsEmptySnap(rd.Snapshot) {
-        processSnapshot(rd.Snapshot)
-      }
-      for _, entry := range rd.CommittedEntries {
-        process(entry)
-        if entry.Type == raftpb.EntryConfChange {
-          var cc raftpb.ConfChange
-          cc.Unmarshal(entry.Data)
-          s.Node.ApplyConfChange(cc)
-        }
-      }
-      s.Node.Advance()
-    case <-s.done:
-      return
-    }
-  }
-```
-
-To propose changes to the state machine from the node to take application data, serialize it into a byte slice and call:
-
-```go
-	n.Propose(ctx, data)
-```
-
-If the proposal is committed, data will appear in committed entries with type raftpb.EntryNormal. There is no guarantee that a proposed command will be committed; the command may have to be reproposed after a timeout. 
-
-To add or remove node in a cluster, build ConfChange struct 'cc' and call:
-
-```go
-	n.ProposeConfChange(ctx, cc)
-```
-
-After config change is committed, some committed entry with type raftpb.EntryConfChange will be returned. This must be applied to node through:
-
-```go
-	var cc raftpb.ConfChange
-	cc.Unmarshal(data)
-	n.ApplyConfChange(cc)
-```
-
-Note: An ID represents a unique node in a cluster for all time. A
-given ID MUST be used only once even if the old node has been removed.
-This means that for example IP addresses make poor node IDs since they
-may be reused. Node IDs must be non-zero.
-
-## Implementation notes
-
-This implementation is up to date with the final Raft thesis (https://ramcloud.stanford.edu/~ongaro/thesis.pdf), although this implementation of the membership change protocol differs somewhat from that described in chapter 4. The key invariant that membership changes happen one node at a time is preserved, but in our implementation the membership change takes effect when its entry is applied, not when it is added to the log (so the entry is committed under the old membership instead of the new). This is equivalent in terms of safety, since the old and new configurations are guaranteed to overlap.
-
-To ensure there is no attempt to commit two membership changes at once by matching log positions (which would be unsafe since they should have different quorum requirements), any proposed membership change is simply disallowed while any uncommitted change appears in the leader's log.
-
-This approach introduces a problem when removing a member from a two-member cluster: If one of the members dies before the other one receives the commit of the confchange entry, then the member cannot be removed any more since the cluster cannot make progress. For this reason it is highly recommended to use three or more nodes in every cluster.
diff --git a/vendor/github.com/coreos/etcd/raft/design.md b/vendor/github.com/coreos/etcd/raft/design.md
deleted file mode 100644
index 7bc0531..0000000
--- a/vendor/github.com/coreos/etcd/raft/design.md
+++ /dev/null
@@ -1,57 +0,0 @@
-## Progress
-
-Progress represents a follower’s progress in the view of the leader. Leader maintains progresses of all followers, and sends `replication message` to the follower based on its progress. 
-
-`replication message` is a `msgApp` with log entries.
-
-A progress has two attribute: `match` and `next`. `match` is the index of the highest known matched entry. If leader knows nothing about follower’s replication status, `match` is set to zero. `next` is the index of the first entry that will be replicated to the follower. Leader puts entries from `next` to its latest one in next `replication message`.
-
-A progress is in one of the three state: `probe`, `replicate`, `snapshot`. 
-
-```
-                            +--------------------------------------------------------+          
-                            |                  send snapshot                         |          
-                            |                                                        |          
-                  +---------+----------+                                  +----------v---------+
-              +--->       probe        |                                  |      snapshot      |
-              |   |  max inflight = 1  <----------------------------------+  max inflight = 0  |
-              |   +---------+----------+                                  +--------------------+
-              |             |            1. snapshot success                                    
-              |             |               (next=snapshot.index + 1)                           
-              |             |            2. snapshot failure                                    
-              |             |               (no change)                                         
-              |             |            3. receives msgAppResp(rej=false&&index>lastsnap.index)
-              |             |               (match=m.index,next=match+1)                        
-receives msgAppResp(rej=true)                                                                   
-(next=match+1)|             |                                                                   
-              |             |                                                                   
-              |             |                                                                   
-              |             |   receives msgAppResp(rej=false&&index>match)                     
-              |             |   (match=m.index,next=match+1)                                    
-              |             |                                                                   
-              |             |                                                                   
-              |             |                                                                   
-              |   +---------v----------+                                                        
-              |   |     replicate      |                                                        
-              +---+  max inflight = n  |                                                        
-                  +--------------------+                                                        
-```
-
-When the progress of a follower is in `probe` state, leader sends at most one `replication message` per heartbeat interval. The leader sends `replication message` slowly and probing the actual progress of the follower. A `msgHeartbeatResp` or a `msgAppResp` with reject might trigger the sending of the next `replication message`.
-
-When the progress of a follower is in `replicate` state, leader sends `replication message`, then optimistically increases `next` to the latest entry sent. This is an optimized state for fast replicating log entries to the follower.
-
-When the progress of a follower is in `snapshot` state, leader stops sending any `replication message`.
-
-A newly elected leader sets the progresses of all the followers to `probe` state with `match` = 0 and `next` = last index. The leader slowly (at most once per heartbeat) sends `replication message` to the follower and probes its progress.
-
-A progress changes to `replicate` when the follower replies with a non-rejection `msgAppResp`, which implies that it has matched the index sent. At this point, leader starts to stream log entries to the follower fast. The progress will fall back to `probe` when the follower replies a rejection `msgAppResp` or the link layer reports the follower is unreachable. We aggressively reset `next` to `match`+1 since if we receive any `msgAppResp` soon, both `match` and `next` will increase directly to the `index` in `msgAppResp`. (We might end up with sending some duplicate entries when aggressively reset `next` too low.  see open question)
-
-A progress changes from `probe` to `snapshot` when the follower falls very far behind and requires a snapshot. After sending `msgSnap`, the leader waits until the success, failure or abortion of the previous snapshot sent. The progress will go back to `probe` after the sending result is applied.
-
-### Flow Control
-
-1. limit the max size of message sent per message. Max should be configurable.
-Lower the cost at probing state as we limit the size per message; lower the penalty when aggressively decreased to a too low `next`
-
-2. limit the # of in flight messages < N when in `replicate` state. N should be configurable. Most implementation will have a sending buffer on top of its actual network transport layer (not blocking raft node). We want to make sure raft does not overflow that buffer, which can cause message dropping and triggering a bunch of unnecessary resending repeatedly. 
diff --git a/vendor/github.com/coreos/etcd/raft/doc.go b/vendor/github.com/coreos/etcd/raft/doc.go
deleted file mode 100644
index b55c591..0000000
--- a/vendor/github.com/coreos/etcd/raft/doc.go
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/*
-Package raft sends and receives messages in the Protocol Buffer format
-defined in the raftpb package.
-
-Raft is a protocol with which a cluster of nodes can maintain a replicated state machine.
-The state machine is kept in sync through the use of a replicated log.
-For more details on Raft, see "In Search of an Understandable Consensus Algorithm"
-(https://ramcloud.stanford.edu/raft.pdf) by Diego Ongaro and John Ousterhout.
-
-A simple example application, _raftexample_, is also available to help illustrate
-how to use this package in practice:
-https://github.com/coreos/etcd/tree/master/contrib/raftexample
-
-Usage
-
-The primary object in raft is a Node. You either start a Node from scratch
-using raft.StartNode or start a Node from some initial state using raft.RestartNode.
-
-To start a node from scratch:
-
-  storage := raft.NewMemoryStorage()
-  c := &Config{
-    ID:              0x01,
-    ElectionTick:    10,
-    HeartbeatTick:   1,
-    Storage:         storage,
-    MaxSizePerMsg:   4096,
-    MaxInflightMsgs: 256,
-  }
-  n := raft.StartNode(c, []raft.Peer{{ID: 0x02}, {ID: 0x03}})
-
-To restart a node from previous state:
-
-  storage := raft.NewMemoryStorage()
-
-  // recover the in-memory storage from persistent
-  // snapshot, state and entries.
-  storage.ApplySnapshot(snapshot)
-  storage.SetHardState(state)
-  storage.Append(entries)
-
-  c := &Config{
-    ID:              0x01,
-    ElectionTick:    10,
-    HeartbeatTick:   1,
-    Storage:         storage,
-    MaxSizePerMsg:   4096,
-    MaxInflightMsgs: 256,
-  }
-
-  // restart raft without peer information.
-  // peer information is already included in the storage.
-  n := raft.RestartNode(c)
-
-Now that you are holding onto a Node you have a few responsibilities:
-
-First, you must read from the Node.Ready() channel and process the updates
-it contains. These steps may be performed in parallel, except as noted in step
-2.
-
-1. Write HardState, Entries, and Snapshot to persistent storage if they are
-not empty. Note that when writing an Entry with Index i, any
-previously-persisted entries with Index >= i must be discarded.
-
-2. Send all Messages to the nodes named in the To field. It is important that
-no messages be sent until the latest HardState has been persisted to disk,
-and all Entries written by any previous Ready batch (Messages may be sent while
-entries from the same batch are being persisted). To reduce the I/O latency, an
-optimization can be applied to make leader write to disk in parallel with its
-followers (as explained at section 10.2.1 in Raft thesis). If any Message has type
-MsgSnap, call Node.ReportSnapshot() after it has been sent (these messages may be
-large).
-
-Note: Marshalling messages is not thread-safe; it is important that you
-make sure that no new entries are persisted while marshalling.
-The easiest way to achieve this is to serialise the messages directly inside
-your main raft loop.
-
-3. Apply Snapshot (if any) and CommittedEntries to the state machine.
-If any committed Entry has Type EntryConfChange, call Node.ApplyConfChange()
-to apply it to the node. The configuration change may be cancelled at this point
-by setting the NodeID field to zero before calling ApplyConfChange
-(but ApplyConfChange must be called one way or the other, and the decision to cancel
-must be based solely on the state machine and not external information such as
-the observed health of the node).
-
-4. Call Node.Advance() to signal readiness for the next batch of updates.
-This may be done at any time after step 1, although all updates must be processed
-in the order they were returned by Ready.
-
-Second, all persisted log entries must be made available via an
-implementation of the Storage interface. The provided MemoryStorage
-type can be used for this (if you repopulate its state upon a
-restart), or you can supply your own disk-backed implementation.
-
-Third, when you receive a message from another node, pass it to Node.Step:
-
-	func recvRaftRPC(ctx context.Context, m raftpb.Message) {
-		n.Step(ctx, m)
-	}
-
-Finally, you need to call Node.Tick() at regular intervals (probably
-via a time.Ticker). Raft has two important timeouts: heartbeat and the
-election timeout. However, internally to the raft package time is
-represented by an abstract "tick".
-
-The total state machine handling loop will look something like this:
-
-  for {
-    select {
-    case <-s.Ticker:
-      n.Tick()
-    case rd := <-s.Node.Ready():
-      saveToStorage(rd.State, rd.Entries, rd.Snapshot)
-      send(rd.Messages)
-      if !raft.IsEmptySnap(rd.Snapshot) {
-        processSnapshot(rd.Snapshot)
-      }
-      for _, entry := range rd.CommittedEntries {
-        process(entry)
-        if entry.Type == raftpb.EntryConfChange {
-          var cc raftpb.ConfChange
-          cc.Unmarshal(entry.Data)
-          s.Node.ApplyConfChange(cc)
-        }
-      }
-      s.Node.Advance()
-    case <-s.done:
-      return
-    }
-  }
-
-To propose changes to the state machine from your node take your application
-data, serialize it into a byte slice and call:
-
-	n.Propose(ctx, data)
-
-If the proposal is committed, data will appear in committed entries with type
-raftpb.EntryNormal. There is no guarantee that a proposed command will be
-committed; you may have to re-propose after a timeout.
-
-To add or remove node in a cluster, build ConfChange struct 'cc' and call:
-
-	n.ProposeConfChange(ctx, cc)
-
-After config change is committed, some committed entry with type
-raftpb.EntryConfChange will be returned. You must apply it to node through:
-
-	var cc raftpb.ConfChange
-	cc.Unmarshal(data)
-	n.ApplyConfChange(cc)
-
-Note: An ID represents a unique node in a cluster for all time. A
-given ID MUST be used only once even if the old node has been removed.
-This means that for example IP addresses make poor node IDs since they
-may be reused. Node IDs must be non-zero.
-
-Implementation notes
-
-This implementation is up to date with the final Raft thesis
-(https://ramcloud.stanford.edu/~ongaro/thesis.pdf), although our
-implementation of the membership change protocol differs somewhat from
-that described in chapter 4. The key invariant that membership changes
-happen one node at a time is preserved, but in our implementation the
-membership change takes effect when its entry is applied, not when it
-is added to the log (so the entry is committed under the old
-membership instead of the new). This is equivalent in terms of safety,
-since the old and new configurations are guaranteed to overlap.
-
-To ensure that we do not attempt to commit two membership changes at
-once by matching log positions (which would be unsafe since they
-should have different quorum requirements), we simply disallow any
-proposed membership change while any uncommitted change appears in
-the leader's log.
-
-This approach introduces a problem when you try to remove a member
-from a two-member cluster: If one of the members dies before the
-other one receives the commit of the confchange entry, then the member
-cannot be removed any more since the cluster cannot make progress.
-For this reason it is highly recommended to use three or more nodes in
-every cluster.
-
-MessageType
-
-Package raft sends and receives message in Protocol Buffer format (defined
-in raftpb package). Each state (follower, candidate, leader) implements its
-own 'step' method ('stepFollower', 'stepCandidate', 'stepLeader') when
-advancing with the given raftpb.Message. Each step is determined by its
-raftpb.MessageType. Note that every step is checked by one common method
-'Step' that safety-checks the terms of node and incoming message to prevent
-stale log entries:
-
-	'MsgHup' is used for election. If a node is a follower or candidate, the
-	'tick' function in 'raft' struct is set as 'tickElection'. If a follower or
-	candidate has not received any heartbeat before the election timeout, it
-	passes 'MsgHup' to its Step method and becomes (or remains) a candidate to
-	start a new election.
-
-	'MsgBeat' is an internal type that signals the leader to send a heartbeat of
-	the 'MsgHeartbeat' type. If a node is a leader, the 'tick' function in
-	the 'raft' struct is set as 'tickHeartbeat', and triggers the leader to
-	send periodic 'MsgHeartbeat' messages to its followers.
-
-	'MsgProp' proposes to append data to its log entries. This is a special
-	type to redirect proposals to leader. Therefore, send method overwrites
-	raftpb.Message's term with its HardState's term to avoid attaching its
-	local term to 'MsgProp'. When 'MsgProp' is passed to the leader's 'Step'
-	method, the leader first calls the 'appendEntry' method to append entries
-	to its log, and then calls 'bcastAppend' method to send those entries to
-	its peers. When passed to candidate, 'MsgProp' is dropped. When passed to
-	follower, 'MsgProp' is stored in follower's mailbox(msgs) by the send
-	method. It is stored with sender's ID and later forwarded to leader by
-	rafthttp package.
-
-	'MsgApp' contains log entries to replicate. A leader calls bcastAppend,
-	which calls sendAppend, which sends soon-to-be-replicated logs in 'MsgApp'
-	type. When 'MsgApp' is passed to candidate's Step method, candidate reverts
-	back to follower, because it indicates that there is a valid leader sending
-	'MsgApp' messages. Candidate and follower respond to this message in
-	'MsgAppResp' type.
-
-	'MsgAppResp' is response to log replication request('MsgApp'). When
-	'MsgApp' is passed to candidate or follower's Step method, it responds by
-	calling 'handleAppendEntries' method, which sends 'MsgAppResp' to raft
-	mailbox.
-
-	'MsgVote' requests votes for election. When a node is a follower or
-	candidate and 'MsgHup' is passed to its Step method, then the node calls
-	'campaign' method to campaign itself to become a leader. Once 'campaign'
-	method is called, the node becomes candidate and sends 'MsgVote' to peers
-	in cluster to request votes. When passed to leader or candidate's Step
-	method and the message's Term is lower than leader's or candidate's,
-	'MsgVote' will be rejected ('MsgVoteResp' is returned with Reject true).
-	If leader or candidate receives 'MsgVote' with higher term, it will revert
-	back to follower. When 'MsgVote' is passed to follower, it votes for the
-	sender only when sender's last term is greater than MsgVote's term or
-	sender's last term is equal to MsgVote's term but sender's last committed
-	index is greater than or equal to follower's.
-
-	'MsgVoteResp' contains responses from voting request. When 'MsgVoteResp' is
-	passed to candidate, the candidate calculates how many votes it has won. If
-	it's more than majority (quorum), it becomes leader and calls 'bcastAppend'.
-	If candidate receives majority of votes of denials, it reverts back to
-	follower.
-
-	'MsgPreVote' and 'MsgPreVoteResp' are used in an optional two-phase election
-	protocol. When Config.PreVote is true, a pre-election is carried out first
-	(using the same rules as a regular election), and no node increases its term
-	number unless the pre-election indicates that the campaigining node would win.
-	This minimizes disruption when a partitioned node rejoins the cluster.
-
-	'MsgSnap' requests to install a snapshot message. When a node has just
-	become a leader or the leader receives 'MsgProp' message, it calls
-	'bcastAppend' method, which then calls 'sendAppend' method to each
-	follower. In 'sendAppend', if a leader fails to get term or entries,
-	the leader requests snapshot by sending 'MsgSnap' type message.
-
-	'MsgSnapStatus' tells the result of snapshot install message. When a
-	follower rejected 'MsgSnap', it indicates the snapshot request with
-	'MsgSnap' had failed from network issues which causes the network layer
-	to fail to send out snapshots to its followers. Then leader considers
-	follower's progress as probe. When 'MsgSnap' were not rejected, it
-	indicates that the snapshot succeeded and the leader sets follower's
-	progress to probe and resumes its log replication.
-
-	'MsgHeartbeat' sends heartbeat from leader. When 'MsgHeartbeat' is passed
-	to candidate and message's term is higher than candidate's, the candidate
-	reverts back to follower and updates its committed index from the one in
-	this heartbeat. And it sends the message to its mailbox. When
-	'MsgHeartbeat' is passed to follower's Step method and message's term is
-	higher than follower's, the follower updates its leaderID with the ID
-	from the message.
-
-	'MsgHeartbeatResp' is a response to 'MsgHeartbeat'. When 'MsgHeartbeatResp'
-	is passed to leader's Step method, the leader knows which follower
-	responded. And only when the leader's last committed index is greater than
-	follower's Match index, the leader runs 'sendAppend` method.
-
-	'MsgUnreachable' tells that request(message) wasn't delivered. When
-	'MsgUnreachable' is passed to leader's Step method, the leader discovers
-	that the follower that sent this 'MsgUnreachable' is not reachable, often
-	indicating 'MsgApp' is lost. When follower's progress state is replicate,
-	the leader sets it back to probe.
-
-*/
-package raft
diff --git a/vendor/github.com/coreos/etcd/raft/log.go b/vendor/github.com/coreos/etcd/raft/log.go
deleted file mode 100644
index c3036d3..0000000
--- a/vendor/github.com/coreos/etcd/raft/log.go
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import (
-	"fmt"
-	"log"
-
-	pb "github.com/coreos/etcd/raft/raftpb"
-)
-
-type raftLog struct {
-	// storage contains all stable entries since the last snapshot.
-	storage Storage
-
-	// unstable contains all unstable entries and snapshot.
-	// they will be saved into storage.
-	unstable unstable
-
-	// committed is the highest log position that is known to be in
-	// stable storage on a quorum of nodes.
-	committed uint64
-	// applied is the highest log position that the application has
-	// been instructed to apply to its state machine.
-	// Invariant: applied <= committed
-	applied uint64
-
-	logger Logger
-}
-
-// newLog returns log using the given storage. It recovers the log to the state
-// that it just commits and applies the latest snapshot.
-func newLog(storage Storage, logger Logger) *raftLog {
-	if storage == nil {
-		log.Panic("storage must not be nil")
-	}
-	log := &raftLog{
-		storage: storage,
-		logger:  logger,
-	}
-	firstIndex, err := storage.FirstIndex()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-	lastIndex, err := storage.LastIndex()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-	log.unstable.offset = lastIndex + 1
-	log.unstable.logger = logger
-	// Initialize our committed and applied pointers to the time of the last compaction.
-	log.committed = firstIndex - 1
-	log.applied = firstIndex - 1
-
-	return log
-}
-
-func (l *raftLog) String() string {
-	return fmt.Sprintf("committed=%d, applied=%d, unstable.offset=%d, len(unstable.Entries)=%d", l.committed, l.applied, l.unstable.offset, len(l.unstable.entries))
-}
-
-// maybeAppend returns (0, false) if the entries cannot be appended. Otherwise,
-// it returns (last index of new entries, true).
-func (l *raftLog) maybeAppend(index, logTerm, committed uint64, ents ...pb.Entry) (lastnewi uint64, ok bool) {
-	if l.matchTerm(index, logTerm) {
-		lastnewi = index + uint64(len(ents))
-		ci := l.findConflict(ents)
-		switch {
-		case ci == 0:
-		case ci <= l.committed:
-			l.logger.Panicf("entry %d conflict with committed entry [committed(%d)]", ci, l.committed)
-		default:
-			offset := index + 1
-			l.append(ents[ci-offset:]...)
-		}
-		l.commitTo(min(committed, lastnewi))
-		return lastnewi, true
-	}
-	return 0, false
-}
-
-func (l *raftLog) append(ents ...pb.Entry) uint64 {
-	if len(ents) == 0 {
-		return l.lastIndex()
-	}
-	if after := ents[0].Index - 1; after < l.committed {
-		l.logger.Panicf("after(%d) is out of range [committed(%d)]", after, l.committed)
-	}
-	l.unstable.truncateAndAppend(ents)
-	return l.lastIndex()
-}
-
-// findConflict finds the index of the conflict.
-// It returns the first pair of conflicting entries between the existing
-// entries and the given entries, if there are any.
-// If there is no conflicting entries, and the existing entries contains
-// all the given entries, zero will be returned.
-// If there is no conflicting entries, but the given entries contains new
-// entries, the index of the first new entry will be returned.
-// An entry is considered to be conflicting if it has the same index but
-// a different term.
-// The first entry MUST have an index equal to the argument 'from'.
-// The index of the given entries MUST be continuously increasing.
-func (l *raftLog) findConflict(ents []pb.Entry) uint64 {
-	for _, ne := range ents {
-		if !l.matchTerm(ne.Index, ne.Term) {
-			if ne.Index <= l.lastIndex() {
-				l.logger.Infof("found conflict at index %d [existing term: %d, conflicting term: %d]",
-					ne.Index, l.zeroTermOnErrCompacted(l.term(ne.Index)), ne.Term)
-			}
-			return ne.Index
-		}
-	}
-	return 0
-}
-
-func (l *raftLog) unstableEntries() []pb.Entry {
-	if len(l.unstable.entries) == 0 {
-		return nil
-	}
-	return l.unstable.entries
-}
-
-// nextEnts returns all the available entries for execution.
-// If applied is smaller than the index of snapshot, it returns all committed
-// entries after the index of snapshot.
-func (l *raftLog) nextEnts() (ents []pb.Entry) {
-	off := max(l.applied+1, l.firstIndex())
-	if l.committed+1 > off {
-		ents, err := l.slice(off, l.committed+1, noLimit)
-		if err != nil {
-			l.logger.Panicf("unexpected error when getting unapplied entries (%v)", err)
-		}
-		return ents
-	}
-	return nil
-}
-
-// hasNextEnts returns if there is any available entries for execution. This
-// is a fast check without heavy raftLog.slice() in raftLog.nextEnts().
-func (l *raftLog) hasNextEnts() bool {
-	off := max(l.applied+1, l.firstIndex())
-	return l.committed+1 > off
-}
-
-func (l *raftLog) snapshot() (pb.Snapshot, error) {
-	if l.unstable.snapshot != nil {
-		return *l.unstable.snapshot, nil
-	}
-	return l.storage.Snapshot()
-}
-
-func (l *raftLog) firstIndex() uint64 {
-	if i, ok := l.unstable.maybeFirstIndex(); ok {
-		return i
-	}
-	index, err := l.storage.FirstIndex()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-	return index
-}
-
-func (l *raftLog) lastIndex() uint64 {
-	if i, ok := l.unstable.maybeLastIndex(); ok {
-		return i
-	}
-	i, err := l.storage.LastIndex()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-	return i
-}
-
-func (l *raftLog) commitTo(tocommit uint64) {
-	// never decrease commit
-	if l.committed < tocommit {
-		if l.lastIndex() < tocommit {
-			l.logger.Panicf("tocommit(%d) is out of range [lastIndex(%d)]. Was the raft log corrupted, truncated, or lost?", tocommit, l.lastIndex())
-		}
-		l.committed = tocommit
-	}
-}
-
-func (l *raftLog) appliedTo(i uint64) {
-	if i == 0 {
-		return
-	}
-	if l.committed < i || i < l.applied {
-		l.logger.Panicf("applied(%d) is out of range [prevApplied(%d), committed(%d)]", i, l.applied, l.committed)
-	}
-	l.applied = i
-}
-
-func (l *raftLog) stableTo(i, t uint64) { l.unstable.stableTo(i, t) }
-
-func (l *raftLog) stableSnapTo(i uint64) { l.unstable.stableSnapTo(i) }
-
-func (l *raftLog) lastTerm() uint64 {
-	t, err := l.term(l.lastIndex())
-	if err != nil {
-		l.logger.Panicf("unexpected error when getting the last term (%v)", err)
-	}
-	return t
-}
-
-func (l *raftLog) term(i uint64) (uint64, error) {
-	// the valid term range is [index of dummy entry, last index]
-	dummyIndex := l.firstIndex() - 1
-	if i < dummyIndex || i > l.lastIndex() {
-		// TODO: return an error instead?
-		return 0, nil
-	}
-
-	if t, ok := l.unstable.maybeTerm(i); ok {
-		return t, nil
-	}
-
-	t, err := l.storage.Term(i)
-	if err == nil {
-		return t, nil
-	}
-	if err == ErrCompacted || err == ErrUnavailable {
-		return 0, err
-	}
-	panic(err) // TODO(bdarnell)
-}
-
-func (l *raftLog) entries(i, maxsize uint64) ([]pb.Entry, error) {
-	if i > l.lastIndex() {
-		return nil, nil
-	}
-	return l.slice(i, l.lastIndex()+1, maxsize)
-}
-
-// allEntries returns all entries in the log.
-func (l *raftLog) allEntries() []pb.Entry {
-	ents, err := l.entries(l.firstIndex(), noLimit)
-	if err == nil {
-		return ents
-	}
-	if err == ErrCompacted { // try again if there was a racing compaction
-		return l.allEntries()
-	}
-	// TODO (xiangli): handle error?
-	panic(err)
-}
-
-// isUpToDate determines if the given (lastIndex,term) log is more up-to-date
-// by comparing the index and term of the last entries in the existing logs.
-// If the logs have last entries with different terms, then the log with the
-// later term is more up-to-date. If the logs end with the same term, then
-// whichever log has the larger lastIndex is more up-to-date. If the logs are
-// the same, the given log is up-to-date.
-func (l *raftLog) isUpToDate(lasti, term uint64) bool {
-	return term > l.lastTerm() || (term == l.lastTerm() && lasti >= l.lastIndex())
-}
-
-func (l *raftLog) matchTerm(i, term uint64) bool {
-	t, err := l.term(i)
-	if err != nil {
-		return false
-	}
-	return t == term
-}
-
-func (l *raftLog) maybeCommit(maxIndex, term uint64) bool {
-	if maxIndex > l.committed && l.zeroTermOnErrCompacted(l.term(maxIndex)) == term {
-		l.commitTo(maxIndex)
-		return true
-	}
-	return false
-}
-
-func (l *raftLog) restore(s pb.Snapshot) {
-	l.logger.Infof("log [%s] starts to restore snapshot [index: %d, term: %d]", l, s.Metadata.Index, s.Metadata.Term)
-	l.committed = s.Metadata.Index
-	l.unstable.restore(s)
-}
-
-// slice returns a slice of log entries from lo through hi-1, inclusive.
-func (l *raftLog) slice(lo, hi, maxSize uint64) ([]pb.Entry, error) {
-	err := l.mustCheckOutOfBounds(lo, hi)
-	if err != nil {
-		return nil, err
-	}
-	if lo == hi {
-		return nil, nil
-	}
-	var ents []pb.Entry
-	if lo < l.unstable.offset {
-		storedEnts, err := l.storage.Entries(lo, min(hi, l.unstable.offset), maxSize)
-		if err == ErrCompacted {
-			return nil, err
-		} else if err == ErrUnavailable {
-			l.logger.Panicf("entries[%d:%d) is unavailable from storage", lo, min(hi, l.unstable.offset))
-		} else if err != nil {
-			panic(err) // TODO(bdarnell)
-		}
-
-		// check if ents has reached the size limitation
-		if uint64(len(storedEnts)) < min(hi, l.unstable.offset)-lo {
-			return storedEnts, nil
-		}
-
-		ents = storedEnts
-	}
-	if hi > l.unstable.offset {
-		unstable := l.unstable.slice(max(lo, l.unstable.offset), hi)
-		if len(ents) > 0 {
-			ents = append([]pb.Entry{}, ents...)
-			ents = append(ents, unstable...)
-		} else {
-			ents = unstable
-		}
-	}
-	return limitSize(ents, maxSize), nil
-}
-
-// l.firstIndex <= lo <= hi <= l.firstIndex + len(l.entries)
-func (l *raftLog) mustCheckOutOfBounds(lo, hi uint64) error {
-	if lo > hi {
-		l.logger.Panicf("invalid slice %d > %d", lo, hi)
-	}
-	fi := l.firstIndex()
-	if lo < fi {
-		return ErrCompacted
-	}
-
-	length := l.lastIndex() + 1 - fi
-	if lo < fi || hi > fi+length {
-		l.logger.Panicf("slice[%d,%d) out of bound [%d,%d]", lo, hi, fi, l.lastIndex())
-	}
-	return nil
-}
-
-func (l *raftLog) zeroTermOnErrCompacted(t uint64, err error) uint64 {
-	if err == nil {
-		return t
-	}
-	if err == ErrCompacted {
-		return 0
-	}
-	l.logger.Panicf("unexpected error (%v)", err)
-	return 0
-}
diff --git a/vendor/github.com/coreos/etcd/raft/log_unstable.go b/vendor/github.com/coreos/etcd/raft/log_unstable.go
deleted file mode 100644
index 263af9c..0000000
--- a/vendor/github.com/coreos/etcd/raft/log_unstable.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import pb "github.com/coreos/etcd/raft/raftpb"
-
-// unstable.entries[i] has raft log position i+unstable.offset.
-// Note that unstable.offset may be less than the highest log
-// position in storage; this means that the next write to storage
-// might need to truncate the log before persisting unstable.entries.
-type unstable struct {
-	// the incoming unstable snapshot, if any.
-	snapshot *pb.Snapshot
-	// all entries that have not yet been written to storage.
-	entries []pb.Entry
-	offset  uint64
-
-	logger Logger
-}
-
-// maybeFirstIndex returns the index of the first possible entry in entries
-// if it has a snapshot.
-func (u *unstable) maybeFirstIndex() (uint64, bool) {
-	if u.snapshot != nil {
-		return u.snapshot.Metadata.Index + 1, true
-	}
-	return 0, false
-}
-
-// maybeLastIndex returns the last index if it has at least one
-// unstable entry or snapshot.
-func (u *unstable) maybeLastIndex() (uint64, bool) {
-	if l := len(u.entries); l != 0 {
-		return u.offset + uint64(l) - 1, true
-	}
-	if u.snapshot != nil {
-		return u.snapshot.Metadata.Index, true
-	}
-	return 0, false
-}
-
-// maybeTerm returns the term of the entry at index i, if there
-// is any.
-func (u *unstable) maybeTerm(i uint64) (uint64, bool) {
-	if i < u.offset {
-		if u.snapshot == nil {
-			return 0, false
-		}
-		if u.snapshot.Metadata.Index == i {
-			return u.snapshot.Metadata.Term, true
-		}
-		return 0, false
-	}
-
-	last, ok := u.maybeLastIndex()
-	if !ok {
-		return 0, false
-	}
-	if i > last {
-		return 0, false
-	}
-	return u.entries[i-u.offset].Term, true
-}
-
-func (u *unstable) stableTo(i, t uint64) {
-	gt, ok := u.maybeTerm(i)
-	if !ok {
-		return
-	}
-	// if i < offset, term is matched with the snapshot
-	// only update the unstable entries if term is matched with
-	// an unstable entry.
-	if gt == t && i >= u.offset {
-		u.entries = u.entries[i+1-u.offset:]
-		u.offset = i + 1
-		u.shrinkEntriesArray()
-	}
-}
-
-// shrinkEntriesArray discards the underlying array used by the entries slice
-// if most of it isn't being used. This avoids holding references to a bunch of
-// potentially large entries that aren't needed anymore. Simply clearing the
-// entries wouldn't be safe because clients might still be using them.
-func (u *unstable) shrinkEntriesArray() {
-	// We replace the array if we're using less than half of the space in
-	// it. This number is fairly arbitrary, chosen as an attempt to balance
-	// memory usage vs number of allocations. It could probably be improved
-	// with some focused tuning.
-	const lenMultiple = 2
-	if len(u.entries) == 0 {
-		u.entries = nil
-	} else if len(u.entries)*lenMultiple < cap(u.entries) {
-		newEntries := make([]pb.Entry, len(u.entries))
-		copy(newEntries, u.entries)
-		u.entries = newEntries
-	}
-}
-
-func (u *unstable) stableSnapTo(i uint64) {
-	if u.snapshot != nil && u.snapshot.Metadata.Index == i {
-		u.snapshot = nil
-	}
-}
-
-func (u *unstable) restore(s pb.Snapshot) {
-	u.offset = s.Metadata.Index + 1
-	u.entries = nil
-	u.snapshot = &s
-}
-
-func (u *unstable) truncateAndAppend(ents []pb.Entry) {
-	after := ents[0].Index
-	switch {
-	case after == u.offset+uint64(len(u.entries)):
-		// after is the next index in the u.entries
-		// directly append
-		u.entries = append(u.entries, ents...)
-	case after <= u.offset:
-		u.logger.Infof("replace the unstable entries from index %d", after)
-		// The log is being truncated to before our current offset
-		// portion, so set the offset and replace the entries
-		u.offset = after
-		u.entries = ents
-	default:
-		// truncate to after and copy to u.entries
-		// then append
-		u.logger.Infof("truncate the unstable entries before index %d", after)
-		u.entries = append([]pb.Entry{}, u.slice(u.offset, after)...)
-		u.entries = append(u.entries, ents...)
-	}
-}
-
-func (u *unstable) slice(lo uint64, hi uint64) []pb.Entry {
-	u.mustCheckOutOfBounds(lo, hi)
-	return u.entries[lo-u.offset : hi-u.offset]
-}
-
-// u.offset <= lo <= hi <= u.offset+len(u.offset)
-func (u *unstable) mustCheckOutOfBounds(lo, hi uint64) {
-	if lo > hi {
-		u.logger.Panicf("invalid unstable.slice %d > %d", lo, hi)
-	}
-	upper := u.offset + uint64(len(u.entries))
-	if lo < u.offset || hi > upper {
-		u.logger.Panicf("unstable.slice[%d,%d) out of bound [%d,%d]", lo, hi, u.offset, upper)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/raft/logger.go b/vendor/github.com/coreos/etcd/raft/logger.go
deleted file mode 100644
index 92e55b3..0000000
--- a/vendor/github.com/coreos/etcd/raft/logger.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import (
-	"fmt"
-	"io/ioutil"
-	"log"
-	"os"
-)
-
-type Logger interface {
-	Debug(v ...interface{})
-	Debugf(format string, v ...interface{})
-
-	Error(v ...interface{})
-	Errorf(format string, v ...interface{})
-
-	Info(v ...interface{})
-	Infof(format string, v ...interface{})
-
-	Warning(v ...interface{})
-	Warningf(format string, v ...interface{})
-
-	Fatal(v ...interface{})
-	Fatalf(format string, v ...interface{})
-
-	Panic(v ...interface{})
-	Panicf(format string, v ...interface{})
-}
-
-func SetLogger(l Logger) { raftLogger = l }
-
-var (
-	defaultLogger = &DefaultLogger{Logger: log.New(os.Stderr, "raft", log.LstdFlags)}
-	discardLogger = &DefaultLogger{Logger: log.New(ioutil.Discard, "", 0)}
-	raftLogger    = Logger(defaultLogger)
-)
-
-const (
-	calldepth = 2
-)
-
-// DefaultLogger is a default implementation of the Logger interface.
-type DefaultLogger struct {
-	*log.Logger
-	debug bool
-}
-
-func (l *DefaultLogger) EnableTimestamps() {
-	l.SetFlags(l.Flags() | log.Ldate | log.Ltime)
-}
-
-func (l *DefaultLogger) EnableDebug() {
-	l.debug = true
-}
-
-func (l *DefaultLogger) Debug(v ...interface{}) {
-	if l.debug {
-		l.Output(calldepth, header("DEBUG", fmt.Sprint(v...)))
-	}
-}
-
-func (l *DefaultLogger) Debugf(format string, v ...interface{}) {
-	if l.debug {
-		l.Output(calldepth, header("DEBUG", fmt.Sprintf(format, v...)))
-	}
-}
-
-func (l *DefaultLogger) Info(v ...interface{}) {
-	l.Output(calldepth, header("INFO", fmt.Sprint(v...)))
-}
-
-func (l *DefaultLogger) Infof(format string, v ...interface{}) {
-	l.Output(calldepth, header("INFO", fmt.Sprintf(format, v...)))
-}
-
-func (l *DefaultLogger) Error(v ...interface{}) {
-	l.Output(calldepth, header("ERROR", fmt.Sprint(v...)))
-}
-
-func (l *DefaultLogger) Errorf(format string, v ...interface{}) {
-	l.Output(calldepth, header("ERROR", fmt.Sprintf(format, v...)))
-}
-
-func (l *DefaultLogger) Warning(v ...interface{}) {
-	l.Output(calldepth, header("WARN", fmt.Sprint(v...)))
-}
-
-func (l *DefaultLogger) Warningf(format string, v ...interface{}) {
-	l.Output(calldepth, header("WARN", fmt.Sprintf(format, v...)))
-}
-
-func (l *DefaultLogger) Fatal(v ...interface{}) {
-	l.Output(calldepth, header("FATAL", fmt.Sprint(v...)))
-	os.Exit(1)
-}
-
-func (l *DefaultLogger) Fatalf(format string, v ...interface{}) {
-	l.Output(calldepth, header("FATAL", fmt.Sprintf(format, v...)))
-	os.Exit(1)
-}
-
-func (l *DefaultLogger) Panic(v ...interface{}) {
-	l.Logger.Panic(v)
-}
-
-func (l *DefaultLogger) Panicf(format string, v ...interface{}) {
-	l.Logger.Panicf(format, v...)
-}
-
-func header(lvl, msg string) string {
-	return fmt.Sprintf("%s: %s", lvl, msg)
-}
diff --git a/vendor/github.com/coreos/etcd/raft/node.go b/vendor/github.com/coreos/etcd/raft/node.go
deleted file mode 100644
index 33a9db8..0000000
--- a/vendor/github.com/coreos/etcd/raft/node.go
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import (
-	"context"
-	"errors"
-
-	pb "github.com/coreos/etcd/raft/raftpb"
-)
-
-type SnapshotStatus int
-
-const (
-	SnapshotFinish  SnapshotStatus = 1
-	SnapshotFailure SnapshotStatus = 2
-)
-
-var (
-	emptyState = pb.HardState{}
-
-	// ErrStopped is returned by methods on Nodes that have been stopped.
-	ErrStopped = errors.New("raft: stopped")
-)
-
-// SoftState provides state that is useful for logging and debugging.
-// The state is volatile and does not need to be persisted to the WAL.
-type SoftState struct {
-	Lead      uint64 // must use atomic operations to access; keep 64-bit aligned.
-	RaftState StateType
-}
-
-func (a *SoftState) equal(b *SoftState) bool {
-	return a.Lead == b.Lead && a.RaftState == b.RaftState
-}
-
-// Ready encapsulates the entries and messages that are ready to read,
-// be saved to stable storage, committed or sent to other peers.
-// All fields in Ready are read-only.
-type Ready struct {
-	// The current volatile state of a Node.
-	// SoftState will be nil if there is no update.
-	// It is not required to consume or store SoftState.
-	*SoftState
-
-	// The current state of a Node to be saved to stable storage BEFORE
-	// Messages are sent.
-	// HardState will be equal to empty state if there is no update.
-	pb.HardState
-
-	// ReadStates can be used for node to serve linearizable read requests locally
-	// when its applied index is greater than the index in ReadState.
-	// Note that the readState will be returned when raft receives msgReadIndex.
-	// The returned is only valid for the request that requested to read.
-	ReadStates []ReadState
-
-	// Entries specifies entries to be saved to stable storage BEFORE
-	// Messages are sent.
-	Entries []pb.Entry
-
-	// Snapshot specifies the snapshot to be saved to stable storage.
-	Snapshot pb.Snapshot
-
-	// CommittedEntries specifies entries to be committed to a
-	// store/state-machine. These have previously been committed to stable
-	// store.
-	CommittedEntries []pb.Entry
-
-	// Messages specifies outbound messages to be sent AFTER Entries are
-	// committed to stable storage.
-	// If it contains a MsgSnap message, the application MUST report back to raft
-	// when the snapshot has been received or has failed by calling ReportSnapshot.
-	Messages []pb.Message
-
-	// MustSync indicates whether the HardState and Entries must be synchronously
-	// written to disk or if an asynchronous write is permissible.
-	MustSync bool
-}
-
-func isHardStateEqual(a, b pb.HardState) bool {
-	return a.Term == b.Term && a.Vote == b.Vote && a.Commit == b.Commit
-}
-
-// IsEmptyHardState returns true if the given HardState is empty.
-func IsEmptyHardState(st pb.HardState) bool {
-	return isHardStateEqual(st, emptyState)
-}
-
-// IsEmptySnap returns true if the given Snapshot is empty.
-func IsEmptySnap(sp pb.Snapshot) bool {
-	return sp.Metadata.Index == 0
-}
-
-func (rd Ready) containsUpdates() bool {
-	return rd.SoftState != nil || !IsEmptyHardState(rd.HardState) ||
-		!IsEmptySnap(rd.Snapshot) || len(rd.Entries) > 0 ||
-		len(rd.CommittedEntries) > 0 || len(rd.Messages) > 0 || len(rd.ReadStates) != 0
-}
-
-// Node represents a node in a raft cluster.
-type Node interface {
-	// Tick increments the internal logical clock for the Node by a single tick. Election
-	// timeouts and heartbeat timeouts are in units of ticks.
-	Tick()
-	// Campaign causes the Node to transition to candidate state and start campaigning to become leader.
-	Campaign(ctx context.Context) error
-	// Propose proposes that data be appended to the log.
-	Propose(ctx context.Context, data []byte) error
-	// ProposeConfChange proposes config change.
-	// At most one ConfChange can be in the process of going through consensus.
-	// Application needs to call ApplyConfChange when applying EntryConfChange type entry.
-	ProposeConfChange(ctx context.Context, cc pb.ConfChange) error
-	// Step advances the state machine using the given message. ctx.Err() will be returned, if any.
-	Step(ctx context.Context, msg pb.Message) error
-
-	// Ready returns a channel that returns the current point-in-time state.
-	// Users of the Node must call Advance after retrieving the state returned by Ready.
-	//
-	// NOTE: No committed entries from the next Ready may be applied until all committed entries
-	// and snapshots from the previous one have finished.
-	Ready() <-chan Ready
-
-	// Advance notifies the Node that the application has saved progress up to the last Ready.
-	// It prepares the node to return the next available Ready.
-	//
-	// The application should generally call Advance after it applies the entries in last Ready.
-	//
-	// However, as an optimization, the application may call Advance while it is applying the
-	// commands. For example. when the last Ready contains a snapshot, the application might take
-	// a long time to apply the snapshot data. To continue receiving Ready without blocking raft
-	// progress, it can call Advance before finishing applying the last ready.
-	Advance()
-	// ApplyConfChange applies config change to the local node.
-	// Returns an opaque ConfState protobuf which must be recorded
-	// in snapshots. Will never return nil; it returns a pointer only
-	// to match MemoryStorage.Compact.
-	ApplyConfChange(cc pb.ConfChange) *pb.ConfState
-
-	// TransferLeadership attempts to transfer leadership to the given transferee.
-	TransferLeadership(ctx context.Context, lead, transferee uint64)
-
-	// ReadIndex request a read state. The read state will be set in the ready.
-	// Read state has a read index. Once the application advances further than the read
-	// index, any linearizable read requests issued before the read request can be
-	// processed safely. The read state will have the same rctx attached.
-	ReadIndex(ctx context.Context, rctx []byte) error
-
-	// Status returns the current status of the raft state machine.
-	Status() Status
-	// ReportUnreachable reports the given node is not reachable for the last send.
-	ReportUnreachable(id uint64)
-	// ReportSnapshot reports the status of the sent snapshot.
-	ReportSnapshot(id uint64, status SnapshotStatus)
-	// Stop performs any necessary termination of the Node.
-	Stop()
-}
-
-type Peer struct {
-	ID      uint64
-	Context []byte
-}
-
-// StartNode returns a new Node given configuration and a list of raft peers.
-// It appends a ConfChangeAddNode entry for each given peer to the initial log.
-func StartNode(c *Config, peers []Peer) Node {
-	r := newRaft(c)
-	// become the follower at term 1 and apply initial configuration
-	// entries of term 1
-	r.becomeFollower(1, None)
-	for _, peer := range peers {
-		cc := pb.ConfChange{Type: pb.ConfChangeAddNode, NodeID: peer.ID, Context: peer.Context}
-		d, err := cc.Marshal()
-		if err != nil {
-			panic("unexpected marshal error")
-		}
-		e := pb.Entry{Type: pb.EntryConfChange, Term: 1, Index: r.raftLog.lastIndex() + 1, Data: d}
-		r.raftLog.append(e)
-	}
-	// Mark these initial entries as committed.
-	// TODO(bdarnell): These entries are still unstable; do we need to preserve
-	// the invariant that committed < unstable?
-	r.raftLog.committed = r.raftLog.lastIndex()
-	// Now apply them, mainly so that the application can call Campaign
-	// immediately after StartNode in tests. Note that these nodes will
-	// be added to raft twice: here and when the application's Ready
-	// loop calls ApplyConfChange. The calls to addNode must come after
-	// all calls to raftLog.append so progress.next is set after these
-	// bootstrapping entries (it is an error if we try to append these
-	// entries since they have already been committed).
-	// We do not set raftLog.applied so the application will be able
-	// to observe all conf changes via Ready.CommittedEntries.
-	for _, peer := range peers {
-		r.addNode(peer.ID)
-	}
-
-	n := newNode()
-	n.logger = c.Logger
-	go n.run(r)
-	return &n
-}
-
-// RestartNode is similar to StartNode but does not take a list of peers.
-// The current membership of the cluster will be restored from the Storage.
-// If the caller has an existing state machine, pass in the last log index that
-// has been applied to it; otherwise use zero.
-func RestartNode(c *Config) Node {
-	r := newRaft(c)
-
-	n := newNode()
-	n.logger = c.Logger
-	go n.run(r)
-	return &n
-}
-
-// node is the canonical implementation of the Node interface
-type node struct {
-	propc      chan pb.Message
-	recvc      chan pb.Message
-	confc      chan pb.ConfChange
-	confstatec chan pb.ConfState
-	readyc     chan Ready
-	advancec   chan struct{}
-	tickc      chan struct{}
-	done       chan struct{}
-	stop       chan struct{}
-	status     chan chan Status
-
-	logger Logger
-}
-
-func newNode() node {
-	return node{
-		propc:      make(chan pb.Message),
-		recvc:      make(chan pb.Message),
-		confc:      make(chan pb.ConfChange),
-		confstatec: make(chan pb.ConfState),
-		readyc:     make(chan Ready),
-		advancec:   make(chan struct{}),
-		// make tickc a buffered chan, so raft node can buffer some ticks when the node
-		// is busy processing raft messages. Raft node will resume process buffered
-		// ticks when it becomes idle.
-		tickc:  make(chan struct{}, 128),
-		done:   make(chan struct{}),
-		stop:   make(chan struct{}),
-		status: make(chan chan Status),
-	}
-}
-
-func (n *node) Stop() {
-	select {
-	case n.stop <- struct{}{}:
-		// Not already stopped, so trigger it
-	case <-n.done:
-		// Node has already been stopped - no need to do anything
-		return
-	}
-	// Block until the stop has been acknowledged by run()
-	<-n.done
-}
-
-func (n *node) run(r *raft) {
-	var propc chan pb.Message
-	var readyc chan Ready
-	var advancec chan struct{}
-	var prevLastUnstablei, prevLastUnstablet uint64
-	var havePrevLastUnstablei bool
-	var prevSnapi uint64
-	var rd Ready
-
-	lead := None
-	prevSoftSt := r.softState()
-	prevHardSt := emptyState
-
-	for {
-		if advancec != nil {
-			readyc = nil
-		} else {
-			rd = newReady(r, prevSoftSt, prevHardSt)
-			if rd.containsUpdates() {
-				readyc = n.readyc
-			} else {
-				readyc = nil
-			}
-		}
-
-		if lead != r.lead {
-			if r.hasLeader() {
-				if lead == None {
-					r.logger.Infof("raft.node: %x elected leader %x at term %d", r.id, r.lead, r.Term)
-				} else {
-					r.logger.Infof("raft.node: %x changed leader from %x to %x at term %d", r.id, lead, r.lead, r.Term)
-				}
-				propc = n.propc
-			} else {
-				r.logger.Infof("raft.node: %x lost leader %x at term %d", r.id, lead, r.Term)
-				propc = nil
-			}
-			lead = r.lead
-		}
-
-		select {
-		// TODO: maybe buffer the config propose if there exists one (the way
-		// described in raft dissertation)
-		// Currently it is dropped in Step silently.
-		case m := <-propc:
-			m.From = r.id
-			r.Step(m)
-		case m := <-n.recvc:
-			// filter out response message from unknown From.
-			if pr := r.getProgress(m.From); pr != nil || !IsResponseMsg(m.Type) {
-				r.Step(m) // raft never returns an error
-			}
-		case cc := <-n.confc:
-			if cc.NodeID == None {
-				r.resetPendingConf()
-				select {
-				case n.confstatec <- pb.ConfState{Nodes: r.nodes()}:
-				case <-n.done:
-				}
-				break
-			}
-			switch cc.Type {
-			case pb.ConfChangeAddNode:
-				r.addNode(cc.NodeID)
-			case pb.ConfChangeAddLearnerNode:
-				r.addLearner(cc.NodeID)
-			case pb.ConfChangeRemoveNode:
-				// block incoming proposal when local node is
-				// removed
-				if cc.NodeID == r.id {
-					propc = nil
-				}
-				r.removeNode(cc.NodeID)
-			case pb.ConfChangeUpdateNode:
-				r.resetPendingConf()
-			default:
-				panic("unexpected conf type")
-			}
-			select {
-			case n.confstatec <- pb.ConfState{Nodes: r.nodes()}:
-			case <-n.done:
-			}
-		case <-n.tickc:
-			r.tick()
-		case readyc <- rd:
-			if rd.SoftState != nil {
-				prevSoftSt = rd.SoftState
-			}
-			if len(rd.Entries) > 0 {
-				prevLastUnstablei = rd.Entries[len(rd.Entries)-1].Index
-				prevLastUnstablet = rd.Entries[len(rd.Entries)-1].Term
-				havePrevLastUnstablei = true
-			}
-			if !IsEmptyHardState(rd.HardState) {
-				prevHardSt = rd.HardState
-			}
-			if !IsEmptySnap(rd.Snapshot) {
-				prevSnapi = rd.Snapshot.Metadata.Index
-			}
-
-			r.msgs = nil
-			r.readStates = nil
-			advancec = n.advancec
-		case <-advancec:
-			if prevHardSt.Commit != 0 {
-				r.raftLog.appliedTo(prevHardSt.Commit)
-			}
-			if havePrevLastUnstablei {
-				r.raftLog.stableTo(prevLastUnstablei, prevLastUnstablet)
-				havePrevLastUnstablei = false
-			}
-			r.raftLog.stableSnapTo(prevSnapi)
-			advancec = nil
-		case c := <-n.status:
-			c <- getStatus(r)
-		case <-n.stop:
-			close(n.done)
-			return
-		}
-	}
-}
-
-// Tick increments the internal logical clock for this Node. Election timeouts
-// and heartbeat timeouts are in units of ticks.
-func (n *node) Tick() {
-	select {
-	case n.tickc <- struct{}{}:
-	case <-n.done:
-	default:
-		n.logger.Warningf("A tick missed to fire. Node blocks too long!")
-	}
-}
-
-func (n *node) Campaign(ctx context.Context) error { return n.step(ctx, pb.Message{Type: pb.MsgHup}) }
-
-func (n *node) Propose(ctx context.Context, data []byte) error {
-	return n.step(ctx, pb.Message{Type: pb.MsgProp, Entries: []pb.Entry{{Data: data}}})
-}
-
-func (n *node) Step(ctx context.Context, m pb.Message) error {
-	// ignore unexpected local messages receiving over network
-	if IsLocalMsg(m.Type) {
-		// TODO: return an error?
-		return nil
-	}
-	return n.step(ctx, m)
-}
-
-func (n *node) ProposeConfChange(ctx context.Context, cc pb.ConfChange) error {
-	data, err := cc.Marshal()
-	if err != nil {
-		return err
-	}
-	return n.Step(ctx, pb.Message{Type: pb.MsgProp, Entries: []pb.Entry{{Type: pb.EntryConfChange, Data: data}}})
-}
-
-// Step advances the state machine using msgs. The ctx.Err() will be returned,
-// if any.
-func (n *node) step(ctx context.Context, m pb.Message) error {
-	ch := n.recvc
-	if m.Type == pb.MsgProp {
-		ch = n.propc
-	}
-
-	select {
-	case ch <- m:
-		return nil
-	case <-ctx.Done():
-		return ctx.Err()
-	case <-n.done:
-		return ErrStopped
-	}
-}
-
-func (n *node) Ready() <-chan Ready { return n.readyc }
-
-func (n *node) Advance() {
-	select {
-	case n.advancec <- struct{}{}:
-	case <-n.done:
-	}
-}
-
-func (n *node) ApplyConfChange(cc pb.ConfChange) *pb.ConfState {
-	var cs pb.ConfState
-	select {
-	case n.confc <- cc:
-	case <-n.done:
-	}
-	select {
-	case cs = <-n.confstatec:
-	case <-n.done:
-	}
-	return &cs
-}
-
-func (n *node) Status() Status {
-	c := make(chan Status)
-	select {
-	case n.status <- c:
-		return <-c
-	case <-n.done:
-		return Status{}
-	}
-}
-
-func (n *node) ReportUnreachable(id uint64) {
-	select {
-	case n.recvc <- pb.Message{Type: pb.MsgUnreachable, From: id}:
-	case <-n.done:
-	}
-}
-
-func (n *node) ReportSnapshot(id uint64, status SnapshotStatus) {
-	rej := status == SnapshotFailure
-
-	select {
-	case n.recvc <- pb.Message{Type: pb.MsgSnapStatus, From: id, Reject: rej}:
-	case <-n.done:
-	}
-}
-
-func (n *node) TransferLeadership(ctx context.Context, lead, transferee uint64) {
-	select {
-	// manually set 'from' and 'to', so that leader can voluntarily transfers its leadership
-	case n.recvc <- pb.Message{Type: pb.MsgTransferLeader, From: transferee, To: lead}:
-	case <-n.done:
-	case <-ctx.Done():
-	}
-}
-
-func (n *node) ReadIndex(ctx context.Context, rctx []byte) error {
-	return n.step(ctx, pb.Message{Type: pb.MsgReadIndex, Entries: []pb.Entry{{Data: rctx}}})
-}
-
-func newReady(r *raft, prevSoftSt *SoftState, prevHardSt pb.HardState) Ready {
-	rd := Ready{
-		Entries:          r.raftLog.unstableEntries(),
-		CommittedEntries: r.raftLog.nextEnts(),
-		Messages:         r.msgs,
-	}
-	if softSt := r.softState(); !softSt.equal(prevSoftSt) {
-		rd.SoftState = softSt
-	}
-	if hardSt := r.hardState(); !isHardStateEqual(hardSt, prevHardSt) {
-		rd.HardState = hardSt
-	}
-	if r.raftLog.unstable.snapshot != nil {
-		rd.Snapshot = *r.raftLog.unstable.snapshot
-	}
-	if len(r.readStates) != 0 {
-		rd.ReadStates = r.readStates
-	}
-	rd.MustSync = MustSync(rd.HardState, prevHardSt, len(rd.Entries))
-	return rd
-}
-
-// MustSync returns true if the hard state and count of Raft entries indicate
-// that a synchronous write to persistent storage is required.
-func MustSync(st, prevst pb.HardState, entsnum int) bool {
-	// Persistent state on all servers:
-	// (Updated on stable storage before responding to RPCs)
-	// currentTerm
-	// votedFor
-	// log entries[]
-	return entsnum != 0 || st.Vote != prevst.Vote || st.Term != prevst.Term
-}
diff --git a/vendor/github.com/coreos/etcd/raft/progress.go b/vendor/github.com/coreos/etcd/raft/progress.go
deleted file mode 100644
index ef3787d..0000000
--- a/vendor/github.com/coreos/etcd/raft/progress.go
+++ /dev/null
@@ -1,284 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import "fmt"
-
-const (
-	ProgressStateProbe ProgressStateType = iota
-	ProgressStateReplicate
-	ProgressStateSnapshot
-)
-
-type ProgressStateType uint64
-
-var prstmap = [...]string{
-	"ProgressStateProbe",
-	"ProgressStateReplicate",
-	"ProgressStateSnapshot",
-}
-
-func (st ProgressStateType) String() string { return prstmap[uint64(st)] }
-
-// Progress represents a follower’s progress in the view of the leader. Leader maintains
-// progresses of all followers, and sends entries to the follower based on its progress.
-type Progress struct {
-	Match, Next uint64
-	// State defines how the leader should interact with the follower.
-	//
-	// When in ProgressStateProbe, leader sends at most one replication message
-	// per heartbeat interval. It also probes actual progress of the follower.
-	//
-	// When in ProgressStateReplicate, leader optimistically increases next
-	// to the latest entry sent after sending replication message. This is
-	// an optimized state for fast replicating log entries to the follower.
-	//
-	// When in ProgressStateSnapshot, leader should have sent out snapshot
-	// before and stops sending any replication message.
-	State ProgressStateType
-
-	// Paused is used in ProgressStateProbe.
-	// When Paused is true, raft should pause sending replication message to this peer.
-	Paused bool
-	// PendingSnapshot is used in ProgressStateSnapshot.
-	// If there is a pending snapshot, the pendingSnapshot will be set to the
-	// index of the snapshot. If pendingSnapshot is set, the replication process of
-	// this Progress will be paused. raft will not resend snapshot until the pending one
-	// is reported to be failed.
-	PendingSnapshot uint64
-
-	// RecentActive is true if the progress is recently active. Receiving any messages
-	// from the corresponding follower indicates the progress is active.
-	// RecentActive can be reset to false after an election timeout.
-	RecentActive bool
-
-	// inflights is a sliding window for the inflight messages.
-	// Each inflight message contains one or more log entries.
-	// The max number of entries per message is defined in raft config as MaxSizePerMsg.
-	// Thus inflight effectively limits both the number of inflight messages
-	// and the bandwidth each Progress can use.
-	// When inflights is full, no more message should be sent.
-	// When a leader sends out a message, the index of the last
-	// entry should be added to inflights. The index MUST be added
-	// into inflights in order.
-	// When a leader receives a reply, the previous inflights should
-	// be freed by calling inflights.freeTo with the index of the last
-	// received entry.
-	ins *inflights
-
-	// IsLearner is true if this progress is tracked for a learner.
-	IsLearner bool
-}
-
-func (pr *Progress) resetState(state ProgressStateType) {
-	pr.Paused = false
-	pr.PendingSnapshot = 0
-	pr.State = state
-	pr.ins.reset()
-}
-
-func (pr *Progress) becomeProbe() {
-	// If the original state is ProgressStateSnapshot, progress knows that
-	// the pending snapshot has been sent to this peer successfully, then
-	// probes from pendingSnapshot + 1.
-	if pr.State == ProgressStateSnapshot {
-		pendingSnapshot := pr.PendingSnapshot
-		pr.resetState(ProgressStateProbe)
-		pr.Next = max(pr.Match+1, pendingSnapshot+1)
-	} else {
-		pr.resetState(ProgressStateProbe)
-		pr.Next = pr.Match + 1
-	}
-}
-
-func (pr *Progress) becomeReplicate() {
-	pr.resetState(ProgressStateReplicate)
-	pr.Next = pr.Match + 1
-}
-
-func (pr *Progress) becomeSnapshot(snapshoti uint64) {
-	pr.resetState(ProgressStateSnapshot)
-	pr.PendingSnapshot = snapshoti
-}
-
-// maybeUpdate returns false if the given n index comes from an outdated message.
-// Otherwise it updates the progress and returns true.
-func (pr *Progress) maybeUpdate(n uint64) bool {
-	var updated bool
-	if pr.Match < n {
-		pr.Match = n
-		updated = true
-		pr.resume()
-	}
-	if pr.Next < n+1 {
-		pr.Next = n + 1
-	}
-	return updated
-}
-
-func (pr *Progress) optimisticUpdate(n uint64) { pr.Next = n + 1 }
-
-// maybeDecrTo returns false if the given to index comes from an out of order message.
-// Otherwise it decreases the progress next index to min(rejected, last) and returns true.
-func (pr *Progress) maybeDecrTo(rejected, last uint64) bool {
-	if pr.State == ProgressStateReplicate {
-		// the rejection must be stale if the progress has matched and "rejected"
-		// is smaller than "match".
-		if rejected <= pr.Match {
-			return false
-		}
-		// directly decrease next to match + 1
-		pr.Next = pr.Match + 1
-		return true
-	}
-
-	// the rejection must be stale if "rejected" does not match next - 1
-	if pr.Next-1 != rejected {
-		return false
-	}
-
-	if pr.Next = min(rejected, last+1); pr.Next < 1 {
-		pr.Next = 1
-	}
-	pr.resume()
-	return true
-}
-
-func (pr *Progress) pause()  { pr.Paused = true }
-func (pr *Progress) resume() { pr.Paused = false }
-
-// IsPaused returns whether sending log entries to this node has been
-// paused. A node may be paused because it has rejected recent
-// MsgApps, is currently waiting for a snapshot, or has reached the
-// MaxInflightMsgs limit.
-func (pr *Progress) IsPaused() bool {
-	switch pr.State {
-	case ProgressStateProbe:
-		return pr.Paused
-	case ProgressStateReplicate:
-		return pr.ins.full()
-	case ProgressStateSnapshot:
-		return true
-	default:
-		panic("unexpected state")
-	}
-}
-
-func (pr *Progress) snapshotFailure() { pr.PendingSnapshot = 0 }
-
-// needSnapshotAbort returns true if snapshot progress's Match
-// is equal or higher than the pendingSnapshot.
-func (pr *Progress) needSnapshotAbort() bool {
-	return pr.State == ProgressStateSnapshot && pr.Match >= pr.PendingSnapshot
-}
-
-func (pr *Progress) String() string {
-	return fmt.Sprintf("next = %d, match = %d, state = %s, waiting = %v, pendingSnapshot = %d", pr.Next, pr.Match, pr.State, pr.IsPaused(), pr.PendingSnapshot)
-}
-
-type inflights struct {
-	// the starting index in the buffer
-	start int
-	// number of inflights in the buffer
-	count int
-
-	// the size of the buffer
-	size int
-
-	// buffer contains the index of the last entry
-	// inside one message.
-	buffer []uint64
-}
-
-func newInflights(size int) *inflights {
-	return &inflights{
-		size: size,
-	}
-}
-
-// add adds an inflight into inflights
-func (in *inflights) add(inflight uint64) {
-	if in.full() {
-		panic("cannot add into a full inflights")
-	}
-	next := in.start + in.count
-	size := in.size
-	if next >= size {
-		next -= size
-	}
-	if next >= len(in.buffer) {
-		in.growBuf()
-	}
-	in.buffer[next] = inflight
-	in.count++
-}
-
-// grow the inflight buffer by doubling up to inflights.size. We grow on demand
-// instead of preallocating to inflights.size to handle systems which have
-// thousands of Raft groups per process.
-func (in *inflights) growBuf() {
-	newSize := len(in.buffer) * 2
-	if newSize == 0 {
-		newSize = 1
-	} else if newSize > in.size {
-		newSize = in.size
-	}
-	newBuffer := make([]uint64, newSize)
-	copy(newBuffer, in.buffer)
-	in.buffer = newBuffer
-}
-
-// freeTo frees the inflights smaller or equal to the given `to` flight.
-func (in *inflights) freeTo(to uint64) {
-	if in.count == 0 || to < in.buffer[in.start] {
-		// out of the left side of the window
-		return
-	}
-
-	idx := in.start
-	var i int
-	for i = 0; i < in.count; i++ {
-		if to < in.buffer[idx] { // found the first large inflight
-			break
-		}
-
-		// increase index and maybe rotate
-		size := in.size
-		if idx++; idx >= size {
-			idx -= size
-		}
-	}
-	// free i inflights and set new start index
-	in.count -= i
-	in.start = idx
-	if in.count == 0 {
-		// inflights is empty, reset the start index so that we don't grow the
-		// buffer unnecessarily.
-		in.start = 0
-	}
-}
-
-func (in *inflights) freeFirstOne() { in.freeTo(in.buffer[in.start]) }
-
-// full returns true if the inflights is full.
-func (in *inflights) full() bool {
-	return in.count == in.size
-}
-
-// resets frees all inflights.
-func (in *inflights) reset() {
-	in.count = 0
-	in.start = 0
-}
diff --git a/vendor/github.com/coreos/etcd/raft/raft.go b/vendor/github.com/coreos/etcd/raft/raft.go
deleted file mode 100644
index b4c0f02..0000000
--- a/vendor/github.com/coreos/etcd/raft/raft.go
+++ /dev/null
@@ -1,1406 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"math"
-	"math/rand"
-	"sort"
-	"strings"
-	"sync"
-	"time"
-
-	pb "github.com/coreos/etcd/raft/raftpb"
-)
-
-// None is a placeholder node ID used when there is no leader.
-const None uint64 = 0
-const noLimit = math.MaxUint64
-
-// Possible values for StateType.
-const (
-	StateFollower StateType = iota
-	StateCandidate
-	StateLeader
-	StatePreCandidate
-	numStates
-)
-
-type ReadOnlyOption int
-
-const (
-	// ReadOnlySafe guarantees the linearizability of the read only request by
-	// communicating with the quorum. It is the default and suggested option.
-	ReadOnlySafe ReadOnlyOption = iota
-	// ReadOnlyLeaseBased ensures linearizability of the read only request by
-	// relying on the leader lease. It can be affected by clock drift.
-	// If the clock drift is unbounded, leader might keep the lease longer than it
-	// should (clock can move backward/pause without any bound). ReadIndex is not safe
-	// in that case.
-	ReadOnlyLeaseBased
-)
-
-// Possible values for CampaignType
-const (
-	// campaignPreElection represents the first phase of a normal election when
-	// Config.PreVote is true.
-	campaignPreElection CampaignType = "CampaignPreElection"
-	// campaignElection represents a normal (time-based) election (the second phase
-	// of the election when Config.PreVote is true).
-	campaignElection CampaignType = "CampaignElection"
-	// campaignTransfer represents the type of leader transfer
-	campaignTransfer CampaignType = "CampaignTransfer"
-)
-
-// lockedRand is a small wrapper around rand.Rand to provide
-// synchronization. Only the methods needed by the code are exposed
-// (e.g. Intn).
-type lockedRand struct {
-	mu   sync.Mutex
-	rand *rand.Rand
-}
-
-func (r *lockedRand) Intn(n int) int {
-	r.mu.Lock()
-	v := r.rand.Intn(n)
-	r.mu.Unlock()
-	return v
-}
-
-var globalRand = &lockedRand{
-	rand: rand.New(rand.NewSource(time.Now().UnixNano())),
-}
-
-// CampaignType represents the type of campaigning
-// the reason we use the type of string instead of uint64
-// is because it's simpler to compare and fill in raft entries
-type CampaignType string
-
-// StateType represents the role of a node in a cluster.
-type StateType uint64
-
-var stmap = [...]string{
-	"StateFollower",
-	"StateCandidate",
-	"StateLeader",
-	"StatePreCandidate",
-}
-
-func (st StateType) String() string {
-	return stmap[uint64(st)]
-}
-
-// Config contains the parameters to start a raft.
-type Config struct {
-	// ID is the identity of the local raft. ID cannot be 0.
-	ID uint64
-
-	// peers contains the IDs of all nodes (including self) in the raft cluster. It
-	// should only be set when starting a new raft cluster. Restarting raft from
-	// previous configuration will panic if peers is set. peer is private and only
-	// used for testing right now.
-	peers []uint64
-
-	// learners contains the IDs of all leaner nodes (including self if the local node is a leaner) in the raft cluster.
-	// learners only receives entries from the leader node. It does not vote or promote itself.
-	learners []uint64
-
-	// ElectionTick is the number of Node.Tick invocations that must pass between
-	// elections. That is, if a follower does not receive any message from the
-	// leader of current term before ElectionTick has elapsed, it will become
-	// candidate and start an election. ElectionTick must be greater than
-	// HeartbeatTick. We suggest ElectionTick = 10 * HeartbeatTick to avoid
-	// unnecessary leader switching.
-	ElectionTick int
-	// HeartbeatTick is the number of Node.Tick invocations that must pass between
-	// heartbeats. That is, a leader sends heartbeat messages to maintain its
-	// leadership every HeartbeatTick ticks.
-	HeartbeatTick int
-
-	// Storage is the storage for raft. raft generates entries and states to be
-	// stored in storage. raft reads the persisted entries and states out of
-	// Storage when it needs. raft reads out the previous state and configuration
-	// out of storage when restarting.
-	Storage Storage
-	// Applied is the last applied index. It should only be set when restarting
-	// raft. raft will not return entries to the application smaller or equal to
-	// Applied. If Applied is unset when restarting, raft might return previous
-	// applied entries. This is a very application dependent configuration.
-	Applied uint64
-
-	// MaxSizePerMsg limits the max size of each append message. Smaller value
-	// lowers the raft recovery cost(initial probing and message lost during normal
-	// operation). On the other side, it might affect the throughput during normal
-	// replication. Note: math.MaxUint64 for unlimited, 0 for at most one entry per
-	// message.
-	MaxSizePerMsg uint64
-	// MaxInflightMsgs limits the max number of in-flight append messages during
-	// optimistic replication phase. The application transportation layer usually
-	// has its own sending buffer over TCP/UDP. Setting MaxInflightMsgs to avoid
-	// overflowing that sending buffer. TODO (xiangli): feedback to application to
-	// limit the proposal rate?
-	MaxInflightMsgs int
-
-	// CheckQuorum specifies if the leader should check quorum activity. Leader
-	// steps down when quorum is not active for an electionTimeout.
-	CheckQuorum bool
-
-	// PreVote enables the Pre-Vote algorithm described in raft thesis section
-	// 9.6. This prevents disruption when a node that has been partitioned away
-	// rejoins the cluster.
-	PreVote bool
-
-	// ReadOnlyOption specifies how the read only request is processed.
-	//
-	// ReadOnlySafe guarantees the linearizability of the read only request by
-	// communicating with the quorum. It is the default and suggested option.
-	//
-	// ReadOnlyLeaseBased ensures linearizability of the read only request by
-	// relying on the leader lease. It can be affected by clock drift.
-	// If the clock drift is unbounded, leader might keep the lease longer than it
-	// should (clock can move backward/pause without any bound). ReadIndex is not safe
-	// in that case.
-	// CheckQuorum MUST be enabled if ReadOnlyOption is ReadOnlyLeaseBased.
-	ReadOnlyOption ReadOnlyOption
-
-	// Logger is the logger used for raft log. For multinode which can host
-	// multiple raft group, each raft group can have its own logger
-	Logger Logger
-
-	// DisableProposalForwarding set to true means that followers will drop
-	// proposals, rather than forwarding them to the leader. One use case for
-	// this feature would be in a situation where the Raft leader is used to
-	// compute the data of a proposal, for example, adding a timestamp from a
-	// hybrid logical clock to data in a monotonically increasing way. Forwarding
-	// should be disabled to prevent a follower with an innaccurate hybrid
-	// logical clock from assigning the timestamp and then forwarding the data
-	// to the leader.
-	DisableProposalForwarding bool
-}
-
-func (c *Config) validate() error {
-	if c.ID == None {
-		return errors.New("cannot use none as id")
-	}
-
-	if c.HeartbeatTick <= 0 {
-		return errors.New("heartbeat tick must be greater than 0")
-	}
-
-	if c.ElectionTick <= c.HeartbeatTick {
-		return errors.New("election tick must be greater than heartbeat tick")
-	}
-
-	if c.Storage == nil {
-		return errors.New("storage cannot be nil")
-	}
-
-	if c.MaxInflightMsgs <= 0 {
-		return errors.New("max inflight messages must be greater than 0")
-	}
-
-	if c.Logger == nil {
-		c.Logger = raftLogger
-	}
-
-	if c.ReadOnlyOption == ReadOnlyLeaseBased && !c.CheckQuorum {
-		return errors.New("CheckQuorum must be enabled when ReadOnlyOption is ReadOnlyLeaseBased")
-	}
-
-	return nil
-}
-
-type raft struct {
-	id uint64
-
-	Term uint64
-	Vote uint64
-
-	readStates []ReadState
-
-	// the log
-	raftLog *raftLog
-
-	maxInflight int
-	maxMsgSize  uint64
-	prs         map[uint64]*Progress
-	learnerPrs  map[uint64]*Progress
-
-	state StateType
-
-	// isLearner is true if the local raft node is a learner.
-	isLearner bool
-
-	votes map[uint64]bool
-
-	msgs []pb.Message
-
-	// the leader id
-	lead uint64
-	// leadTransferee is id of the leader transfer target when its value is not zero.
-	// Follow the procedure defined in raft thesis 3.10.
-	leadTransferee uint64
-	// New configuration is ignored if there exists unapplied configuration.
-	pendingConf bool
-
-	readOnly *readOnly
-
-	// number of ticks since it reached last electionTimeout when it is leader
-	// or candidate.
-	// number of ticks since it reached last electionTimeout or received a
-	// valid message from current leader when it is a follower.
-	electionElapsed int
-
-	// number of ticks since it reached last heartbeatTimeout.
-	// only leader keeps heartbeatElapsed.
-	heartbeatElapsed int
-
-	checkQuorum bool
-	preVote     bool
-
-	heartbeatTimeout int
-	electionTimeout  int
-	// randomizedElectionTimeout is a random number between
-	// [electiontimeout, 2 * electiontimeout - 1]. It gets reset
-	// when raft changes its state to follower or candidate.
-	randomizedElectionTimeout int
-	disableProposalForwarding bool
-
-	tick func()
-	step stepFunc
-
-	logger Logger
-}
-
-func newRaft(c *Config) *raft {
-	if err := c.validate(); err != nil {
-		panic(err.Error())
-	}
-	raftlog := newLog(c.Storage, c.Logger)
-	hs, cs, err := c.Storage.InitialState()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-	peers := c.peers
-	learners := c.learners
-	if len(cs.Nodes) > 0 || len(cs.Learners) > 0 {
-		if len(peers) > 0 || len(learners) > 0 {
-			// TODO(bdarnell): the peers argument is always nil except in
-			// tests; the argument should be removed and these tests should be
-			// updated to specify their nodes through a snapshot.
-			panic("cannot specify both newRaft(peers, learners) and ConfState.(Nodes, Learners)")
-		}
-		peers = cs.Nodes
-		learners = cs.Learners
-	}
-	r := &raft{
-		id:                        c.ID,
-		lead:                      None,
-		isLearner:                 false,
-		raftLog:                   raftlog,
-		maxMsgSize:                c.MaxSizePerMsg,
-		maxInflight:               c.MaxInflightMsgs,
-		prs:                       make(map[uint64]*Progress),
-		learnerPrs:                make(map[uint64]*Progress),
-		electionTimeout:           c.ElectionTick,
-		heartbeatTimeout:          c.HeartbeatTick,
-		logger:                    c.Logger,
-		checkQuorum:               c.CheckQuorum,
-		preVote:                   c.PreVote,
-		readOnly:                  newReadOnly(c.ReadOnlyOption),
-		disableProposalForwarding: c.DisableProposalForwarding,
-	}
-	for _, p := range peers {
-		r.prs[p] = &Progress{Next: 1, ins: newInflights(r.maxInflight)}
-	}
-	for _, p := range learners {
-		if _, ok := r.prs[p]; ok {
-			panic(fmt.Sprintf("node %x is in both learner and peer list", p))
-		}
-		r.learnerPrs[p] = &Progress{Next: 1, ins: newInflights(r.maxInflight), IsLearner: true}
-		if r.id == p {
-			r.isLearner = true
-		}
-	}
-
-	if !isHardStateEqual(hs, emptyState) {
-		r.loadState(hs)
-	}
-	if c.Applied > 0 {
-		raftlog.appliedTo(c.Applied)
-	}
-	r.becomeFollower(r.Term, None)
-
-	var nodesStrs []string
-	for _, n := range r.nodes() {
-		nodesStrs = append(nodesStrs, fmt.Sprintf("%x", n))
-	}
-
-	r.logger.Infof("newRaft %x [peers: [%s], term: %d, commit: %d, applied: %d, lastindex: %d, lastterm: %d]",
-		r.id, strings.Join(nodesStrs, ","), r.Term, r.raftLog.committed, r.raftLog.applied, r.raftLog.lastIndex(), r.raftLog.lastTerm())
-	return r
-}
-
-func (r *raft) hasLeader() bool { return r.lead != None }
-
-func (r *raft) softState() *SoftState { return &SoftState{Lead: r.lead, RaftState: r.state} }
-
-func (r *raft) hardState() pb.HardState {
-	return pb.HardState{
-		Term:   r.Term,
-		Vote:   r.Vote,
-		Commit: r.raftLog.committed,
-	}
-}
-
-func (r *raft) quorum() int { return len(r.prs)/2 + 1 }
-
-func (r *raft) nodes() []uint64 {
-	nodes := make([]uint64, 0, len(r.prs)+len(r.learnerPrs))
-	for id := range r.prs {
-		nodes = append(nodes, id)
-	}
-	for id := range r.learnerPrs {
-		nodes = append(nodes, id)
-	}
-	sort.Sort(uint64Slice(nodes))
-	return nodes
-}
-
-// send persists state to stable storage and then sends to its mailbox.
-func (r *raft) send(m pb.Message) {
-	m.From = r.id
-	if m.Type == pb.MsgVote || m.Type == pb.MsgVoteResp || m.Type == pb.MsgPreVote || m.Type == pb.MsgPreVoteResp {
-		if m.Term == 0 {
-			// All {pre-,}campaign messages need to have the term set when
-			// sending.
-			// - MsgVote: m.Term is the term the node is campaigning for,
-			//   non-zero as we increment the term when campaigning.
-			// - MsgVoteResp: m.Term is the new r.Term if the MsgVote was
-			//   granted, non-zero for the same reason MsgVote is
-			// - MsgPreVote: m.Term is the term the node will campaign,
-			//   non-zero as we use m.Term to indicate the next term we'll be
-			//   campaigning for
-			// - MsgPreVoteResp: m.Term is the term received in the original
-			//   MsgPreVote if the pre-vote was granted, non-zero for the
-			//   same reasons MsgPreVote is
-			panic(fmt.Sprintf("term should be set when sending %s", m.Type))
-		}
-	} else {
-		if m.Term != 0 {
-			panic(fmt.Sprintf("term should not be set when sending %s (was %d)", m.Type, m.Term))
-		}
-		// do not attach term to MsgProp, MsgReadIndex
-		// proposals are a way to forward to the leader and
-		// should be treated as local message.
-		// MsgReadIndex is also forwarded to leader.
-		if m.Type != pb.MsgProp && m.Type != pb.MsgReadIndex {
-			m.Term = r.Term
-		}
-	}
-	r.msgs = append(r.msgs, m)
-}
-
-func (r *raft) getProgress(id uint64) *Progress {
-	if pr, ok := r.prs[id]; ok {
-		return pr
-	}
-
-	return r.learnerPrs[id]
-}
-
-// sendAppend sends RPC, with entries to the given peer.
-func (r *raft) sendAppend(to uint64) {
-	pr := r.getProgress(to)
-	if pr.IsPaused() {
-		return
-	}
-	m := pb.Message{}
-	m.To = to
-
-	term, errt := r.raftLog.term(pr.Next - 1)
-	ents, erre := r.raftLog.entries(pr.Next, r.maxMsgSize)
-
-	if errt != nil || erre != nil { // send snapshot if we failed to get term or entries
-		if !pr.RecentActive {
-			r.logger.Debugf("ignore sending snapshot to %x since it is not recently active", to)
-			return
-		}
-
-		m.Type = pb.MsgSnap
-		snapshot, err := r.raftLog.snapshot()
-		if err != nil {
-			if err == ErrSnapshotTemporarilyUnavailable {
-				r.logger.Debugf("%x failed to send snapshot to %x because snapshot is temporarily unavailable", r.id, to)
-				return
-			}
-			panic(err) // TODO(bdarnell)
-		}
-		if IsEmptySnap(snapshot) {
-			panic("need non-empty snapshot")
-		}
-		m.Snapshot = snapshot
-		sindex, sterm := snapshot.Metadata.Index, snapshot.Metadata.Term
-		r.logger.Debugf("%x [firstindex: %d, commit: %d] sent snapshot[index: %d, term: %d] to %x [%s]",
-			r.id, r.raftLog.firstIndex(), r.raftLog.committed, sindex, sterm, to, pr)
-		pr.becomeSnapshot(sindex)
-		r.logger.Debugf("%x paused sending replication messages to %x [%s]", r.id, to, pr)
-	} else {
-		m.Type = pb.MsgApp
-		m.Index = pr.Next - 1
-		m.LogTerm = term
-		m.Entries = ents
-		m.Commit = r.raftLog.committed
-		if n := len(m.Entries); n != 0 {
-			switch pr.State {
-			// optimistically increase the next when in ProgressStateReplicate
-			case ProgressStateReplicate:
-				last := m.Entries[n-1].Index
-				pr.optimisticUpdate(last)
-				pr.ins.add(last)
-			case ProgressStateProbe:
-				pr.pause()
-			default:
-				r.logger.Panicf("%x is sending append in unhandled state %s", r.id, pr.State)
-			}
-		}
-	}
-	r.send(m)
-}
-
-// sendHeartbeat sends an empty MsgApp
-func (r *raft) sendHeartbeat(to uint64, ctx []byte) {
-	// Attach the commit as min(to.matched, r.committed).
-	// When the leader sends out heartbeat message,
-	// the receiver(follower) might not be matched with the leader
-	// or it might not have all the committed entries.
-	// The leader MUST NOT forward the follower's commit to
-	// an unmatched index.
-	commit := min(r.getProgress(to).Match, r.raftLog.committed)
-	m := pb.Message{
-		To:      to,
-		Type:    pb.MsgHeartbeat,
-		Commit:  commit,
-		Context: ctx,
-	}
-
-	r.send(m)
-}
-
-func (r *raft) forEachProgress(f func(id uint64, pr *Progress)) {
-	for id, pr := range r.prs {
-		f(id, pr)
-	}
-
-	for id, pr := range r.learnerPrs {
-		f(id, pr)
-	}
-}
-
-// bcastAppend sends RPC, with entries to all peers that are not up-to-date
-// according to the progress recorded in r.prs.
-func (r *raft) bcastAppend() {
-	r.forEachProgress(func(id uint64, _ *Progress) {
-		if id == r.id {
-			return
-		}
-
-		r.sendAppend(id)
-	})
-}
-
-// bcastHeartbeat sends RPC, without entries to all the peers.
-func (r *raft) bcastHeartbeat() {
-	lastCtx := r.readOnly.lastPendingRequestCtx()
-	if len(lastCtx) == 0 {
-		r.bcastHeartbeatWithCtx(nil)
-	} else {
-		r.bcastHeartbeatWithCtx([]byte(lastCtx))
-	}
-}
-
-func (r *raft) bcastHeartbeatWithCtx(ctx []byte) {
-	r.forEachProgress(func(id uint64, _ *Progress) {
-		if id == r.id {
-			return
-		}
-		r.sendHeartbeat(id, ctx)
-	})
-}
-
-// maybeCommit attempts to advance the commit index. Returns true if
-// the commit index changed (in which case the caller should call
-// r.bcastAppend).
-func (r *raft) maybeCommit() bool {
-	// TODO(bmizerany): optimize.. Currently naive
-	mis := make(uint64Slice, 0, len(r.prs))
-	for _, p := range r.prs {
-		mis = append(mis, p.Match)
-	}
-	sort.Sort(sort.Reverse(mis))
-	mci := mis[r.quorum()-1]
-	return r.raftLog.maybeCommit(mci, r.Term)
-}
-
-func (r *raft) reset(term uint64) {
-	if r.Term != term {
-		r.Term = term
-		r.Vote = None
-	}
-	r.lead = None
-
-	r.electionElapsed = 0
-	r.heartbeatElapsed = 0
-	r.resetRandomizedElectionTimeout()
-
-	r.abortLeaderTransfer()
-
-	r.votes = make(map[uint64]bool)
-	r.forEachProgress(func(id uint64, pr *Progress) {
-		*pr = Progress{Next: r.raftLog.lastIndex() + 1, ins: newInflights(r.maxInflight), IsLearner: pr.IsLearner}
-		if id == r.id {
-			pr.Match = r.raftLog.lastIndex()
-		}
-	})
-
-	r.pendingConf = false
-	r.readOnly = newReadOnly(r.readOnly.option)
-}
-
-func (r *raft) appendEntry(es ...pb.Entry) {
-	li := r.raftLog.lastIndex()
-	for i := range es {
-		es[i].Term = r.Term
-		es[i].Index = li + 1 + uint64(i)
-	}
-	r.raftLog.append(es...)
-	r.getProgress(r.id).maybeUpdate(r.raftLog.lastIndex())
-	// Regardless of maybeCommit's return, our caller will call bcastAppend.
-	r.maybeCommit()
-}
-
-// tickElection is run by followers and candidates after r.electionTimeout.
-func (r *raft) tickElection() {
-	r.electionElapsed++
-
-	if r.promotable() && r.pastElectionTimeout() {
-		r.electionElapsed = 0
-		r.Step(pb.Message{From: r.id, Type: pb.MsgHup})
-	}
-}
-
-// tickHeartbeat is run by leaders to send a MsgBeat after r.heartbeatTimeout.
-func (r *raft) tickHeartbeat() {
-	r.heartbeatElapsed++
-	r.electionElapsed++
-
-	if r.electionElapsed >= r.electionTimeout {
-		r.electionElapsed = 0
-		if r.checkQuorum {
-			r.Step(pb.Message{From: r.id, Type: pb.MsgCheckQuorum})
-		}
-		// If current leader cannot transfer leadership in electionTimeout, it becomes leader again.
-		if r.state == StateLeader && r.leadTransferee != None {
-			r.abortLeaderTransfer()
-		}
-	}
-
-	if r.state != StateLeader {
-		return
-	}
-
-	if r.heartbeatElapsed >= r.heartbeatTimeout {
-		r.heartbeatElapsed = 0
-		r.Step(pb.Message{From: r.id, Type: pb.MsgBeat})
-	}
-}
-
-func (r *raft) becomeFollower(term uint64, lead uint64) {
-	r.step = stepFollower
-	r.reset(term)
-	r.tick = r.tickElection
-	r.lead = lead
-	r.state = StateFollower
-	r.logger.Infof("%x became follower at term %d", r.id, r.Term)
-}
-
-func (r *raft) becomeCandidate() {
-	// TODO(xiangli) remove the panic when the raft implementation is stable
-	if r.state == StateLeader {
-		panic("invalid transition [leader -> candidate]")
-	}
-	r.step = stepCandidate
-	r.reset(r.Term + 1)
-	r.tick = r.tickElection
-	r.Vote = r.id
-	r.state = StateCandidate
-	r.logger.Infof("%x became candidate at term %d", r.id, r.Term)
-}
-
-func (r *raft) becomePreCandidate() {
-	// TODO(xiangli) remove the panic when the raft implementation is stable
-	if r.state == StateLeader {
-		panic("invalid transition [leader -> pre-candidate]")
-	}
-	// Becoming a pre-candidate changes our step functions and state,
-	// but doesn't change anything else. In particular it does not increase
-	// r.Term or change r.Vote.
-	r.step = stepCandidate
-	r.votes = make(map[uint64]bool)
-	r.tick = r.tickElection
-	r.state = StatePreCandidate
-	r.logger.Infof("%x became pre-candidate at term %d", r.id, r.Term)
-}
-
-func (r *raft) becomeLeader() {
-	// TODO(xiangli) remove the panic when the raft implementation is stable
-	if r.state == StateFollower {
-		panic("invalid transition [follower -> leader]")
-	}
-	r.step = stepLeader
-	r.reset(r.Term)
-	r.tick = r.tickHeartbeat
-	r.lead = r.id
-	r.state = StateLeader
-	ents, err := r.raftLog.entries(r.raftLog.committed+1, noLimit)
-	if err != nil {
-		r.logger.Panicf("unexpected error getting uncommitted entries (%v)", err)
-	}
-
-	nconf := numOfPendingConf(ents)
-	if nconf > 1 {
-		panic("unexpected multiple uncommitted config entry")
-	}
-	if nconf == 1 {
-		r.pendingConf = true
-	}
-
-	r.appendEntry(pb.Entry{Data: nil})
-	r.logger.Infof("%x became leader at term %d", r.id, r.Term)
-}
-
-func (r *raft) campaign(t CampaignType) {
-	var term uint64
-	var voteMsg pb.MessageType
-	if t == campaignPreElection {
-		r.becomePreCandidate()
-		voteMsg = pb.MsgPreVote
-		// PreVote RPCs are sent for the next term before we've incremented r.Term.
-		term = r.Term + 1
-	} else {
-		r.becomeCandidate()
-		voteMsg = pb.MsgVote
-		term = r.Term
-	}
-	if r.quorum() == r.poll(r.id, voteRespMsgType(voteMsg), true) {
-		// We won the election after voting for ourselves (which must mean that
-		// this is a single-node cluster). Advance to the next state.
-		if t == campaignPreElection {
-			r.campaign(campaignElection)
-		} else {
-			r.becomeLeader()
-		}
-		return
-	}
-	for id := range r.prs {
-		if id == r.id {
-			continue
-		}
-		r.logger.Infof("%x [logterm: %d, index: %d] sent %s request to %x at term %d",
-			r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), voteMsg, id, r.Term)
-
-		var ctx []byte
-		if t == campaignTransfer {
-			ctx = []byte(t)
-		}
-		r.send(pb.Message{Term: term, To: id, Type: voteMsg, Index: r.raftLog.lastIndex(), LogTerm: r.raftLog.lastTerm(), Context: ctx})
-	}
-}
-
-func (r *raft) poll(id uint64, t pb.MessageType, v bool) (granted int) {
-	if v {
-		r.logger.Infof("%x received %s from %x at term %d", r.id, t, id, r.Term)
-	} else {
-		r.logger.Infof("%x received %s rejection from %x at term %d", r.id, t, id, r.Term)
-	}
-	if _, ok := r.votes[id]; !ok {
-		r.votes[id] = v
-	}
-	for _, vv := range r.votes {
-		if vv {
-			granted++
-		}
-	}
-	return granted
-}
-
-func (r *raft) Step(m pb.Message) error {
-	// Handle the message term, which may result in our stepping down to a follower.
-	switch {
-	case m.Term == 0:
-		// local message
-	case m.Term > r.Term:
-		if m.Type == pb.MsgVote || m.Type == pb.MsgPreVote {
-			force := bytes.Equal(m.Context, []byte(campaignTransfer))
-			inLease := r.checkQuorum && r.lead != None && r.electionElapsed < r.electionTimeout
-			if !force && inLease {
-				// If a server receives a RequestVote request within the minimum election timeout
-				// of hearing from a current leader, it does not update its term or grant its vote
-				r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] ignored %s from %x [logterm: %d, index: %d] at term %d: lease is not expired (remaining ticks: %d)",
-					r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term, r.electionTimeout-r.electionElapsed)
-				return nil
-			}
-		}
-		switch {
-		case m.Type == pb.MsgPreVote:
-			// Never change our term in response to a PreVote
-		case m.Type == pb.MsgPreVoteResp && !m.Reject:
-			// We send pre-vote requests with a term in our future. If the
-			// pre-vote is granted, we will increment our term when we get a
-			// quorum. If it is not, the term comes from the node that
-			// rejected our vote so we should become a follower at the new
-			// term.
-		default:
-			r.logger.Infof("%x [term: %d] received a %s message with higher term from %x [term: %d]",
-				r.id, r.Term, m.Type, m.From, m.Term)
-			if m.Type == pb.MsgApp || m.Type == pb.MsgHeartbeat || m.Type == pb.MsgSnap {
-				r.becomeFollower(m.Term, m.From)
-			} else {
-				r.becomeFollower(m.Term, None)
-			}
-		}
-
-	case m.Term < r.Term:
-		if r.checkQuorum && (m.Type == pb.MsgHeartbeat || m.Type == pb.MsgApp) {
-			// We have received messages from a leader at a lower term. It is possible
-			// that these messages were simply delayed in the network, but this could
-			// also mean that this node has advanced its term number during a network
-			// partition, and it is now unable to either win an election or to rejoin
-			// the majority on the old term. If checkQuorum is false, this will be
-			// handled by incrementing term numbers in response to MsgVote with a
-			// higher term, but if checkQuorum is true we may not advance the term on
-			// MsgVote and must generate other messages to advance the term. The net
-			// result of these two features is to minimize the disruption caused by
-			// nodes that have been removed from the cluster's configuration: a
-			// removed node will send MsgVotes (or MsgPreVotes) which will be ignored,
-			// but it will not receive MsgApp or MsgHeartbeat, so it will not create
-			// disruptive term increases
-			r.send(pb.Message{To: m.From, Type: pb.MsgAppResp})
-		} else {
-			// ignore other cases
-			r.logger.Infof("%x [term: %d] ignored a %s message with lower term from %x [term: %d]",
-				r.id, r.Term, m.Type, m.From, m.Term)
-		}
-		return nil
-	}
-
-	switch m.Type {
-	case pb.MsgHup:
-		if r.state != StateLeader {
-			ents, err := r.raftLog.slice(r.raftLog.applied+1, r.raftLog.committed+1, noLimit)
-			if err != nil {
-				r.logger.Panicf("unexpected error getting unapplied entries (%v)", err)
-			}
-			if n := numOfPendingConf(ents); n != 0 && r.raftLog.committed > r.raftLog.applied {
-				r.logger.Warningf("%x cannot campaign at term %d since there are still %d pending configuration changes to apply", r.id, r.Term, n)
-				return nil
-			}
-
-			r.logger.Infof("%x is starting a new election at term %d", r.id, r.Term)
-			if r.preVote {
-				r.campaign(campaignPreElection)
-			} else {
-				r.campaign(campaignElection)
-			}
-		} else {
-			r.logger.Debugf("%x ignoring MsgHup because already leader", r.id)
-		}
-
-	case pb.MsgVote, pb.MsgPreVote:
-		if r.isLearner {
-			// TODO: learner may need to vote, in case of node down when confchange.
-			r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] ignored %s from %x [logterm: %d, index: %d] at term %d: learner can not vote",
-				r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term)
-			return nil
-		}
-		// The m.Term > r.Term clause is for MsgPreVote. For MsgVote m.Term should
-		// always equal r.Term.
-		if (r.Vote == None || m.Term > r.Term || r.Vote == m.From) && r.raftLog.isUpToDate(m.Index, m.LogTerm) {
-			r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] cast %s for %x [logterm: %d, index: %d] at term %d",
-				r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term)
-			// When responding to Msg{Pre,}Vote messages we include the term
-			// from the message, not the local term. To see why consider the
-			// case where a single node was previously partitioned away and
-			// it's local term is now of date. If we include the local term
-			// (recall that for pre-votes we don't update the local term), the
-			// (pre-)campaigning node on the other end will proceed to ignore
-			// the message (it ignores all out of date messages).
-			// The term in the original message and current local term are the
-			// same in the case of regular votes, but different for pre-votes.
-			r.send(pb.Message{To: m.From, Term: m.Term, Type: voteRespMsgType(m.Type)})
-			if m.Type == pb.MsgVote {
-				// Only record real votes.
-				r.electionElapsed = 0
-				r.Vote = m.From
-			}
-		} else {
-			r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] rejected %s from %x [logterm: %d, index: %d] at term %d",
-				r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term)
-			r.send(pb.Message{To: m.From, Term: r.Term, Type: voteRespMsgType(m.Type), Reject: true})
-		}
-
-	default:
-		r.step(r, m)
-	}
-	return nil
-}
-
-type stepFunc func(r *raft, m pb.Message)
-
-func stepLeader(r *raft, m pb.Message) {
-	// These message types do not require any progress for m.From.
-	switch m.Type {
-	case pb.MsgBeat:
-		r.bcastHeartbeat()
-		return
-	case pb.MsgCheckQuorum:
-		if !r.checkQuorumActive() {
-			r.logger.Warningf("%x stepped down to follower since quorum is not active", r.id)
-			r.becomeFollower(r.Term, None)
-		}
-		return
-	case pb.MsgProp:
-		if len(m.Entries) == 0 {
-			r.logger.Panicf("%x stepped empty MsgProp", r.id)
-		}
-		if _, ok := r.prs[r.id]; !ok {
-			// If we are not currently a member of the range (i.e. this node
-			// was removed from the configuration while serving as leader),
-			// drop any new proposals.
-			return
-		}
-		if r.leadTransferee != None {
-			r.logger.Debugf("%x [term %d] transfer leadership to %x is in progress; dropping proposal", r.id, r.Term, r.leadTransferee)
-			return
-		}
-
-		for i, e := range m.Entries {
-			if e.Type == pb.EntryConfChange {
-				if r.pendingConf {
-					r.logger.Infof("propose conf %s ignored since pending unapplied configuration", e.String())
-					m.Entries[i] = pb.Entry{Type: pb.EntryNormal}
-				}
-				r.pendingConf = true
-			}
-		}
-		r.appendEntry(m.Entries...)
-		r.bcastAppend()
-		return
-	case pb.MsgReadIndex:
-		if r.quorum() > 1 {
-			if r.raftLog.zeroTermOnErrCompacted(r.raftLog.term(r.raftLog.committed)) != r.Term {
-				// Reject read only request when this leader has not committed any log entry at its term.
-				return
-			}
-
-			// thinking: use an interally defined context instead of the user given context.
-			// We can express this in terms of the term and index instead of a user-supplied value.
-			// This would allow multiple reads to piggyback on the same message.
-			switch r.readOnly.option {
-			case ReadOnlySafe:
-				r.readOnly.addRequest(r.raftLog.committed, m)
-				r.bcastHeartbeatWithCtx(m.Entries[0].Data)
-			case ReadOnlyLeaseBased:
-				ri := r.raftLog.committed
-				if m.From == None || m.From == r.id { // from local member
-					r.readStates = append(r.readStates, ReadState{Index: r.raftLog.committed, RequestCtx: m.Entries[0].Data})
-				} else {
-					r.send(pb.Message{To: m.From, Type: pb.MsgReadIndexResp, Index: ri, Entries: m.Entries})
-				}
-			}
-		} else {
-			r.readStates = append(r.readStates, ReadState{Index: r.raftLog.committed, RequestCtx: m.Entries[0].Data})
-		}
-
-		return
-	}
-
-	// All other message types require a progress for m.From (pr).
-	pr := r.getProgress(m.From)
-	if pr == nil {
-		r.logger.Debugf("%x no progress available for %x", r.id, m.From)
-		return
-	}
-	switch m.Type {
-	case pb.MsgAppResp:
-		pr.RecentActive = true
-
-		if m.Reject {
-			r.logger.Debugf("%x received msgApp rejection(lastindex: %d) from %x for index %d",
-				r.id, m.RejectHint, m.From, m.Index)
-			if pr.maybeDecrTo(m.Index, m.RejectHint) {
-				r.logger.Debugf("%x decreased progress of %x to [%s]", r.id, m.From, pr)
-				if pr.State == ProgressStateReplicate {
-					pr.becomeProbe()
-				}
-				r.sendAppend(m.From)
-			}
-		} else {
-			oldPaused := pr.IsPaused()
-			if pr.maybeUpdate(m.Index) {
-				switch {
-				case pr.State == ProgressStateProbe:
-					pr.becomeReplicate()
-				case pr.State == ProgressStateSnapshot && pr.needSnapshotAbort():
-					r.logger.Debugf("%x snapshot aborted, resumed sending replication messages to %x [%s]", r.id, m.From, pr)
-					pr.becomeProbe()
-				case pr.State == ProgressStateReplicate:
-					pr.ins.freeTo(m.Index)
-				}
-
-				if r.maybeCommit() {
-					r.bcastAppend()
-				} else if oldPaused {
-					// update() reset the wait state on this node. If we had delayed sending
-					// an update before, send it now.
-					r.sendAppend(m.From)
-				}
-				// Transfer leadership is in progress.
-				if m.From == r.leadTransferee && pr.Match == r.raftLog.lastIndex() {
-					r.logger.Infof("%x sent MsgTimeoutNow to %x after received MsgAppResp", r.id, m.From)
-					r.sendTimeoutNow(m.From)
-				}
-			}
-		}
-	case pb.MsgHeartbeatResp:
-		pr.RecentActive = true
-		pr.resume()
-
-		// free one slot for the full inflights window to allow progress.
-		if pr.State == ProgressStateReplicate && pr.ins.full() {
-			pr.ins.freeFirstOne()
-		}
-		if pr.Match < r.raftLog.lastIndex() {
-			r.sendAppend(m.From)
-		}
-
-		if r.readOnly.option != ReadOnlySafe || len(m.Context) == 0 {
-			return
-		}
-
-		ackCount := r.readOnly.recvAck(m)
-		if ackCount < r.quorum() {
-			return
-		}
-
-		rss := r.readOnly.advance(m)
-		for _, rs := range rss {
-			req := rs.req
-			if req.From == None || req.From == r.id { // from local member
-				r.readStates = append(r.readStates, ReadState{Index: rs.index, RequestCtx: req.Entries[0].Data})
-			} else {
-				r.send(pb.Message{To: req.From, Type: pb.MsgReadIndexResp, Index: rs.index, Entries: req.Entries})
-			}
-		}
-	case pb.MsgSnapStatus:
-		if pr.State != ProgressStateSnapshot {
-			return
-		}
-		if !m.Reject {
-			pr.becomeProbe()
-			r.logger.Debugf("%x snapshot succeeded, resumed sending replication messages to %x [%s]", r.id, m.From, pr)
-		} else {
-			pr.snapshotFailure()
-			pr.becomeProbe()
-			r.logger.Debugf("%x snapshot failed, resumed sending replication messages to %x [%s]", r.id, m.From, pr)
-		}
-		// If snapshot finish, wait for the msgAppResp from the remote node before sending
-		// out the next msgApp.
-		// If snapshot failure, wait for a heartbeat interval before next try
-		pr.pause()
-	case pb.MsgUnreachable:
-		// During optimistic replication, if the remote becomes unreachable,
-		// there is huge probability that a MsgApp is lost.
-		if pr.State == ProgressStateReplicate {
-			pr.becomeProbe()
-		}
-		r.logger.Debugf("%x failed to send message to %x because it is unreachable [%s]", r.id, m.From, pr)
-	case pb.MsgTransferLeader:
-		if pr.IsLearner {
-			r.logger.Debugf("%x is learner. Ignored transferring leadership", r.id)
-			return
-		}
-		leadTransferee := m.From
-		lastLeadTransferee := r.leadTransferee
-		if lastLeadTransferee != None {
-			if lastLeadTransferee == leadTransferee {
-				r.logger.Infof("%x [term %d] transfer leadership to %x is in progress, ignores request to same node %x",
-					r.id, r.Term, leadTransferee, leadTransferee)
-				return
-			}
-			r.abortLeaderTransfer()
-			r.logger.Infof("%x [term %d] abort previous transferring leadership to %x", r.id, r.Term, lastLeadTransferee)
-		}
-		if leadTransferee == r.id {
-			r.logger.Debugf("%x is already leader. Ignored transferring leadership to self", r.id)
-			return
-		}
-		// Transfer leadership to third party.
-		r.logger.Infof("%x [term %d] starts to transfer leadership to %x", r.id, r.Term, leadTransferee)
-		// Transfer leadership should be finished in one electionTimeout, so reset r.electionElapsed.
-		r.electionElapsed = 0
-		r.leadTransferee = leadTransferee
-		if pr.Match == r.raftLog.lastIndex() {
-			r.sendTimeoutNow(leadTransferee)
-			r.logger.Infof("%x sends MsgTimeoutNow to %x immediately as %x already has up-to-date log", r.id, leadTransferee, leadTransferee)
-		} else {
-			r.sendAppend(leadTransferee)
-		}
-	}
-}
-
-// stepCandidate is shared by StateCandidate and StatePreCandidate; the difference is
-// whether they respond to MsgVoteResp or MsgPreVoteResp.
-func stepCandidate(r *raft, m pb.Message) {
-	// Only handle vote responses corresponding to our candidacy (while in
-	// StateCandidate, we may get stale MsgPreVoteResp messages in this term from
-	// our pre-candidate state).
-	var myVoteRespType pb.MessageType
-	if r.state == StatePreCandidate {
-		myVoteRespType = pb.MsgPreVoteResp
-	} else {
-		myVoteRespType = pb.MsgVoteResp
-	}
-	switch m.Type {
-	case pb.MsgProp:
-		r.logger.Infof("%x no leader at term %d; dropping proposal", r.id, r.Term)
-		return
-	case pb.MsgApp:
-		r.becomeFollower(r.Term, m.From)
-		r.handleAppendEntries(m)
-	case pb.MsgHeartbeat:
-		r.becomeFollower(r.Term, m.From)
-		r.handleHeartbeat(m)
-	case pb.MsgSnap:
-		r.becomeFollower(m.Term, m.From)
-		r.handleSnapshot(m)
-	case myVoteRespType:
-		gr := r.poll(m.From, m.Type, !m.Reject)
-		r.logger.Infof("%x [quorum:%d] has received %d %s votes and %d vote rejections", r.id, r.quorum(), gr, m.Type, len(r.votes)-gr)
-		switch r.quorum() {
-		case gr:
-			if r.state == StatePreCandidate {
-				r.campaign(campaignElection)
-			} else {
-				r.becomeLeader()
-				r.bcastAppend()
-			}
-		case len(r.votes) - gr:
-			r.becomeFollower(r.Term, None)
-		}
-	case pb.MsgTimeoutNow:
-		r.logger.Debugf("%x [term %d state %v] ignored MsgTimeoutNow from %x", r.id, r.Term, r.state, m.From)
-	}
-}
-
-func stepFollower(r *raft, m pb.Message) {
-	switch m.Type {
-	case pb.MsgProp:
-		if r.lead == None {
-			r.logger.Infof("%x no leader at term %d; dropping proposal", r.id, r.Term)
-			return
-		} else if r.disableProposalForwarding {
-			r.logger.Infof("%x not forwarding to leader %x at term %d; dropping proposal", r.id, r.lead, r.Term)
-			return
-		}
-		m.To = r.lead
-		r.send(m)
-	case pb.MsgApp:
-		r.electionElapsed = 0
-		r.lead = m.From
-		r.handleAppendEntries(m)
-	case pb.MsgHeartbeat:
-		r.electionElapsed = 0
-		r.lead = m.From
-		r.handleHeartbeat(m)
-	case pb.MsgSnap:
-		r.electionElapsed = 0
-		r.lead = m.From
-		r.handleSnapshot(m)
-	case pb.MsgTransferLeader:
-		if r.lead == None {
-			r.logger.Infof("%x no leader at term %d; dropping leader transfer msg", r.id, r.Term)
-			return
-		}
-		m.To = r.lead
-		r.send(m)
-	case pb.MsgTimeoutNow:
-		if r.promotable() {
-			r.logger.Infof("%x [term %d] received MsgTimeoutNow from %x and starts an election to get leadership.", r.id, r.Term, m.From)
-			// Leadership transfers never use pre-vote even if r.preVote is true; we
-			// know we are not recovering from a partition so there is no need for the
-			// extra round trip.
-			r.campaign(campaignTransfer)
-		} else {
-			r.logger.Infof("%x received MsgTimeoutNow from %x but is not promotable", r.id, m.From)
-		}
-	case pb.MsgReadIndex:
-		if r.lead == None {
-			r.logger.Infof("%x no leader at term %d; dropping index reading msg", r.id, r.Term)
-			return
-		}
-		m.To = r.lead
-		r.send(m)
-	case pb.MsgReadIndexResp:
-		if len(m.Entries) != 1 {
-			r.logger.Errorf("%x invalid format of MsgReadIndexResp from %x, entries count: %d", r.id, m.From, len(m.Entries))
-			return
-		}
-		r.readStates = append(r.readStates, ReadState{Index: m.Index, RequestCtx: m.Entries[0].Data})
-	}
-}
-
-func (r *raft) handleAppendEntries(m pb.Message) {
-	if m.Index < r.raftLog.committed {
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: r.raftLog.committed})
-		return
-	}
-
-	if mlastIndex, ok := r.raftLog.maybeAppend(m.Index, m.LogTerm, m.Commit, m.Entries...); ok {
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: mlastIndex})
-	} else {
-		r.logger.Debugf("%x [logterm: %d, index: %d] rejected msgApp [logterm: %d, index: %d] from %x",
-			r.id, r.raftLog.zeroTermOnErrCompacted(r.raftLog.term(m.Index)), m.Index, m.LogTerm, m.Index, m.From)
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: m.Index, Reject: true, RejectHint: r.raftLog.lastIndex()})
-	}
-}
-
-func (r *raft) handleHeartbeat(m pb.Message) {
-	r.raftLog.commitTo(m.Commit)
-	r.send(pb.Message{To: m.From, Type: pb.MsgHeartbeatResp, Context: m.Context})
-}
-
-func (r *raft) handleSnapshot(m pb.Message) {
-	sindex, sterm := m.Snapshot.Metadata.Index, m.Snapshot.Metadata.Term
-	if r.restore(m.Snapshot) {
-		r.logger.Infof("%x [commit: %d] restored snapshot [index: %d, term: %d]",
-			r.id, r.raftLog.committed, sindex, sterm)
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: r.raftLog.lastIndex()})
-	} else {
-		r.logger.Infof("%x [commit: %d] ignored snapshot [index: %d, term: %d]",
-			r.id, r.raftLog.committed, sindex, sterm)
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: r.raftLog.committed})
-	}
-}
-
-// restore recovers the state machine from a snapshot. It restores the log and the
-// configuration of state machine.
-func (r *raft) restore(s pb.Snapshot) bool {
-	if s.Metadata.Index <= r.raftLog.committed {
-		return false
-	}
-	if r.raftLog.matchTerm(s.Metadata.Index, s.Metadata.Term) {
-		r.logger.Infof("%x [commit: %d, lastindex: %d, lastterm: %d] fast-forwarded commit to snapshot [index: %d, term: %d]",
-			r.id, r.raftLog.committed, r.raftLog.lastIndex(), r.raftLog.lastTerm(), s.Metadata.Index, s.Metadata.Term)
-		r.raftLog.commitTo(s.Metadata.Index)
-		return false
-	}
-
-	// The normal peer can't become learner.
-	if !r.isLearner {
-		for _, id := range s.Metadata.ConfState.Learners {
-			if id == r.id {
-				r.logger.Errorf("%x can't become learner when restores snapshot [index: %d, term: %d]", r.id, s.Metadata.Index, s.Metadata.Term)
-				return false
-			}
-		}
-	}
-
-	r.logger.Infof("%x [commit: %d, lastindex: %d, lastterm: %d] starts to restore snapshot [index: %d, term: %d]",
-		r.id, r.raftLog.committed, r.raftLog.lastIndex(), r.raftLog.lastTerm(), s.Metadata.Index, s.Metadata.Term)
-
-	r.raftLog.restore(s)
-	r.prs = make(map[uint64]*Progress)
-	r.learnerPrs = make(map[uint64]*Progress)
-	r.restoreNode(s.Metadata.ConfState.Nodes, false)
-	r.restoreNode(s.Metadata.ConfState.Learners, true)
-	return true
-}
-
-func (r *raft) restoreNode(nodes []uint64, isLearner bool) {
-	for _, n := range nodes {
-		match, next := uint64(0), r.raftLog.lastIndex()+1
-		if n == r.id {
-			match = next - 1
-			r.isLearner = isLearner
-		}
-		r.setProgress(n, match, next, isLearner)
-		r.logger.Infof("%x restored progress of %x [%s]", r.id, n, r.getProgress(n))
-	}
-}
-
-// promotable indicates whether state machine can be promoted to leader,
-// which is true when its own id is in progress list.
-func (r *raft) promotable() bool {
-	_, ok := r.prs[r.id]
-	return ok
-}
-
-func (r *raft) addNode(id uint64) {
-	r.addNodeOrLearnerNode(id, false)
-}
-
-func (r *raft) addLearner(id uint64) {
-	r.addNodeOrLearnerNode(id, true)
-}
-
-func (r *raft) addNodeOrLearnerNode(id uint64, isLearner bool) {
-	r.pendingConf = false
-	pr := r.getProgress(id)
-	if pr == nil {
-		r.setProgress(id, 0, r.raftLog.lastIndex()+1, isLearner)
-	} else {
-		if isLearner && !pr.IsLearner {
-			// can only change Learner to Voter
-			r.logger.Infof("%x ignored addLeaner: do not support changing %x from raft peer to learner.", r.id, id)
-			return
-		}
-
-		if isLearner == pr.IsLearner {
-			// Ignore any redundant addNode calls (which can happen because the
-			// initial bootstrapping entries are applied twice).
-			return
-		}
-
-		// change Learner to Voter, use origin Learner progress
-		delete(r.learnerPrs, id)
-		pr.IsLearner = false
-		r.prs[id] = pr
-	}
-
-	if r.id == id {
-		r.isLearner = isLearner
-	}
-
-	// When a node is first added, we should mark it as recently active.
-	// Otherwise, CheckQuorum may cause us to step down if it is invoked
-	// before the added node has a chance to communicate with us.
-	pr = r.getProgress(id)
-	pr.RecentActive = true
-}
-
-func (r *raft) removeNode(id uint64) {
-	r.delProgress(id)
-	r.pendingConf = false
-
-	// do not try to commit or abort transferring if there is no nodes in the cluster.
-	if len(r.prs) == 0 && len(r.learnerPrs) == 0 {
-		return
-	}
-
-	// The quorum size is now smaller, so see if any pending entries can
-	// be committed.
-	if r.maybeCommit() {
-		r.bcastAppend()
-	}
-	// If the removed node is the leadTransferee, then abort the leadership transferring.
-	if r.state == StateLeader && r.leadTransferee == id {
-		r.abortLeaderTransfer()
-	}
-}
-
-func (r *raft) resetPendingConf() { r.pendingConf = false }
-
-func (r *raft) setProgress(id, match, next uint64, isLearner bool) {
-	if !isLearner {
-		delete(r.learnerPrs, id)
-		r.prs[id] = &Progress{Next: next, Match: match, ins: newInflights(r.maxInflight)}
-		return
-	}
-
-	if _, ok := r.prs[id]; ok {
-		panic(fmt.Sprintf("%x unexpected changing from voter to learner for %x", r.id, id))
-	}
-	r.learnerPrs[id] = &Progress{Next: next, Match: match, ins: newInflights(r.maxInflight), IsLearner: true}
-}
-
-func (r *raft) delProgress(id uint64) {
-	delete(r.prs, id)
-	delete(r.learnerPrs, id)
-}
-
-func (r *raft) loadState(state pb.HardState) {
-	if state.Commit < r.raftLog.committed || state.Commit > r.raftLog.lastIndex() {
-		r.logger.Panicf("%x state.commit %d is out of range [%d, %d]", r.id, state.Commit, r.raftLog.committed, r.raftLog.lastIndex())
-	}
-	r.raftLog.committed = state.Commit
-	r.Term = state.Term
-	r.Vote = state.Vote
-}
-
-// pastElectionTimeout returns true iff r.electionElapsed is greater
-// than or equal to the randomized election timeout in
-// [electiontimeout, 2 * electiontimeout - 1].
-func (r *raft) pastElectionTimeout() bool {
-	return r.electionElapsed >= r.randomizedElectionTimeout
-}
-
-func (r *raft) resetRandomizedElectionTimeout() {
-	r.randomizedElectionTimeout = r.electionTimeout + globalRand.Intn(r.electionTimeout)
-}
-
-// checkQuorumActive returns true if the quorum is active from
-// the view of the local raft state machine. Otherwise, it returns
-// false.
-// checkQuorumActive also resets all RecentActive to false.
-func (r *raft) checkQuorumActive() bool {
-	var act int
-
-	r.forEachProgress(func(id uint64, pr *Progress) {
-		if id == r.id { // self is always active
-			act++
-			return
-		}
-
-		if pr.RecentActive && !pr.IsLearner {
-			act++
-		}
-
-		pr.RecentActive = false
-	})
-
-	return act >= r.quorum()
-}
-
-func (r *raft) sendTimeoutNow(to uint64) {
-	r.send(pb.Message{To: to, Type: pb.MsgTimeoutNow})
-}
-
-func (r *raft) abortLeaderTransfer() {
-	r.leadTransferee = None
-}
-
-func numOfPendingConf(ents []pb.Entry) int {
-	n := 0
-	for i := range ents {
-		if ents[i].Type == pb.EntryConfChange {
-			n++
-		}
-	}
-	return n
-}
diff --git a/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto b/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto
deleted file mode 100644
index 644ce7b..0000000
--- a/vendor/github.com/coreos/etcd/raft/raftpb/raft.proto
+++ /dev/null
@@ -1,95 +0,0 @@
-syntax = "proto2";
-package raftpb;
-
-import "gogoproto/gogo.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.sizer_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-option (gogoproto.goproto_getters_all) = false;
-option (gogoproto.goproto_enum_prefix_all) = false;
-
-enum EntryType {
-	EntryNormal     = 0;
-	EntryConfChange = 1;
-}
-
-message Entry {
-	optional uint64     Term  = 2 [(gogoproto.nullable) = false]; // must be 64-bit aligned for atomic operations
-	optional uint64     Index = 3 [(gogoproto.nullable) = false]; // must be 64-bit aligned for atomic operations
-	optional EntryType  Type  = 1 [(gogoproto.nullable) = false];
-	optional bytes      Data  = 4;
-}
-
-message SnapshotMetadata {
-	optional ConfState conf_state = 1 [(gogoproto.nullable) = false];
-	optional uint64    index      = 2 [(gogoproto.nullable) = false];
-	optional uint64    term       = 3 [(gogoproto.nullable) = false];
-}
-
-message Snapshot {
-	optional bytes            data     = 1;
-	optional SnapshotMetadata metadata = 2 [(gogoproto.nullable) = false];
-}
-
-enum MessageType {
-	MsgHup             = 0;
-	MsgBeat            = 1;
-	MsgProp            = 2;
-	MsgApp             = 3;
-	MsgAppResp         = 4;
-	MsgVote            = 5;
-	MsgVoteResp        = 6;
-	MsgSnap            = 7;
-	MsgHeartbeat       = 8;
-	MsgHeartbeatResp   = 9;
-	MsgUnreachable     = 10;
-	MsgSnapStatus      = 11;
-	MsgCheckQuorum     = 12;
-	MsgTransferLeader  = 13;
-	MsgTimeoutNow      = 14;
-	MsgReadIndex       = 15;
-	MsgReadIndexResp   = 16;
-	MsgPreVote         = 17;
-	MsgPreVoteResp     = 18;
-}
-
-message Message {
-	optional MessageType type        = 1  [(gogoproto.nullable) = false];
-	optional uint64      to          = 2  [(gogoproto.nullable) = false];
-	optional uint64      from        = 3  [(gogoproto.nullable) = false];
-	optional uint64      term        = 4  [(gogoproto.nullable) = false];
-	optional uint64      logTerm     = 5  [(gogoproto.nullable) = false];
-	optional uint64      index       = 6  [(gogoproto.nullable) = false];
-	repeated Entry       entries     = 7  [(gogoproto.nullable) = false];
-	optional uint64      commit      = 8  [(gogoproto.nullable) = false];
-	optional Snapshot    snapshot    = 9  [(gogoproto.nullable) = false];
-	optional bool        reject      = 10 [(gogoproto.nullable) = false];
-	optional uint64      rejectHint  = 11 [(gogoproto.nullable) = false];
-	optional bytes       context     = 12;
-}
-
-message HardState {
-	optional uint64 term   = 1 [(gogoproto.nullable) = false];
-	optional uint64 vote   = 2 [(gogoproto.nullable) = false];
-	optional uint64 commit = 3 [(gogoproto.nullable) = false];
-}
-
-message ConfState {
-	repeated uint64 nodes    = 1;
-	repeated uint64 learners = 2;
-}
-
-enum ConfChangeType {
-	ConfChangeAddNode        = 0;
-	ConfChangeRemoveNode     = 1;
-	ConfChangeUpdateNode     = 2;
-	ConfChangeAddLearnerNode = 3;
-}
-
-message ConfChange {
-	optional uint64          ID      = 1 [(gogoproto.nullable) = false];
-	optional ConfChangeType  Type    = 2 [(gogoproto.nullable) = false];
-	optional uint64          NodeID  = 3 [(gogoproto.nullable) = false];
-	optional bytes           Context = 4;
-}
diff --git a/vendor/github.com/coreos/etcd/raft/rawnode.go b/vendor/github.com/coreos/etcd/raft/rawnode.go
deleted file mode 100644
index 925cb85..0000000
--- a/vendor/github.com/coreos/etcd/raft/rawnode.go
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import (
-	"errors"
-
-	pb "github.com/coreos/etcd/raft/raftpb"
-)
-
-// ErrStepLocalMsg is returned when try to step a local raft message
-var ErrStepLocalMsg = errors.New("raft: cannot step raft local message")
-
-// ErrStepPeerNotFound is returned when try to step a response message
-// but there is no peer found in raft.prs for that node.
-var ErrStepPeerNotFound = errors.New("raft: cannot step as peer not found")
-
-// RawNode is a thread-unsafe Node.
-// The methods of this struct correspond to the methods of Node and are described
-// more fully there.
-type RawNode struct {
-	raft       *raft
-	prevSoftSt *SoftState
-	prevHardSt pb.HardState
-}
-
-func (rn *RawNode) newReady() Ready {
-	return newReady(rn.raft, rn.prevSoftSt, rn.prevHardSt)
-}
-
-func (rn *RawNode) commitReady(rd Ready) {
-	if rd.SoftState != nil {
-		rn.prevSoftSt = rd.SoftState
-	}
-	if !IsEmptyHardState(rd.HardState) {
-		rn.prevHardSt = rd.HardState
-	}
-	if rn.prevHardSt.Commit != 0 {
-		// In most cases, prevHardSt and rd.HardState will be the same
-		// because when there are new entries to apply we just sent a
-		// HardState with an updated Commit value. However, on initial
-		// startup the two are different because we don't send a HardState
-		// until something changes, but we do send any un-applied but
-		// committed entries (and previously-committed entries may be
-		// incorporated into the snapshot, even if rd.CommittedEntries is
-		// empty). Therefore we mark all committed entries as applied
-		// whether they were included in rd.HardState or not.
-		rn.raft.raftLog.appliedTo(rn.prevHardSt.Commit)
-	}
-	if len(rd.Entries) > 0 {
-		e := rd.Entries[len(rd.Entries)-1]
-		rn.raft.raftLog.stableTo(e.Index, e.Term)
-	}
-	if !IsEmptySnap(rd.Snapshot) {
-		rn.raft.raftLog.stableSnapTo(rd.Snapshot.Metadata.Index)
-	}
-	if len(rd.ReadStates) != 0 {
-		rn.raft.readStates = nil
-	}
-}
-
-// NewRawNode returns a new RawNode given configuration and a list of raft peers.
-func NewRawNode(config *Config, peers []Peer) (*RawNode, error) {
-	if config.ID == 0 {
-		panic("config.ID must not be zero")
-	}
-	r := newRaft(config)
-	rn := &RawNode{
-		raft: r,
-	}
-	lastIndex, err := config.Storage.LastIndex()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-	// If the log is empty, this is a new RawNode (like StartNode); otherwise it's
-	// restoring an existing RawNode (like RestartNode).
-	// TODO(bdarnell): rethink RawNode initialization and whether the application needs
-	// to be able to tell us when it expects the RawNode to exist.
-	if lastIndex == 0 {
-		r.becomeFollower(1, None)
-		ents := make([]pb.Entry, len(peers))
-		for i, peer := range peers {
-			cc := pb.ConfChange{Type: pb.ConfChangeAddNode, NodeID: peer.ID, Context: peer.Context}
-			data, err := cc.Marshal()
-			if err != nil {
-				panic("unexpected marshal error")
-			}
-
-			ents[i] = pb.Entry{Type: pb.EntryConfChange, Term: 1, Index: uint64(i + 1), Data: data}
-		}
-		r.raftLog.append(ents...)
-		r.raftLog.committed = uint64(len(ents))
-		for _, peer := range peers {
-			r.addNode(peer.ID)
-		}
-	}
-
-	// Set the initial hard and soft states after performing all initialization.
-	rn.prevSoftSt = r.softState()
-	if lastIndex == 0 {
-		rn.prevHardSt = emptyState
-	} else {
-		rn.prevHardSt = r.hardState()
-	}
-
-	return rn, nil
-}
-
-// Tick advances the internal logical clock by a single tick.
-func (rn *RawNode) Tick() {
-	rn.raft.tick()
-}
-
-// TickQuiesced advances the internal logical clock by a single tick without
-// performing any other state machine processing. It allows the caller to avoid
-// periodic heartbeats and elections when all of the peers in a Raft group are
-// known to be at the same state. Expected usage is to periodically invoke Tick
-// or TickQuiesced depending on whether the group is "active" or "quiesced".
-//
-// WARNING: Be very careful about using this method as it subverts the Raft
-// state machine. You should probably be using Tick instead.
-func (rn *RawNode) TickQuiesced() {
-	rn.raft.electionElapsed++
-}
-
-// Campaign causes this RawNode to transition to candidate state.
-func (rn *RawNode) Campaign() error {
-	return rn.raft.Step(pb.Message{
-		Type: pb.MsgHup,
-	})
-}
-
-// Propose proposes data be appended to the raft log.
-func (rn *RawNode) Propose(data []byte) error {
-	return rn.raft.Step(pb.Message{
-		Type: pb.MsgProp,
-		From: rn.raft.id,
-		Entries: []pb.Entry{
-			{Data: data},
-		}})
-}
-
-// ProposeConfChange proposes a config change.
-func (rn *RawNode) ProposeConfChange(cc pb.ConfChange) error {
-	data, err := cc.Marshal()
-	if err != nil {
-		return err
-	}
-	return rn.raft.Step(pb.Message{
-		Type: pb.MsgProp,
-		Entries: []pb.Entry{
-			{Type: pb.EntryConfChange, Data: data},
-		},
-	})
-}
-
-// ApplyConfChange applies a config change to the local node.
-func (rn *RawNode) ApplyConfChange(cc pb.ConfChange) *pb.ConfState {
-	if cc.NodeID == None {
-		rn.raft.resetPendingConf()
-		return &pb.ConfState{Nodes: rn.raft.nodes()}
-	}
-	switch cc.Type {
-	case pb.ConfChangeAddNode:
-		rn.raft.addNode(cc.NodeID)
-	case pb.ConfChangeAddLearnerNode:
-		rn.raft.addLearner(cc.NodeID)
-	case pb.ConfChangeRemoveNode:
-		rn.raft.removeNode(cc.NodeID)
-	case pb.ConfChangeUpdateNode:
-		rn.raft.resetPendingConf()
-	default:
-		panic("unexpected conf type")
-	}
-	return &pb.ConfState{Nodes: rn.raft.nodes()}
-}
-
-// Step advances the state machine using the given message.
-func (rn *RawNode) Step(m pb.Message) error {
-	// ignore unexpected local messages receiving over network
-	if IsLocalMsg(m.Type) {
-		return ErrStepLocalMsg
-	}
-	if pr := rn.raft.getProgress(m.From); pr != nil || !IsResponseMsg(m.Type) {
-		return rn.raft.Step(m)
-	}
-	return ErrStepPeerNotFound
-}
-
-// Ready returns the current point-in-time state of this RawNode.
-func (rn *RawNode) Ready() Ready {
-	rd := rn.newReady()
-	rn.raft.msgs = nil
-	return rd
-}
-
-// HasReady called when RawNode user need to check if any Ready pending.
-// Checking logic in this method should be consistent with Ready.containsUpdates().
-func (rn *RawNode) HasReady() bool {
-	r := rn.raft
-	if !r.softState().equal(rn.prevSoftSt) {
-		return true
-	}
-	if hardSt := r.hardState(); !IsEmptyHardState(hardSt) && !isHardStateEqual(hardSt, rn.prevHardSt) {
-		return true
-	}
-	if r.raftLog.unstable.snapshot != nil && !IsEmptySnap(*r.raftLog.unstable.snapshot) {
-		return true
-	}
-	if len(r.msgs) > 0 || len(r.raftLog.unstableEntries()) > 0 || r.raftLog.hasNextEnts() {
-		return true
-	}
-	if len(r.readStates) != 0 {
-		return true
-	}
-	return false
-}
-
-// Advance notifies the RawNode that the application has applied and saved progress in the
-// last Ready results.
-func (rn *RawNode) Advance(rd Ready) {
-	rn.commitReady(rd)
-}
-
-// Status returns the current status of the given group.
-func (rn *RawNode) Status() *Status {
-	status := getStatus(rn.raft)
-	return &status
-}
-
-// ReportUnreachable reports the given node is not reachable for the last send.
-func (rn *RawNode) ReportUnreachable(id uint64) {
-	_ = rn.raft.Step(pb.Message{Type: pb.MsgUnreachable, From: id})
-}
-
-// ReportSnapshot reports the status of the sent snapshot.
-func (rn *RawNode) ReportSnapshot(id uint64, status SnapshotStatus) {
-	rej := status == SnapshotFailure
-
-	_ = rn.raft.Step(pb.Message{Type: pb.MsgSnapStatus, From: id, Reject: rej})
-}
-
-// TransferLeader tries to transfer leadership to the given transferee.
-func (rn *RawNode) TransferLeader(transferee uint64) {
-	_ = rn.raft.Step(pb.Message{Type: pb.MsgTransferLeader, From: transferee})
-}
-
-// ReadIndex requests a read state. The read state will be set in ready.
-// Read State has a read index. Once the application advances further than the read
-// index, any linearizable read requests issued before the read request can be
-// processed safely. The read state will have the same rctx attached.
-func (rn *RawNode) ReadIndex(rctx []byte) {
-	_ = rn.raft.Step(pb.Message{Type: pb.MsgReadIndex, Entries: []pb.Entry{{Data: rctx}}})
-}
diff --git a/vendor/github.com/coreos/etcd/raft/read_only.go b/vendor/github.com/coreos/etcd/raft/read_only.go
deleted file mode 100644
index ae746fa..0000000
--- a/vendor/github.com/coreos/etcd/raft/read_only.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import pb "github.com/coreos/etcd/raft/raftpb"
-
-// ReadState provides state for read only query.
-// It's caller's responsibility to call ReadIndex first before getting
-// this state from ready, it's also caller's duty to differentiate if this
-// state is what it requests through RequestCtx, eg. given a unique id as
-// RequestCtx
-type ReadState struct {
-	Index      uint64
-	RequestCtx []byte
-}
-
-type readIndexStatus struct {
-	req   pb.Message
-	index uint64
-	acks  map[uint64]struct{}
-}
-
-type readOnly struct {
-	option           ReadOnlyOption
-	pendingReadIndex map[string]*readIndexStatus
-	readIndexQueue   []string
-}
-
-func newReadOnly(option ReadOnlyOption) *readOnly {
-	return &readOnly{
-		option:           option,
-		pendingReadIndex: make(map[string]*readIndexStatus),
-	}
-}
-
-// addRequest adds a read only reuqest into readonly struct.
-// `index` is the commit index of the raft state machine when it received
-// the read only request.
-// `m` is the original read only request message from the local or remote node.
-func (ro *readOnly) addRequest(index uint64, m pb.Message) {
-	ctx := string(m.Entries[0].Data)
-	if _, ok := ro.pendingReadIndex[ctx]; ok {
-		return
-	}
-	ro.pendingReadIndex[ctx] = &readIndexStatus{index: index, req: m, acks: make(map[uint64]struct{})}
-	ro.readIndexQueue = append(ro.readIndexQueue, ctx)
-}
-
-// recvAck notifies the readonly struct that the raft state machine received
-// an acknowledgment of the heartbeat that attached with the read only request
-// context.
-func (ro *readOnly) recvAck(m pb.Message) int {
-	rs, ok := ro.pendingReadIndex[string(m.Context)]
-	if !ok {
-		return 0
-	}
-
-	rs.acks[m.From] = struct{}{}
-	// add one to include an ack from local node
-	return len(rs.acks) + 1
-}
-
-// advance advances the read only request queue kept by the readonly struct.
-// It dequeues the requests until it finds the read only request that has
-// the same context as the given `m`.
-func (ro *readOnly) advance(m pb.Message) []*readIndexStatus {
-	var (
-		i     int
-		found bool
-	)
-
-	ctx := string(m.Context)
-	rss := []*readIndexStatus{}
-
-	for _, okctx := range ro.readIndexQueue {
-		i++
-		rs, ok := ro.pendingReadIndex[okctx]
-		if !ok {
-			panic("cannot find corresponding read state from pending map")
-		}
-		rss = append(rss, rs)
-		if okctx == ctx {
-			found = true
-			break
-		}
-	}
-
-	if found {
-		ro.readIndexQueue = ro.readIndexQueue[i:]
-		for _, rs := range rss {
-			delete(ro.pendingReadIndex, string(rs.req.Entries[0].Data))
-		}
-		return rss
-	}
-
-	return nil
-}
-
-// lastPendingRequestCtx returns the context of the last pending read only
-// request in readonly struct.
-func (ro *readOnly) lastPendingRequestCtx() string {
-	if len(ro.readIndexQueue) == 0 {
-		return ""
-	}
-	return ro.readIndexQueue[len(ro.readIndexQueue)-1]
-}
diff --git a/vendor/github.com/coreos/etcd/raft/status.go b/vendor/github.com/coreos/etcd/raft/status.go
deleted file mode 100644
index f4d3d86..0000000
--- a/vendor/github.com/coreos/etcd/raft/status.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import (
-	"fmt"
-
-	pb "github.com/coreos/etcd/raft/raftpb"
-)
-
-type Status struct {
-	ID uint64
-
-	pb.HardState
-	SoftState
-
-	Applied  uint64
-	Progress map[uint64]Progress
-
-	LeadTransferee uint64
-}
-
-// getStatus gets a copy of the current raft status.
-func getStatus(r *raft) Status {
-	s := Status{
-		ID:             r.id,
-		LeadTransferee: r.leadTransferee,
-	}
-
-	s.HardState = r.hardState()
-	s.SoftState = *r.softState()
-
-	s.Applied = r.raftLog.applied
-
-	if s.RaftState == StateLeader {
-		s.Progress = make(map[uint64]Progress)
-		for id, p := range r.prs {
-			s.Progress[id] = *p
-		}
-
-		for id, p := range r.learnerPrs {
-			s.Progress[id] = *p
-		}
-	}
-
-	return s
-}
-
-// MarshalJSON translates the raft status into JSON.
-// TODO: try to simplify this by introducing ID type into raft
-func (s Status) MarshalJSON() ([]byte, error) {
-	j := fmt.Sprintf(`{"id":"%x","term":%d,"vote":"%x","commit":%d,"lead":"%x","raftState":%q,"applied":%d,"progress":{`,
-		s.ID, s.Term, s.Vote, s.Commit, s.Lead, s.RaftState, s.Applied)
-
-	if len(s.Progress) == 0 {
-		j += "},"
-	} else {
-		for k, v := range s.Progress {
-			subj := fmt.Sprintf(`"%x":{"match":%d,"next":%d,"state":%q},`, k, v.Match, v.Next, v.State)
-			j += subj
-		}
-		// remove the trailing ","
-		j = j[:len(j)-1] + "},"
-	}
-
-	j += fmt.Sprintf(`"leadtransferee":"%x"}`, s.LeadTransferee)
-	return []byte(j), nil
-}
-
-func (s Status) String() string {
-	b, err := s.MarshalJSON()
-	if err != nil {
-		raftLogger.Panicf("unexpected error: %v", err)
-	}
-	return string(b)
-}
diff --git a/vendor/github.com/coreos/etcd/raft/storage.go b/vendor/github.com/coreos/etcd/raft/storage.go
deleted file mode 100644
index 69c3a7d..0000000
--- a/vendor/github.com/coreos/etcd/raft/storage.go
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import (
-	"errors"
-	"sync"
-
-	pb "github.com/coreos/etcd/raft/raftpb"
-)
-
-// ErrCompacted is returned by Storage.Entries/Compact when a requested
-// index is unavailable because it predates the last snapshot.
-var ErrCompacted = errors.New("requested index is unavailable due to compaction")
-
-// ErrSnapOutOfDate is returned by Storage.CreateSnapshot when a requested
-// index is older than the existing snapshot.
-var ErrSnapOutOfDate = errors.New("requested index is older than the existing snapshot")
-
-// ErrUnavailable is returned by Storage interface when the requested log entries
-// are unavailable.
-var ErrUnavailable = errors.New("requested entry at index is unavailable")
-
-// ErrSnapshotTemporarilyUnavailable is returned by the Storage interface when the required
-// snapshot is temporarily unavailable.
-var ErrSnapshotTemporarilyUnavailable = errors.New("snapshot is temporarily unavailable")
-
-// Storage is an interface that may be implemented by the application
-// to retrieve log entries from storage.
-//
-// If any Storage method returns an error, the raft instance will
-// become inoperable and refuse to participate in elections; the
-// application is responsible for cleanup and recovery in this case.
-type Storage interface {
-	// InitialState returns the saved HardState and ConfState information.
-	InitialState() (pb.HardState, pb.ConfState, error)
-	// Entries returns a slice of log entries in the range [lo,hi).
-	// MaxSize limits the total size of the log entries returned, but
-	// Entries returns at least one entry if any.
-	Entries(lo, hi, maxSize uint64) ([]pb.Entry, error)
-	// Term returns the term of entry i, which must be in the range
-	// [FirstIndex()-1, LastIndex()]. The term of the entry before
-	// FirstIndex is retained for matching purposes even though the
-	// rest of that entry may not be available.
-	Term(i uint64) (uint64, error)
-	// LastIndex returns the index of the last entry in the log.
-	LastIndex() (uint64, error)
-	// FirstIndex returns the index of the first log entry that is
-	// possibly available via Entries (older entries have been incorporated
-	// into the latest Snapshot; if storage only contains the dummy entry the
-	// first log entry is not available).
-	FirstIndex() (uint64, error)
-	// Snapshot returns the most recent snapshot.
-	// If snapshot is temporarily unavailable, it should return ErrSnapshotTemporarilyUnavailable,
-	// so raft state machine could know that Storage needs some time to prepare
-	// snapshot and call Snapshot later.
-	Snapshot() (pb.Snapshot, error)
-}
-
-// MemoryStorage implements the Storage interface backed by an
-// in-memory array.
-type MemoryStorage struct {
-	// Protects access to all fields. Most methods of MemoryStorage are
-	// run on the raft goroutine, but Append() is run on an application
-	// goroutine.
-	sync.Mutex
-
-	hardState pb.HardState
-	snapshot  pb.Snapshot
-	// ents[i] has raft log position i+snapshot.Metadata.Index
-	ents []pb.Entry
-}
-
-// NewMemoryStorage creates an empty MemoryStorage.
-func NewMemoryStorage() *MemoryStorage {
-	return &MemoryStorage{
-		// When starting from scratch populate the list with a dummy entry at term zero.
-		ents: make([]pb.Entry, 1),
-	}
-}
-
-// InitialState implements the Storage interface.
-func (ms *MemoryStorage) InitialState() (pb.HardState, pb.ConfState, error) {
-	return ms.hardState, ms.snapshot.Metadata.ConfState, nil
-}
-
-// SetHardState saves the current HardState.
-func (ms *MemoryStorage) SetHardState(st pb.HardState) error {
-	ms.Lock()
-	defer ms.Unlock()
-	ms.hardState = st
-	return nil
-}
-
-// Entries implements the Storage interface.
-func (ms *MemoryStorage) Entries(lo, hi, maxSize uint64) ([]pb.Entry, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	offset := ms.ents[0].Index
-	if lo <= offset {
-		return nil, ErrCompacted
-	}
-	if hi > ms.lastIndex()+1 {
-		raftLogger.Panicf("entries' hi(%d) is out of bound lastindex(%d)", hi, ms.lastIndex())
-	}
-	// only contains dummy entries.
-	if len(ms.ents) == 1 {
-		return nil, ErrUnavailable
-	}
-
-	ents := ms.ents[lo-offset : hi-offset]
-	return limitSize(ents, maxSize), nil
-}
-
-// Term implements the Storage interface.
-func (ms *MemoryStorage) Term(i uint64) (uint64, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	offset := ms.ents[0].Index
-	if i < offset {
-		return 0, ErrCompacted
-	}
-	if int(i-offset) >= len(ms.ents) {
-		return 0, ErrUnavailable
-	}
-	return ms.ents[i-offset].Term, nil
-}
-
-// LastIndex implements the Storage interface.
-func (ms *MemoryStorage) LastIndex() (uint64, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	return ms.lastIndex(), nil
-}
-
-func (ms *MemoryStorage) lastIndex() uint64 {
-	return ms.ents[0].Index + uint64(len(ms.ents)) - 1
-}
-
-// FirstIndex implements the Storage interface.
-func (ms *MemoryStorage) FirstIndex() (uint64, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	return ms.firstIndex(), nil
-}
-
-func (ms *MemoryStorage) firstIndex() uint64 {
-	return ms.ents[0].Index + 1
-}
-
-// Snapshot implements the Storage interface.
-func (ms *MemoryStorage) Snapshot() (pb.Snapshot, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	return ms.snapshot, nil
-}
-
-// ApplySnapshot overwrites the contents of this Storage object with
-// those of the given snapshot.
-func (ms *MemoryStorage) ApplySnapshot(snap pb.Snapshot) error {
-	ms.Lock()
-	defer ms.Unlock()
-
-	//handle check for old snapshot being applied
-	msIndex := ms.snapshot.Metadata.Index
-	snapIndex := snap.Metadata.Index
-	if msIndex >= snapIndex {
-		return ErrSnapOutOfDate
-	}
-
-	ms.snapshot = snap
-	ms.ents = []pb.Entry{{Term: snap.Metadata.Term, Index: snap.Metadata.Index}}
-	return nil
-}
-
-// CreateSnapshot makes a snapshot which can be retrieved with Snapshot() and
-// can be used to reconstruct the state at that point.
-// If any configuration changes have been made since the last compaction,
-// the result of the last ApplyConfChange must be passed in.
-func (ms *MemoryStorage) CreateSnapshot(i uint64, cs *pb.ConfState, data []byte) (pb.Snapshot, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	if i <= ms.snapshot.Metadata.Index {
-		return pb.Snapshot{}, ErrSnapOutOfDate
-	}
-
-	offset := ms.ents[0].Index
-	if i > ms.lastIndex() {
-		raftLogger.Panicf("snapshot %d is out of bound lastindex(%d)", i, ms.lastIndex())
-	}
-
-	ms.snapshot.Metadata.Index = i
-	ms.snapshot.Metadata.Term = ms.ents[i-offset].Term
-	if cs != nil {
-		ms.snapshot.Metadata.ConfState = *cs
-	}
-	ms.snapshot.Data = data
-	return ms.snapshot, nil
-}
-
-// Compact discards all log entries prior to compactIndex.
-// It is the application's responsibility to not attempt to compact an index
-// greater than raftLog.applied.
-func (ms *MemoryStorage) Compact(compactIndex uint64) error {
-	ms.Lock()
-	defer ms.Unlock()
-	offset := ms.ents[0].Index
-	if compactIndex <= offset {
-		return ErrCompacted
-	}
-	if compactIndex > ms.lastIndex() {
-		raftLogger.Panicf("compact %d is out of bound lastindex(%d)", compactIndex, ms.lastIndex())
-	}
-
-	i := compactIndex - offset
-	ents := make([]pb.Entry, 1, 1+uint64(len(ms.ents))-i)
-	ents[0].Index = ms.ents[i].Index
-	ents[0].Term = ms.ents[i].Term
-	ents = append(ents, ms.ents[i+1:]...)
-	ms.ents = ents
-	return nil
-}
-
-// Append the new entries to storage.
-// TODO (xiangli): ensure the entries are continuous and
-// entries[0].Index > ms.entries[0].Index
-func (ms *MemoryStorage) Append(entries []pb.Entry) error {
-	if len(entries) == 0 {
-		return nil
-	}
-
-	ms.Lock()
-	defer ms.Unlock()
-
-	first := ms.firstIndex()
-	last := entries[0].Index + uint64(len(entries)) - 1
-
-	// shortcut if there is no new entry.
-	if last < first {
-		return nil
-	}
-	// truncate compacted entries
-	if first > entries[0].Index {
-		entries = entries[first-entries[0].Index:]
-	}
-
-	offset := entries[0].Index - ms.ents[0].Index
-	switch {
-	case uint64(len(ms.ents)) > offset:
-		ms.ents = append([]pb.Entry{}, ms.ents[:offset]...)
-		ms.ents = append(ms.ents, entries...)
-	case uint64(len(ms.ents)) == offset:
-		ms.ents = append(ms.ents, entries...)
-	default:
-		raftLogger.Panicf("missing log entry [last: %d, append at: %d]",
-			ms.lastIndex(), entries[0].Index)
-	}
-	return nil
-}
diff --git a/vendor/github.com/coreos/etcd/raft/util.go b/vendor/github.com/coreos/etcd/raft/util.go
deleted file mode 100644
index f4141fe..0000000
--- a/vendor/github.com/coreos/etcd/raft/util.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package raft
-
-import (
-	"bytes"
-	"fmt"
-
-	pb "github.com/coreos/etcd/raft/raftpb"
-)
-
-func (st StateType) MarshalJSON() ([]byte, error) {
-	return []byte(fmt.Sprintf("%q", st.String())), nil
-}
-
-// uint64Slice implements sort interface
-type uint64Slice []uint64
-
-func (p uint64Slice) Len() int           { return len(p) }
-func (p uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
-func (p uint64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-func min(a, b uint64) uint64 {
-	if a > b {
-		return b
-	}
-	return a
-}
-
-func max(a, b uint64) uint64 {
-	if a > b {
-		return a
-	}
-	return b
-}
-
-func IsLocalMsg(msgt pb.MessageType) bool {
-	return msgt == pb.MsgHup || msgt == pb.MsgBeat || msgt == pb.MsgUnreachable ||
-		msgt == pb.MsgSnapStatus || msgt == pb.MsgCheckQuorum
-}
-
-func IsResponseMsg(msgt pb.MessageType) bool {
-	return msgt == pb.MsgAppResp || msgt == pb.MsgVoteResp || msgt == pb.MsgHeartbeatResp || msgt == pb.MsgUnreachable || msgt == pb.MsgPreVoteResp
-}
-
-// voteResponseType maps vote and prevote message types to their corresponding responses.
-func voteRespMsgType(msgt pb.MessageType) pb.MessageType {
-	switch msgt {
-	case pb.MsgVote:
-		return pb.MsgVoteResp
-	case pb.MsgPreVote:
-		return pb.MsgPreVoteResp
-	default:
-		panic(fmt.Sprintf("not a vote message: %s", msgt))
-	}
-}
-
-// EntryFormatter can be implemented by the application to provide human-readable formatting
-// of entry data. Nil is a valid EntryFormatter and will use a default format.
-type EntryFormatter func([]byte) string
-
-// DescribeMessage returns a concise human-readable description of a
-// Message for debugging.
-func DescribeMessage(m pb.Message, f EntryFormatter) string {
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "%x->%x %v Term:%d Log:%d/%d", m.From, m.To, m.Type, m.Term, m.LogTerm, m.Index)
-	if m.Reject {
-		fmt.Fprintf(&buf, " Rejected")
-		if m.RejectHint != 0 {
-			fmt.Fprintf(&buf, "(Hint:%d)", m.RejectHint)
-		}
-	}
-	if m.Commit != 0 {
-		fmt.Fprintf(&buf, " Commit:%d", m.Commit)
-	}
-	if len(m.Entries) > 0 {
-		fmt.Fprintf(&buf, " Entries:[")
-		for i, e := range m.Entries {
-			if i != 0 {
-				buf.WriteString(", ")
-			}
-			buf.WriteString(DescribeEntry(e, f))
-		}
-		fmt.Fprintf(&buf, "]")
-	}
-	if !IsEmptySnap(m.Snapshot) {
-		fmt.Fprintf(&buf, " Snapshot:%v", m.Snapshot)
-	}
-	return buf.String()
-}
-
-// DescribeEntry returns a concise human-readable description of an
-// Entry for debugging.
-func DescribeEntry(e pb.Entry, f EntryFormatter) string {
-	var formatted string
-	if e.Type == pb.EntryNormal && f != nil {
-		formatted = f(e.Data)
-	} else {
-		formatted = fmt.Sprintf("%q", e.Data)
-	}
-	return fmt.Sprintf("%d/%d %s %s", e.Term, e.Index, e.Type, formatted)
-}
-
-func limitSize(ents []pb.Entry, maxSize uint64) []pb.Entry {
-	if len(ents) == 0 {
-		return ents
-	}
-	size := ents[0].Size()
-	var limit int
-	for limit = 1; limit < len(ents); limit++ {
-		size += ents[limit].Size()
-		if uint64(size) > maxSize {
-			break
-		}
-	}
-	return ents[:limit]
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/coder.go b/vendor/github.com/coreos/etcd/rafthttp/coder.go
deleted file mode 100644
index 86ede97..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/coder.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import "github.com/coreos/etcd/raft/raftpb"
-
-type encoder interface {
-	// encode encodes the given message to an output stream.
-	encode(m *raftpb.Message) error
-}
-
-type decoder interface {
-	// decode decodes the message from an input stream.
-	decode() (raftpb.Message, error)
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/doc.go b/vendor/github.com/coreos/etcd/rafthttp/doc.go
deleted file mode 100644
index a9486a8..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package rafthttp implements HTTP transportation layer for etcd/raft pkg.
-package rafthttp
diff --git a/vendor/github.com/coreos/etcd/rafthttp/http.go b/vendor/github.com/coreos/etcd/rafthttp/http.go
deleted file mode 100644
index 223a5de..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/http.go
+++ /dev/null
@@ -1,366 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"path"
-	"strings"
-	"time"
-
-	pioutil "github.com/coreos/etcd/pkg/ioutil"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/snap"
-	"github.com/coreos/etcd/version"
-)
-
-const (
-	// connReadLimitByte limits the number of bytes
-	// a single read can read out.
-	//
-	// 64KB should be large enough for not causing
-	// throughput bottleneck as well as small enough
-	// for not causing a read timeout.
-	connReadLimitByte = 64 * 1024
-)
-
-var (
-	RaftPrefix         = "/raft"
-	ProbingPrefix      = path.Join(RaftPrefix, "probing")
-	RaftStreamPrefix   = path.Join(RaftPrefix, "stream")
-	RaftSnapshotPrefix = path.Join(RaftPrefix, "snapshot")
-
-	errIncompatibleVersion = errors.New("incompatible version")
-	errClusterIDMismatch   = errors.New("cluster ID mismatch")
-)
-
-type peerGetter interface {
-	Get(id types.ID) Peer
-}
-
-type writerToResponse interface {
-	WriteTo(w http.ResponseWriter)
-}
-
-type pipelineHandler struct {
-	tr  Transporter
-	r   Raft
-	cid types.ID
-}
-
-// newPipelineHandler returns a handler for handling raft messages
-// from pipeline for RaftPrefix.
-//
-// The handler reads out the raft message from request body,
-// and forwards it to the given raft state machine for processing.
-func newPipelineHandler(tr Transporter, r Raft, cid types.ID) http.Handler {
-	return &pipelineHandler{
-		tr:  tr,
-		r:   r,
-		cid: cid,
-	}
-}
-
-func (h *pipelineHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if r.Method != "POST" {
-		w.Header().Set("Allow", "POST")
-		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-		return
-	}
-
-	w.Header().Set("X-Etcd-Cluster-ID", h.cid.String())
-
-	if err := checkClusterCompatibilityFromHeader(r.Header, h.cid); err != nil {
-		http.Error(w, err.Error(), http.StatusPreconditionFailed)
-		return
-	}
-
-	addRemoteFromRequest(h.tr, r)
-
-	// Limit the data size that could be read from the request body, which ensures that read from
-	// connection will not time out accidentally due to possible blocking in underlying implementation.
-	limitedr := pioutil.NewLimitedBufferReader(r.Body, connReadLimitByte)
-	b, err := ioutil.ReadAll(limitedr)
-	if err != nil {
-		plog.Errorf("failed to read raft message (%v)", err)
-		http.Error(w, "error reading raft message", http.StatusBadRequest)
-		recvFailures.WithLabelValues(r.RemoteAddr).Inc()
-		return
-	}
-
-	var m raftpb.Message
-	if err := m.Unmarshal(b); err != nil {
-		plog.Errorf("failed to unmarshal raft message (%v)", err)
-		http.Error(w, "error unmarshaling raft message", http.StatusBadRequest)
-		recvFailures.WithLabelValues(r.RemoteAddr).Inc()
-		return
-	}
-
-	receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(len(b)))
-
-	if err := h.r.Process(context.TODO(), m); err != nil {
-		switch v := err.(type) {
-		case writerToResponse:
-			v.WriteTo(w)
-		default:
-			plog.Warningf("failed to process raft message (%v)", err)
-			http.Error(w, "error processing raft message", http.StatusInternalServerError)
-			w.(http.Flusher).Flush()
-			// disconnect the http stream
-			panic(err)
-		}
-		return
-	}
-
-	// Write StatusNoContent header after the message has been processed by
-	// raft, which facilitates the client to report MsgSnap status.
-	w.WriteHeader(http.StatusNoContent)
-}
-
-type snapshotHandler struct {
-	tr          Transporter
-	r           Raft
-	snapshotter *snap.Snapshotter
-	cid         types.ID
-}
-
-func newSnapshotHandler(tr Transporter, r Raft, snapshotter *snap.Snapshotter, cid types.ID) http.Handler {
-	return &snapshotHandler{
-		tr:          tr,
-		r:           r,
-		snapshotter: snapshotter,
-		cid:         cid,
-	}
-}
-
-const unknownSnapshotSender = "UNKNOWN_SNAPSHOT_SENDER"
-
-// ServeHTTP serves HTTP request to receive and process snapshot message.
-//
-// If request sender dies without closing underlying TCP connection,
-// the handler will keep waiting for the request body until TCP keepalive
-// finds out that the connection is broken after several minutes.
-// This is acceptable because
-// 1. snapshot messages sent through other TCP connections could still be
-// received and processed.
-// 2. this case should happen rarely, so no further optimization is done.
-func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	start := time.Now()
-
-	if r.Method != "POST" {
-		w.Header().Set("Allow", "POST")
-		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-		snapshotReceiveFailures.WithLabelValues(unknownSnapshotSender).Inc()
-		return
-	}
-
-	w.Header().Set("X-Etcd-Cluster-ID", h.cid.String())
-
-	if err := checkClusterCompatibilityFromHeader(r.Header, h.cid); err != nil {
-		http.Error(w, err.Error(), http.StatusPreconditionFailed)
-		snapshotReceiveFailures.WithLabelValues(unknownSnapshotSender).Inc()
-		return
-	}
-
-	addRemoteFromRequest(h.tr, r)
-
-	dec := &messageDecoder{r: r.Body}
-	// let snapshots be very large since they can exceed 512MB for large installations
-	m, err := dec.decodeLimit(uint64(1 << 63))
-	from := types.ID(m.From).String()
-	if err != nil {
-		msg := fmt.Sprintf("failed to decode raft message (%v)", err)
-		plog.Errorf(msg)
-		http.Error(w, msg, http.StatusBadRequest)
-		recvFailures.WithLabelValues(r.RemoteAddr).Inc()
-		snapshotReceiveFailures.WithLabelValues(from).Inc()
-		return
-	}
-
-	receivedBytes.WithLabelValues(from).Add(float64(m.Size()))
-
-	if m.Type != raftpb.MsgSnap {
-		plog.Errorf("unexpected raft message type %s on snapshot path", m.Type)
-		http.Error(w, "wrong raft message type", http.StatusBadRequest)
-		snapshotReceiveFailures.WithLabelValues(from).Inc()
-		return
-	}
-
-	plog.Infof("receiving database snapshot [index:%d, from %s] ...", m.Snapshot.Metadata.Index, types.ID(m.From))
-	// save incoming database snapshot.
-	n, err := h.snapshotter.SaveDBFrom(r.Body, m.Snapshot.Metadata.Index)
-	if err != nil {
-		msg := fmt.Sprintf("failed to save KV snapshot (%v)", err)
-		plog.Error(msg)
-		http.Error(w, msg, http.StatusInternalServerError)
-		snapshotReceiveFailures.WithLabelValues(from).Inc()
-		return
-	}
-	receivedBytes.WithLabelValues(from).Add(float64(n))
-	plog.Infof("received and saved database snapshot [index: %d, from: %s] successfully", m.Snapshot.Metadata.Index, types.ID(m.From))
-
-	if err := h.r.Process(context.TODO(), m); err != nil {
-		switch v := err.(type) {
-		// Process may return writerToResponse error when doing some
-		// additional checks before calling raft.Node.Step.
-		case writerToResponse:
-			v.WriteTo(w)
-		default:
-			msg := fmt.Sprintf("failed to process raft message (%v)", err)
-			plog.Warningf(msg)
-			http.Error(w, msg, http.StatusInternalServerError)
-			snapshotReceiveFailures.WithLabelValues(from).Inc()
-		}
-		return
-	}
-	// Write StatusNoContent header after the message has been processed by
-	// raft, which facilitates the client to report MsgSnap status.
-	w.WriteHeader(http.StatusNoContent)
-
-	snapshotReceive.WithLabelValues(from).Inc()
-	snapshotReceiveSeconds.WithLabelValues(from).Observe(time.Since(start).Seconds())
-}
-
-type streamHandler struct {
-	tr         *Transport
-	peerGetter peerGetter
-	r          Raft
-	id         types.ID
-	cid        types.ID
-}
-
-func newStreamHandler(tr *Transport, pg peerGetter, r Raft, id, cid types.ID) http.Handler {
-	return &streamHandler{
-		tr:         tr,
-		peerGetter: pg,
-		r:          r,
-		id:         id,
-		cid:        cid,
-	}
-}
-
-func (h *streamHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if r.Method != "GET" {
-		w.Header().Set("Allow", "GET")
-		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-		return
-	}
-
-	w.Header().Set("X-Server-Version", version.Version)
-	w.Header().Set("X-Etcd-Cluster-ID", h.cid.String())
-
-	if err := checkClusterCompatibilityFromHeader(r.Header, h.cid); err != nil {
-		http.Error(w, err.Error(), http.StatusPreconditionFailed)
-		return
-	}
-
-	var t streamType
-	switch path.Dir(r.URL.Path) {
-	case streamTypeMsgAppV2.endpoint():
-		t = streamTypeMsgAppV2
-	case streamTypeMessage.endpoint():
-		t = streamTypeMessage
-	default:
-		plog.Debugf("ignored unexpected streaming request path %s", r.URL.Path)
-		http.Error(w, "invalid path", http.StatusNotFound)
-		return
-	}
-
-	fromStr := path.Base(r.URL.Path)
-	from, err := types.IDFromString(fromStr)
-	if err != nil {
-		plog.Errorf("failed to parse from %s into ID (%v)", fromStr, err)
-		http.Error(w, "invalid from", http.StatusNotFound)
-		return
-	}
-	if h.r.IsIDRemoved(uint64(from)) {
-		plog.Warningf("rejected the stream from peer %s since it was removed", from)
-		http.Error(w, "removed member", http.StatusGone)
-		return
-	}
-	p := h.peerGetter.Get(from)
-	if p == nil {
-		// This may happen in following cases:
-		// 1. user starts a remote peer that belongs to a different cluster
-		// with the same cluster ID.
-		// 2. local etcd falls behind of the cluster, and cannot recognize
-		// the members that joined after its current progress.
-		if urls := r.Header.Get("X-PeerURLs"); urls != "" {
-			h.tr.AddRemote(from, strings.Split(urls, ","))
-		}
-		plog.Errorf("failed to find member %s in cluster %s", from, h.cid)
-		http.Error(w, "error sender not found", http.StatusNotFound)
-		return
-	}
-
-	wto := h.id.String()
-	if gto := r.Header.Get("X-Raft-To"); gto != wto {
-		plog.Errorf("streaming request ignored (ID mismatch got %s want %s)", gto, wto)
-		http.Error(w, "to field mismatch", http.StatusPreconditionFailed)
-		return
-	}
-
-	w.WriteHeader(http.StatusOK)
-	w.(http.Flusher).Flush()
-
-	c := newCloseNotifier()
-	conn := &outgoingConn{
-		t:       t,
-		Writer:  w,
-		Flusher: w.(http.Flusher),
-		Closer:  c,
-	}
-	p.attachOutgoingConn(conn)
-	<-c.closeNotify()
-}
-
-// checkClusterCompatibilityFromHeader checks the cluster compatibility of
-// the local member from the given header.
-// It checks whether the version of local member is compatible with
-// the versions in the header, and whether the cluster ID of local member
-// matches the one in the header.
-func checkClusterCompatibilityFromHeader(header http.Header, cid types.ID) error {
-	if err := checkVersionCompability(header.Get("X-Server-From"), serverVersion(header), minClusterVersion(header)); err != nil {
-		plog.Errorf("request version incompatibility (%v)", err)
-		return errIncompatibleVersion
-	}
-	if gcid := header.Get("X-Etcd-Cluster-ID"); gcid != cid.String() {
-		plog.Errorf("request cluster ID mismatch (got %s want %s)", gcid, cid)
-		return errClusterIDMismatch
-	}
-	return nil
-}
-
-type closeNotifier struct {
-	done chan struct{}
-}
-
-func newCloseNotifier() *closeNotifier {
-	return &closeNotifier{
-		done: make(chan struct{}),
-	}
-}
-
-func (n *closeNotifier) Close() error {
-	close(n.done)
-	return nil
-}
-
-func (n *closeNotifier) closeNotify() <-chan struct{} { return n.done }
diff --git a/vendor/github.com/coreos/etcd/rafthttp/metrics.go b/vendor/github.com/coreos/etcd/rafthttp/metrics.go
deleted file mode 100644
index 2066663..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/metrics.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	sentBytes = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "peer_sent_bytes_total",
-		Help:      "The total number of bytes sent to peers.",
-	},
-		[]string{"To"},
-	)
-
-	receivedBytes = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "peer_received_bytes_total",
-		Help:      "The total number of bytes received from peers.",
-	},
-		[]string{"From"},
-	)
-
-	sentFailures = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "peer_sent_failures_total",
-		Help:      "The total number of send failures from peers.",
-	},
-		[]string{"To"},
-	)
-
-	recvFailures = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "peer_received_failures_total",
-		Help:      "The total number of receive failures from peers.",
-	},
-		[]string{"From"},
-	)
-
-	snapshotSend = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_send_success",
-		Help:      "Total number of successful snapshot sends",
-	},
-		[]string{"To"},
-	)
-
-	snapshotSendFailures = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_send_failures",
-		Help:      "Total number of snapshot send failures",
-	},
-		[]string{"To"},
-	)
-
-	snapshotSendSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_send_total_duration_seconds",
-		Help:      "Total latency distributions of v3 snapshot sends",
-
-		// lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2
-		// highest bucket start of 0.1 sec * 2^9 == 51.2 sec
-		Buckets: prometheus.ExponentialBuckets(0.1, 2, 10),
-	},
-		[]string{"To"},
-	)
-
-	snapshotReceive = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_receive_success",
-		Help:      "Total number of successful snapshot receives",
-	},
-		[]string{"From"},
-	)
-
-	snapshotReceiveFailures = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_receive_failures",
-		Help:      "Total number of snapshot receive failures",
-	},
-		[]string{"From"},
-	)
-
-	snapshotReceiveSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_receive_total_duration_seconds",
-		Help:      "Total latency distributions of v3 snapshot receives",
-
-		// lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2
-		// highest bucket start of 0.1 sec * 2^9 == 51.2 sec
-		Buckets: prometheus.ExponentialBuckets(0.1, 2, 10),
-	},
-		[]string{"From"},
-	)
-
-	rtts = prometheus.NewHistogramVec(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "peer_round_trip_time_seconds",
-		Help:      "Round-Trip-Time histogram between peers.",
-		Buckets:   prometheus.ExponentialBuckets(0.0001, 2, 14),
-	},
-		[]string{"To"},
-	)
-)
-
-func init() {
-	prometheus.MustRegister(sentBytes)
-	prometheus.MustRegister(receivedBytes)
-	prometheus.MustRegister(sentFailures)
-	prometheus.MustRegister(recvFailures)
-
-	prometheus.MustRegister(snapshotSend)
-	prometheus.MustRegister(snapshotSendFailures)
-	prometheus.MustRegister(snapshotSendSeconds)
-	prometheus.MustRegister(snapshotReceive)
-	prometheus.MustRegister(snapshotReceiveFailures)
-	prometheus.MustRegister(snapshotReceiveSeconds)
-
-	prometheus.MustRegister(rtts)
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/msg_codec.go b/vendor/github.com/coreos/etcd/rafthttp/msg_codec.go
deleted file mode 100644
index ef59bc8..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/msg_codec.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"encoding/binary"
-	"errors"
-	"io"
-
-	"github.com/coreos/etcd/pkg/pbutil"
-	"github.com/coreos/etcd/raft/raftpb"
-)
-
-// messageEncoder is a encoder that can encode all kinds of messages.
-// It MUST be used with a paired messageDecoder.
-type messageEncoder struct {
-	w io.Writer
-}
-
-func (enc *messageEncoder) encode(m *raftpb.Message) error {
-	if err := binary.Write(enc.w, binary.BigEndian, uint64(m.Size())); err != nil {
-		return err
-	}
-	_, err := enc.w.Write(pbutil.MustMarshal(m))
-	return err
-}
-
-// messageDecoder is a decoder that can decode all kinds of messages.
-type messageDecoder struct {
-	r io.Reader
-}
-
-var (
-	readBytesLimit     uint64 = 512 * 1024 * 1024 // 512 MB
-	ErrExceedSizeLimit        = errors.New("rafthttp: error limit exceeded")
-)
-
-func (dec *messageDecoder) decode() (raftpb.Message, error) {
-	return dec.decodeLimit(readBytesLimit)
-}
-
-func (dec *messageDecoder) decodeLimit(numBytes uint64) (raftpb.Message, error) {
-	var m raftpb.Message
-	var l uint64
-	if err := binary.Read(dec.r, binary.BigEndian, &l); err != nil {
-		return m, err
-	}
-	if l > numBytes {
-		return m, ErrExceedSizeLimit
-	}
-	buf := make([]byte, int(l))
-	if _, err := io.ReadFull(dec.r, buf); err != nil {
-		return m, err
-	}
-	return m, m.Unmarshal(buf)
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go b/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go
deleted file mode 100644
index 013ffe7..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/msgappv2_codec.go
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"encoding/binary"
-	"fmt"
-	"io"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver/stats"
-	"github.com/coreos/etcd/pkg/pbutil"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft/raftpb"
-)
-
-const (
-	msgTypeLinkHeartbeat uint8 = 0
-	msgTypeAppEntries    uint8 = 1
-	msgTypeApp           uint8 = 2
-
-	msgAppV2BufSize = 1024 * 1024
-)
-
-// msgappv2 stream sends three types of message: linkHeartbeatMessage,
-// AppEntries and MsgApp. AppEntries is the MsgApp that is sent in
-// replicate state in raft, whose index and term are fully predictable.
-//
-// Data format of linkHeartbeatMessage:
-// | offset | bytes | description |
-// +--------+-------+-------------+
-// | 0      | 1     | \x00        |
-//
-// Data format of AppEntries:
-// | offset | bytes | description |
-// +--------+-------+-------------+
-// | 0      | 1     | \x01        |
-// | 1      | 8     | length of entries |
-// | 9      | 8     | length of first entry |
-// | 17     | n1    | first entry |
-// ...
-// | x      | 8     | length of k-th entry data |
-// | x+8    | nk    | k-th entry data |
-// | x+8+nk | 8     | commit index |
-//
-// Data format of MsgApp:
-// | offset | bytes | description |
-// +--------+-------+-------------+
-// | 0      | 1     | \x02        |
-// | 1      | 8     | length of encoded message |
-// | 9      | n     | encoded message |
-type msgAppV2Encoder struct {
-	w  io.Writer
-	fs *stats.FollowerStats
-
-	term      uint64
-	index     uint64
-	buf       []byte
-	uint64buf []byte
-	uint8buf  []byte
-}
-
-func newMsgAppV2Encoder(w io.Writer, fs *stats.FollowerStats) *msgAppV2Encoder {
-	return &msgAppV2Encoder{
-		w:         w,
-		fs:        fs,
-		buf:       make([]byte, msgAppV2BufSize),
-		uint64buf: make([]byte, 8),
-		uint8buf:  make([]byte, 1),
-	}
-}
-
-func (enc *msgAppV2Encoder) encode(m *raftpb.Message) error {
-	start := time.Now()
-	switch {
-	case isLinkHeartbeatMessage(m):
-		enc.uint8buf[0] = byte(msgTypeLinkHeartbeat)
-		if _, err := enc.w.Write(enc.uint8buf); err != nil {
-			return err
-		}
-	case enc.index == m.Index && enc.term == m.LogTerm && m.LogTerm == m.Term:
-		enc.uint8buf[0] = byte(msgTypeAppEntries)
-		if _, err := enc.w.Write(enc.uint8buf); err != nil {
-			return err
-		}
-		// write length of entries
-		binary.BigEndian.PutUint64(enc.uint64buf, uint64(len(m.Entries)))
-		if _, err := enc.w.Write(enc.uint64buf); err != nil {
-			return err
-		}
-		for i := 0; i < len(m.Entries); i++ {
-			// write length of entry
-			binary.BigEndian.PutUint64(enc.uint64buf, uint64(m.Entries[i].Size()))
-			if _, err := enc.w.Write(enc.uint64buf); err != nil {
-				return err
-			}
-			if n := m.Entries[i].Size(); n < msgAppV2BufSize {
-				if _, err := m.Entries[i].MarshalTo(enc.buf); err != nil {
-					return err
-				}
-				if _, err := enc.w.Write(enc.buf[:n]); err != nil {
-					return err
-				}
-			} else {
-				if _, err := enc.w.Write(pbutil.MustMarshal(&m.Entries[i])); err != nil {
-					return err
-				}
-			}
-			enc.index++
-		}
-		// write commit index
-		binary.BigEndian.PutUint64(enc.uint64buf, m.Commit)
-		if _, err := enc.w.Write(enc.uint64buf); err != nil {
-			return err
-		}
-		enc.fs.Succ(time.Since(start))
-	default:
-		if err := binary.Write(enc.w, binary.BigEndian, msgTypeApp); err != nil {
-			return err
-		}
-		// write size of message
-		if err := binary.Write(enc.w, binary.BigEndian, uint64(m.Size())); err != nil {
-			return err
-		}
-		// write message
-		if _, err := enc.w.Write(pbutil.MustMarshal(m)); err != nil {
-			return err
-		}
-
-		enc.term = m.Term
-		enc.index = m.Index
-		if l := len(m.Entries); l > 0 {
-			enc.index = m.Entries[l-1].Index
-		}
-		enc.fs.Succ(time.Since(start))
-	}
-	return nil
-}
-
-type msgAppV2Decoder struct {
-	r             io.Reader
-	local, remote types.ID
-
-	term      uint64
-	index     uint64
-	buf       []byte
-	uint64buf []byte
-	uint8buf  []byte
-}
-
-func newMsgAppV2Decoder(r io.Reader, local, remote types.ID) *msgAppV2Decoder {
-	return &msgAppV2Decoder{
-		r:         r,
-		local:     local,
-		remote:    remote,
-		buf:       make([]byte, msgAppV2BufSize),
-		uint64buf: make([]byte, 8),
-		uint8buf:  make([]byte, 1),
-	}
-}
-
-func (dec *msgAppV2Decoder) decode() (raftpb.Message, error) {
-	var (
-		m   raftpb.Message
-		typ uint8
-	)
-	if _, err := io.ReadFull(dec.r, dec.uint8buf); err != nil {
-		return m, err
-	}
-	typ = uint8(dec.uint8buf[0])
-	switch typ {
-	case msgTypeLinkHeartbeat:
-		return linkHeartbeatMessage, nil
-	case msgTypeAppEntries:
-		m = raftpb.Message{
-			Type:    raftpb.MsgApp,
-			From:    uint64(dec.remote),
-			To:      uint64(dec.local),
-			Term:    dec.term,
-			LogTerm: dec.term,
-			Index:   dec.index,
-		}
-
-		// decode entries
-		if _, err := io.ReadFull(dec.r, dec.uint64buf); err != nil {
-			return m, err
-		}
-		l := binary.BigEndian.Uint64(dec.uint64buf)
-		m.Entries = make([]raftpb.Entry, int(l))
-		for i := 0; i < int(l); i++ {
-			if _, err := io.ReadFull(dec.r, dec.uint64buf); err != nil {
-				return m, err
-			}
-			size := binary.BigEndian.Uint64(dec.uint64buf)
-			var buf []byte
-			if size < msgAppV2BufSize {
-				buf = dec.buf[:size]
-				if _, err := io.ReadFull(dec.r, buf); err != nil {
-					return m, err
-				}
-			} else {
-				buf = make([]byte, int(size))
-				if _, err := io.ReadFull(dec.r, buf); err != nil {
-					return m, err
-				}
-			}
-			dec.index++
-			// 1 alloc
-			pbutil.MustUnmarshal(&m.Entries[i], buf)
-		}
-		// decode commit index
-		if _, err := io.ReadFull(dec.r, dec.uint64buf); err != nil {
-			return m, err
-		}
-		m.Commit = binary.BigEndian.Uint64(dec.uint64buf)
-	case msgTypeApp:
-		var size uint64
-		if err := binary.Read(dec.r, binary.BigEndian, &size); err != nil {
-			return m, err
-		}
-		buf := make([]byte, int(size))
-		if _, err := io.ReadFull(dec.r, buf); err != nil {
-			return m, err
-		}
-		pbutil.MustUnmarshal(&m, buf)
-
-		dec.term = m.Term
-		dec.index = m.Index
-		if l := len(m.Entries); l > 0 {
-			dec.index = m.Entries[l-1].Index
-		}
-	default:
-		return m, fmt.Errorf("failed to parse type %d in msgappv2 stream", typ)
-	}
-	return m, nil
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/peer.go b/vendor/github.com/coreos/etcd/rafthttp/peer.go
deleted file mode 100644
index e9a25bb..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/peer.go
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"context"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver/stats"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/snap"
-
-	"golang.org/x/time/rate"
-)
-
-const (
-	// ConnReadTimeout and ConnWriteTimeout are the i/o timeout set on each connection rafthttp pkg creates.
-	// A 5 seconds timeout is good enough for recycling bad connections. Or we have to wait for
-	// tcp keepalive failing to detect a bad connection, which is at minutes level.
-	// For long term streaming connections, rafthttp pkg sends application level linkHeartbeatMessage
-	// to keep the connection alive.
-	// For short term pipeline connections, the connection MUST be killed to avoid it being
-	// put back to http pkg connection pool.
-	ConnReadTimeout  = 5 * time.Second
-	ConnWriteTimeout = 5 * time.Second
-
-	recvBufSize = 4096
-	// maxPendingProposals holds the proposals during one leader election process.
-	// Generally one leader election takes at most 1 sec. It should have
-	// 0-2 election conflicts, and each one takes 0.5 sec.
-	// We assume the number of concurrent proposers is smaller than 4096.
-	// One client blocks on its proposal for at least 1 sec, so 4096 is enough
-	// to hold all proposals.
-	maxPendingProposals = 4096
-
-	streamAppV2 = "streamMsgAppV2"
-	streamMsg   = "streamMsg"
-	pipelineMsg = "pipeline"
-	sendSnap    = "sendMsgSnap"
-)
-
-type Peer interface {
-	// send sends the message to the remote peer. The function is non-blocking
-	// and has no promise that the message will be received by the remote.
-	// When it fails to send message out, it will report the status to underlying
-	// raft.
-	send(m raftpb.Message)
-
-	// sendSnap sends the merged snapshot message to the remote peer. Its behavior
-	// is similar to send.
-	sendSnap(m snap.Message)
-
-	// update updates the urls of remote peer.
-	update(urls types.URLs)
-
-	// attachOutgoingConn attaches the outgoing connection to the peer for
-	// stream usage. After the call, the ownership of the outgoing
-	// connection hands over to the peer. The peer will close the connection
-	// when it is no longer used.
-	attachOutgoingConn(conn *outgoingConn)
-	// activeSince returns the time that the connection with the
-	// peer becomes active.
-	activeSince() time.Time
-	// stop performs any necessary finalization and terminates the peer
-	// elegantly.
-	stop()
-}
-
-// peer is the representative of a remote raft node. Local raft node sends
-// messages to the remote through peer.
-// Each peer has two underlying mechanisms to send out a message: stream and
-// pipeline.
-// A stream is a receiver initialized long-polling connection, which
-// is always open to transfer messages. Besides general stream, peer also has
-// a optimized stream for sending msgApp since msgApp accounts for large part
-// of all messages. Only raft leader uses the optimized stream to send msgApp
-// to the remote follower node.
-// A pipeline is a series of http clients that send http requests to the remote.
-// It is only used when the stream has not been established.
-type peer struct {
-	// id of the remote raft peer node
-	id types.ID
-	r  Raft
-
-	status *peerStatus
-
-	picker *urlPicker
-
-	msgAppV2Writer *streamWriter
-	writer         *streamWriter
-	pipeline       *pipeline
-	snapSender     *snapshotSender // snapshot sender to send v3 snapshot messages
-	msgAppV2Reader *streamReader
-	msgAppReader   *streamReader
-
-	recvc chan raftpb.Message
-	propc chan raftpb.Message
-
-	mu     sync.Mutex
-	paused bool
-
-	cancel context.CancelFunc // cancel pending works in go routine created by peer.
-	stopc  chan struct{}
-}
-
-func startPeer(transport *Transport, urls types.URLs, peerID types.ID, fs *stats.FollowerStats) *peer {
-	plog.Infof("starting peer %s...", peerID)
-	defer plog.Infof("started peer %s", peerID)
-
-	status := newPeerStatus(peerID)
-	picker := newURLPicker(urls)
-	errorc := transport.ErrorC
-	r := transport.Raft
-	pipeline := &pipeline{
-		peerID:        peerID,
-		tr:            transport,
-		picker:        picker,
-		status:        status,
-		followerStats: fs,
-		raft:          r,
-		errorc:        errorc,
-	}
-	pipeline.start()
-
-	p := &peer{
-		id:             peerID,
-		r:              r,
-		status:         status,
-		picker:         picker,
-		msgAppV2Writer: startStreamWriter(peerID, status, fs, r),
-		writer:         startStreamWriter(peerID, status, fs, r),
-		pipeline:       pipeline,
-		snapSender:     newSnapshotSender(transport, picker, peerID, status),
-		recvc:          make(chan raftpb.Message, recvBufSize),
-		propc:          make(chan raftpb.Message, maxPendingProposals),
-		stopc:          make(chan struct{}),
-	}
-
-	ctx, cancel := context.WithCancel(context.Background())
-	p.cancel = cancel
-	go func() {
-		for {
-			select {
-			case mm := <-p.recvc:
-				if err := r.Process(ctx, mm); err != nil {
-					plog.Warningf("failed to process raft message (%v)", err)
-				}
-			case <-p.stopc:
-				return
-			}
-		}
-	}()
-
-	// r.Process might block for processing proposal when there is no leader.
-	// Thus propc must be put into a separate routine with recvc to avoid blocking
-	// processing other raft messages.
-	go func() {
-		for {
-			select {
-			case mm := <-p.propc:
-				if err := r.Process(ctx, mm); err != nil {
-					plog.Warningf("failed to process raft message (%v)", err)
-				}
-			case <-p.stopc:
-				return
-			}
-		}
-	}()
-
-	p.msgAppV2Reader = &streamReader{
-		peerID: peerID,
-		typ:    streamTypeMsgAppV2,
-		tr:     transport,
-		picker: picker,
-		status: status,
-		recvc:  p.recvc,
-		propc:  p.propc,
-		rl:     rate.NewLimiter(transport.DialRetryFrequency, 1),
-	}
-	p.msgAppReader = &streamReader{
-		peerID: peerID,
-		typ:    streamTypeMessage,
-		tr:     transport,
-		picker: picker,
-		status: status,
-		recvc:  p.recvc,
-		propc:  p.propc,
-		rl:     rate.NewLimiter(transport.DialRetryFrequency, 1),
-	}
-
-	p.msgAppV2Reader.start()
-	p.msgAppReader.start()
-
-	return p
-}
-
-func (p *peer) send(m raftpb.Message) {
-	p.mu.Lock()
-	paused := p.paused
-	p.mu.Unlock()
-
-	if paused {
-		return
-	}
-
-	writec, name := p.pick(m)
-	select {
-	case writec <- m:
-	default:
-		p.r.ReportUnreachable(m.To)
-		if isMsgSnap(m) {
-			p.r.ReportSnapshot(m.To, raft.SnapshotFailure)
-		}
-		if p.status.isActive() {
-			plog.MergeWarningf("dropped internal raft message to %s since %s's sending buffer is full (bad/overloaded network)", p.id, name)
-		}
-		plog.Debugf("dropped %s to %s since %s's sending buffer is full", m.Type, p.id, name)
-		sentFailures.WithLabelValues(types.ID(m.To).String()).Inc()
-	}
-}
-
-func (p *peer) sendSnap(m snap.Message) {
-	go p.snapSender.send(m)
-}
-
-func (p *peer) update(urls types.URLs) {
-	p.picker.update(urls)
-}
-
-func (p *peer) attachOutgoingConn(conn *outgoingConn) {
-	var ok bool
-	switch conn.t {
-	case streamTypeMsgAppV2:
-		ok = p.msgAppV2Writer.attach(conn)
-	case streamTypeMessage:
-		ok = p.writer.attach(conn)
-	default:
-		plog.Panicf("unhandled stream type %s", conn.t)
-	}
-	if !ok {
-		conn.Close()
-	}
-}
-
-func (p *peer) activeSince() time.Time { return p.status.activeSince() }
-
-// Pause pauses the peer. The peer will simply drops all incoming
-// messages without returning an error.
-func (p *peer) Pause() {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	p.paused = true
-	p.msgAppReader.pause()
-	p.msgAppV2Reader.pause()
-}
-
-// Resume resumes a paused peer.
-func (p *peer) Resume() {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	p.paused = false
-	p.msgAppReader.resume()
-	p.msgAppV2Reader.resume()
-}
-
-func (p *peer) stop() {
-	plog.Infof("stopping peer %s...", p.id)
-	defer plog.Infof("stopped peer %s", p.id)
-
-	close(p.stopc)
-	p.cancel()
-	p.msgAppV2Writer.stop()
-	p.writer.stop()
-	p.pipeline.stop()
-	p.snapSender.stop()
-	p.msgAppV2Reader.stop()
-	p.msgAppReader.stop()
-}
-
-// pick picks a chan for sending the given message. The picked chan and the picked chan
-// string name are returned.
-func (p *peer) pick(m raftpb.Message) (writec chan<- raftpb.Message, picked string) {
-	var ok bool
-	// Considering MsgSnap may have a big size, e.g., 1G, and will block
-	// stream for a long time, only use one of the N pipelines to send MsgSnap.
-	if isMsgSnap(m) {
-		return p.pipeline.msgc, pipelineMsg
-	} else if writec, ok = p.msgAppV2Writer.writec(); ok && isMsgApp(m) {
-		return writec, streamAppV2
-	} else if writec, ok = p.writer.writec(); ok {
-		return writec, streamMsg
-	}
-	return p.pipeline.msgc, pipelineMsg
-}
-
-func isMsgApp(m raftpb.Message) bool { return m.Type == raftpb.MsgApp }
-
-func isMsgSnap(m raftpb.Message) bool { return m.Type == raftpb.MsgSnap }
diff --git a/vendor/github.com/coreos/etcd/rafthttp/peer_status.go b/vendor/github.com/coreos/etcd/rafthttp/peer_status.go
deleted file mode 100644
index 69cbd38..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/peer_status.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"fmt"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/pkg/types"
-)
-
-type failureType struct {
-	source string
-	action string
-}
-
-type peerStatus struct {
-	id     types.ID
-	mu     sync.Mutex // protect variables below
-	active bool
-	since  time.Time
-}
-
-func newPeerStatus(id types.ID) *peerStatus {
-	return &peerStatus{
-		id: id,
-	}
-}
-
-func (s *peerStatus) activate() {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	if !s.active {
-		plog.Infof("peer %s became active", s.id)
-		s.active = true
-		s.since = time.Now()
-	}
-}
-
-func (s *peerStatus) deactivate(failure failureType, reason string) {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	msg := fmt.Sprintf("failed to %s %s on %s (%s)", failure.action, s.id, failure.source, reason)
-	if s.active {
-		plog.Errorf(msg)
-		plog.Infof("peer %s became inactive (message send to peer failed)", s.id)
-		s.active = false
-		s.since = time.Time{}
-		return
-	}
-	plog.Debugf(msg)
-}
-
-func (s *peerStatus) isActive() bool {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.active
-}
-
-func (s *peerStatus) activeSince() time.Time {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.since
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/pipeline.go b/vendor/github.com/coreos/etcd/rafthttp/pipeline.go
deleted file mode 100644
index d9f07c3..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/pipeline.go
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"bytes"
-	"context"
-	"errors"
-	"io/ioutil"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver/stats"
-	"github.com/coreos/etcd/pkg/pbutil"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft"
-	"github.com/coreos/etcd/raft/raftpb"
-)
-
-const (
-	connPerPipeline = 4
-	// pipelineBufSize is the size of pipeline buffer, which helps hold the
-	// temporary network latency.
-	// The size ensures that pipeline does not drop messages when the network
-	// is out of work for less than 1 second in good path.
-	pipelineBufSize = 64
-)
-
-var errStopped = errors.New("stopped")
-
-type pipeline struct {
-	peerID types.ID
-
-	tr     *Transport
-	picker *urlPicker
-	status *peerStatus
-	raft   Raft
-	errorc chan error
-	// deprecate when we depercate v2 API
-	followerStats *stats.FollowerStats
-
-	msgc chan raftpb.Message
-	// wait for the handling routines
-	wg    sync.WaitGroup
-	stopc chan struct{}
-}
-
-func (p *pipeline) start() {
-	p.stopc = make(chan struct{})
-	p.msgc = make(chan raftpb.Message, pipelineBufSize)
-	p.wg.Add(connPerPipeline)
-	for i := 0; i < connPerPipeline; i++ {
-		go p.handle()
-	}
-	plog.Infof("started HTTP pipelining with peer %s", p.peerID)
-}
-
-func (p *pipeline) stop() {
-	close(p.stopc)
-	p.wg.Wait()
-	plog.Infof("stopped HTTP pipelining with peer %s", p.peerID)
-}
-
-func (p *pipeline) handle() {
-	defer p.wg.Done()
-
-	for {
-		select {
-		case m := <-p.msgc:
-			start := time.Now()
-			err := p.post(pbutil.MustMarshal(&m))
-			end := time.Now()
-
-			if err != nil {
-				p.status.deactivate(failureType{source: pipelineMsg, action: "write"}, err.Error())
-
-				if m.Type == raftpb.MsgApp && p.followerStats != nil {
-					p.followerStats.Fail()
-				}
-				p.raft.ReportUnreachable(m.To)
-				if isMsgSnap(m) {
-					p.raft.ReportSnapshot(m.To, raft.SnapshotFailure)
-				}
-				sentFailures.WithLabelValues(types.ID(m.To).String()).Inc()
-				continue
-			}
-
-			p.status.activate()
-			if m.Type == raftpb.MsgApp && p.followerStats != nil {
-				p.followerStats.Succ(end.Sub(start))
-			}
-			if isMsgSnap(m) {
-				p.raft.ReportSnapshot(m.To, raft.SnapshotFinish)
-			}
-			sentBytes.WithLabelValues(types.ID(m.To).String()).Add(float64(m.Size()))
-		case <-p.stopc:
-			return
-		}
-	}
-}
-
-// post POSTs a data payload to a url. Returns nil if the POST succeeds,
-// error on any failure.
-func (p *pipeline) post(data []byte) (err error) {
-	u := p.picker.pick()
-	req := createPostRequest(u, RaftPrefix, bytes.NewBuffer(data), "application/protobuf", p.tr.URLs, p.tr.ID, p.tr.ClusterID)
-
-	done := make(chan struct{}, 1)
-	ctx, cancel := context.WithCancel(context.Background())
-	req = req.WithContext(ctx)
-	go func() {
-		select {
-		case <-done:
-		case <-p.stopc:
-			waitSchedule()
-			cancel()
-		}
-	}()
-
-	resp, err := p.tr.pipelineRt.RoundTrip(req)
-	done <- struct{}{}
-	if err != nil {
-		p.picker.unreachable(u)
-		return err
-	}
-	b, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		p.picker.unreachable(u)
-		return err
-	}
-	resp.Body.Close()
-
-	err = checkPostResponse(resp, b, req, p.peerID)
-	if err != nil {
-		p.picker.unreachable(u)
-		// errMemberRemoved is a critical error since a removed member should
-		// always be stopped. So we use reportCriticalError to report it to errorc.
-		if err == errMemberRemoved {
-			reportCriticalError(err, p.errorc)
-		}
-		return err
-	}
-
-	return nil
-}
-
-// waitSchedule waits other goroutines to be scheduled for a while
-func waitSchedule() { time.Sleep(time.Millisecond) }
diff --git a/vendor/github.com/coreos/etcd/rafthttp/probing_status.go b/vendor/github.com/coreos/etcd/rafthttp/probing_status.go
deleted file mode 100644
index 109a0ae..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/probing_status.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"time"
-
-	"github.com/prometheus/client_golang/prometheus"
-	"github.com/xiang90/probing"
-)
-
-var (
-	// proberInterval must be shorter than read timeout.
-	// Or the connection will time-out.
-	proberInterval           = ConnReadTimeout - time.Second
-	statusMonitoringInterval = 30 * time.Second
-	statusErrorInterval      = 5 * time.Second
-)
-
-const (
-	// RoundTripperNameRaftMessage is the name of round-tripper that sends
-	// all other Raft messages, other than "snap.Message".
-	RoundTripperNameRaftMessage = "ROUND_TRIPPER_RAFT_MESSAGE"
-	// RoundTripperNameSnapshot is the name of round-tripper that sends merged snapshot message.
-	RoundTripperNameSnapshot = "ROUND_TRIPPER_SNAPSHOT"
-)
-
-func addPeerToProber(p probing.Prober, id string, us []string, roundTripperName string, rttSecProm *prometheus.HistogramVec) {
-	hus := make([]string, len(us))
-	for i := range us {
-		hus[i] = us[i] + ProbingPrefix
-	}
-
-	p.AddHTTP(id, proberInterval, hus)
-
-	s, err := p.Status(id)
-	if err != nil {
-		plog.Errorf("failed to add peer %s into prober", id)
-	} else {
-		go monitorProbingStatus(s, id, roundTripperName, rttSecProm)
-	}
-}
-
-func monitorProbingStatus(s probing.Status, id string, roundTripperName string, rttSecProm *prometheus.HistogramVec) {
-	// set the first interval short to log error early.
-	interval := statusErrorInterval
-	for {
-		select {
-		case <-time.After(interval):
-			if !s.Health() {
-				plog.Warningf("health check for peer %s could not connect: %v (prober %q)", id, s.Err(), roundTripperName)
-				interval = statusErrorInterval
-			} else {
-				interval = statusMonitoringInterval
-			}
-			if s.ClockDiff() > time.Second {
-				plog.Warningf("the clock difference against peer %s is too high [%v > %v] (prober %q)", id, s.ClockDiff(), time.Second, roundTripperName)
-			}
-			rttSecProm.WithLabelValues(id).Observe(s.SRTT().Seconds())
-		case <-s.StopNotify():
-			return
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/remote.go b/vendor/github.com/coreos/etcd/rafthttp/remote.go
deleted file mode 100644
index f7f9d2c..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/remote.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft/raftpb"
-)
-
-type remote struct {
-	id       types.ID
-	status   *peerStatus
-	pipeline *pipeline
-}
-
-func startRemote(tr *Transport, urls types.URLs, id types.ID) *remote {
-	picker := newURLPicker(urls)
-	status := newPeerStatus(id)
-	pipeline := &pipeline{
-		peerID: id,
-		tr:     tr,
-		picker: picker,
-		status: status,
-		raft:   tr.Raft,
-		errorc: tr.ErrorC,
-	}
-	pipeline.start()
-
-	return &remote{
-		id:       id,
-		status:   status,
-		pipeline: pipeline,
-	}
-}
-
-func (g *remote) send(m raftpb.Message) {
-	select {
-	case g.pipeline.msgc <- m:
-	default:
-		if g.status.isActive() {
-			plog.MergeWarningf("dropped internal raft message to %s since sending buffer is full (bad/overloaded network)", g.id)
-		}
-		plog.Debugf("dropped %s to %s since sending buffer is full", m.Type, g.id)
-		sentFailures.WithLabelValues(types.ID(m.To).String()).Inc()
-	}
-}
-
-func (g *remote) stop() {
-	g.pipeline.stop()
-}
-
-func (g *remote) Pause() {
-	g.stop()
-}
-
-func (g *remote) Resume() {
-	g.pipeline.start()
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go b/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go
deleted file mode 100644
index 24eb535..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/snapshot_sender.go
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"bytes"
-	"context"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"time"
-
-	"github.com/coreos/etcd/pkg/httputil"
-	pioutil "github.com/coreos/etcd/pkg/ioutil"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft"
-	"github.com/coreos/etcd/snap"
-)
-
-var (
-	// timeout for reading snapshot response body
-	snapResponseReadTimeout = 5 * time.Second
-)
-
-type snapshotSender struct {
-	from, to types.ID
-	cid      types.ID
-
-	tr     *Transport
-	picker *urlPicker
-	status *peerStatus
-	r      Raft
-	errorc chan error
-
-	stopc chan struct{}
-}
-
-func newSnapshotSender(tr *Transport, picker *urlPicker, to types.ID, status *peerStatus) *snapshotSender {
-	return &snapshotSender{
-		from:   tr.ID,
-		to:     to,
-		cid:    tr.ClusterID,
-		tr:     tr,
-		picker: picker,
-		status: status,
-		r:      tr.Raft,
-		errorc: tr.ErrorC,
-		stopc:  make(chan struct{}),
-	}
-}
-
-func (s *snapshotSender) stop() { close(s.stopc) }
-
-func (s *snapshotSender) send(merged snap.Message) {
-	start := time.Now()
-
-	m := merged.Message
-	to := types.ID(m.To).String()
-
-	body := createSnapBody(merged)
-	defer body.Close()
-
-	u := s.picker.pick()
-	req := createPostRequest(u, RaftSnapshotPrefix, body, "application/octet-stream", s.tr.URLs, s.from, s.cid)
-
-	plog.Infof("start to send database snapshot [index: %d, to %s]...", m.Snapshot.Metadata.Index, types.ID(m.To))
-
-	err := s.post(req)
-	defer merged.CloseWithError(err)
-	if err != nil {
-		plog.Warningf("database snapshot [index: %d, to: %s] failed to be sent out (%v)", m.Snapshot.Metadata.Index, types.ID(m.To), err)
-
-		// errMemberRemoved is a critical error since a removed member should
-		// always be stopped. So we use reportCriticalError to report it to errorc.
-		if err == errMemberRemoved {
-			reportCriticalError(err, s.errorc)
-		}
-
-		s.picker.unreachable(u)
-		s.status.deactivate(failureType{source: sendSnap, action: "post"}, err.Error())
-		s.r.ReportUnreachable(m.To)
-		// report SnapshotFailure to raft state machine. After raft state
-		// machine knows about it, it would pause a while and retry sending
-		// new snapshot message.
-		s.r.ReportSnapshot(m.To, raft.SnapshotFailure)
-		sentFailures.WithLabelValues(to).Inc()
-		snapshotSendFailures.WithLabelValues(to).Inc()
-		return
-	}
-	s.status.activate()
-	s.r.ReportSnapshot(m.To, raft.SnapshotFinish)
-	plog.Infof("database snapshot [index: %d, to: %s] sent out successfully", m.Snapshot.Metadata.Index, types.ID(m.To))
-
-	sentBytes.WithLabelValues(to).Add(float64(merged.TotalSize))
-
-	snapshotSend.WithLabelValues(to).Inc()
-	snapshotSendSeconds.WithLabelValues(to).Observe(time.Since(start).Seconds())
-}
-
-// post posts the given request.
-// It returns nil when request is sent out and processed successfully.
-func (s *snapshotSender) post(req *http.Request) (err error) {
-	ctx, cancel := context.WithCancel(context.Background())
-	req = req.WithContext(ctx)
-	defer cancel()
-
-	type responseAndError struct {
-		resp *http.Response
-		body []byte
-		err  error
-	}
-	result := make(chan responseAndError, 1)
-
-	go func() {
-		resp, err := s.tr.pipelineRt.RoundTrip(req)
-		if err != nil {
-			result <- responseAndError{resp, nil, err}
-			return
-		}
-
-		// close the response body when timeouts.
-		// prevents from reading the body forever when the other side dies right after
-		// successfully receives the request body.
-		time.AfterFunc(snapResponseReadTimeout, func() { httputil.GracefulClose(resp) })
-		body, err := ioutil.ReadAll(resp.Body)
-		result <- responseAndError{resp, body, err}
-	}()
-
-	select {
-	case <-s.stopc:
-		return errStopped
-	case r := <-result:
-		if r.err != nil {
-			return r.err
-		}
-		return checkPostResponse(r.resp, r.body, req, s.to)
-	}
-}
-
-func createSnapBody(merged snap.Message) io.ReadCloser {
-	buf := new(bytes.Buffer)
-	enc := &messageEncoder{w: buf}
-	// encode raft message
-	if err := enc.encode(&merged.Message); err != nil {
-		plog.Panicf("encode message error (%v)", err)
-	}
-
-	return &pioutil.ReaderAndCloser{
-		Reader: io.MultiReader(buf, merged.ReadCloser),
-		Closer: merged.ReadCloser,
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/stream.go b/vendor/github.com/coreos/etcd/rafthttp/stream.go
deleted file mode 100644
index af49c18..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/stream.go
+++ /dev/null
@@ -1,533 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"context"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"path"
-	"strings"
-	"sync"
-	"time"
-
-	"golang.org/x/time/rate"
-
-	"github.com/coreos/etcd/etcdserver/stats"
-	"github.com/coreos/etcd/pkg/httputil"
-	"github.com/coreos/etcd/pkg/transport"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/version"
-	"github.com/coreos/go-semver/semver"
-)
-
-const (
-	streamTypeMessage  streamType = "message"
-	streamTypeMsgAppV2 streamType = "msgappv2"
-
-	streamBufSize = 4096
-)
-
-var (
-	errUnsupportedStreamType = fmt.Errorf("unsupported stream type")
-
-	// the key is in string format "major.minor.patch"
-	supportedStream = map[string][]streamType{
-		"2.0.0": {},
-		"2.1.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"2.2.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"2.3.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"3.0.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"3.1.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"3.2.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"3.3.0": {streamTypeMsgAppV2, streamTypeMessage},
-	}
-)
-
-type streamType string
-
-func (t streamType) endpoint() string {
-	switch t {
-	case streamTypeMsgAppV2:
-		return path.Join(RaftStreamPrefix, "msgapp")
-	case streamTypeMessage:
-		return path.Join(RaftStreamPrefix, "message")
-	default:
-		plog.Panicf("unhandled stream type %v", t)
-		return ""
-	}
-}
-
-func (t streamType) String() string {
-	switch t {
-	case streamTypeMsgAppV2:
-		return "stream MsgApp v2"
-	case streamTypeMessage:
-		return "stream Message"
-	default:
-		return "unknown stream"
-	}
-}
-
-var (
-	// linkHeartbeatMessage is a special message used as heartbeat message in
-	// link layer. It never conflicts with messages from raft because raft
-	// doesn't send out messages without From and To fields.
-	linkHeartbeatMessage = raftpb.Message{Type: raftpb.MsgHeartbeat}
-)
-
-func isLinkHeartbeatMessage(m *raftpb.Message) bool {
-	return m.Type == raftpb.MsgHeartbeat && m.From == 0 && m.To == 0
-}
-
-type outgoingConn struct {
-	t streamType
-	io.Writer
-	http.Flusher
-	io.Closer
-}
-
-// streamWriter writes messages to the attached outgoingConn.
-type streamWriter struct {
-	peerID types.ID
-	status *peerStatus
-	fs     *stats.FollowerStats
-	r      Raft
-
-	mu      sync.Mutex // guard field working and closer
-	closer  io.Closer
-	working bool
-
-	msgc  chan raftpb.Message
-	connc chan *outgoingConn
-	stopc chan struct{}
-	done  chan struct{}
-}
-
-// startStreamWriter creates a streamWrite and starts a long running go-routine that accepts
-// messages and writes to the attached outgoing connection.
-func startStreamWriter(id types.ID, status *peerStatus, fs *stats.FollowerStats, r Raft) *streamWriter {
-	w := &streamWriter{
-		peerID: id,
-		status: status,
-		fs:     fs,
-		r:      r,
-		msgc:   make(chan raftpb.Message, streamBufSize),
-		connc:  make(chan *outgoingConn),
-		stopc:  make(chan struct{}),
-		done:   make(chan struct{}),
-	}
-	go w.run()
-	return w
-}
-
-func (cw *streamWriter) run() {
-	var (
-		msgc       chan raftpb.Message
-		heartbeatc <-chan time.Time
-		t          streamType
-		enc        encoder
-		flusher    http.Flusher
-		batched    int
-	)
-	tickc := time.NewTicker(ConnReadTimeout / 3)
-	defer tickc.Stop()
-	unflushed := 0
-
-	plog.Infof("started streaming with peer %s (writer)", cw.peerID)
-
-	for {
-		select {
-		case <-heartbeatc:
-			err := enc.encode(&linkHeartbeatMessage)
-			unflushed += linkHeartbeatMessage.Size()
-			if err == nil {
-				flusher.Flush()
-				batched = 0
-				sentBytes.WithLabelValues(cw.peerID.String()).Add(float64(unflushed))
-				unflushed = 0
-				continue
-			}
-
-			cw.status.deactivate(failureType{source: t.String(), action: "heartbeat"}, err.Error())
-
-			sentFailures.WithLabelValues(cw.peerID.String()).Inc()
-			cw.close()
-			plog.Warningf("lost the TCP streaming connection with peer %s (%s writer)", cw.peerID, t)
-			heartbeatc, msgc = nil, nil
-
-		case m := <-msgc:
-			err := enc.encode(&m)
-			if err == nil {
-				unflushed += m.Size()
-
-				if len(msgc) == 0 || batched > streamBufSize/2 {
-					flusher.Flush()
-					sentBytes.WithLabelValues(cw.peerID.String()).Add(float64(unflushed))
-					unflushed = 0
-					batched = 0
-				} else {
-					batched++
-				}
-
-				continue
-			}
-
-			cw.status.deactivate(failureType{source: t.String(), action: "write"}, err.Error())
-			cw.close()
-			plog.Warningf("lost the TCP streaming connection with peer %s (%s writer)", cw.peerID, t)
-			heartbeatc, msgc = nil, nil
-			cw.r.ReportUnreachable(m.To)
-			sentFailures.WithLabelValues(cw.peerID.String()).Inc()
-
-		case conn := <-cw.connc:
-			cw.mu.Lock()
-			closed := cw.closeUnlocked()
-			t = conn.t
-			switch conn.t {
-			case streamTypeMsgAppV2:
-				enc = newMsgAppV2Encoder(conn.Writer, cw.fs)
-			case streamTypeMessage:
-				enc = &messageEncoder{w: conn.Writer}
-			default:
-				plog.Panicf("unhandled stream type %s", conn.t)
-			}
-			flusher = conn.Flusher
-			unflushed = 0
-			cw.status.activate()
-			cw.closer = conn.Closer
-			cw.working = true
-			cw.mu.Unlock()
-
-			if closed {
-				plog.Warningf("closed an existing TCP streaming connection with peer %s (%s writer)", cw.peerID, t)
-			}
-			plog.Infof("established a TCP streaming connection with peer %s (%s writer)", cw.peerID, t)
-			heartbeatc, msgc = tickc.C, cw.msgc
-		case <-cw.stopc:
-			if cw.close() {
-				plog.Infof("closed the TCP streaming connection with peer %s (%s writer)", cw.peerID, t)
-			}
-			plog.Infof("stopped streaming with peer %s (writer)", cw.peerID)
-			close(cw.done)
-			return
-		}
-	}
-}
-
-func (cw *streamWriter) writec() (chan<- raftpb.Message, bool) {
-	cw.mu.Lock()
-	defer cw.mu.Unlock()
-	return cw.msgc, cw.working
-}
-
-func (cw *streamWriter) close() bool {
-	cw.mu.Lock()
-	defer cw.mu.Unlock()
-	return cw.closeUnlocked()
-}
-
-func (cw *streamWriter) closeUnlocked() bool {
-	if !cw.working {
-		return false
-	}
-	if err := cw.closer.Close(); err != nil {
-		plog.Errorf("peer %s (writer) connection close error: %v", cw.peerID, err)
-	}
-	if len(cw.msgc) > 0 {
-		cw.r.ReportUnreachable(uint64(cw.peerID))
-	}
-	cw.msgc = make(chan raftpb.Message, streamBufSize)
-	cw.working = false
-	return true
-}
-
-func (cw *streamWriter) attach(conn *outgoingConn) bool {
-	select {
-	case cw.connc <- conn:
-		return true
-	case <-cw.done:
-		return false
-	}
-}
-
-func (cw *streamWriter) stop() {
-	close(cw.stopc)
-	<-cw.done
-}
-
-// streamReader is a long-running go-routine that dials to the remote stream
-// endpoint and reads messages from the response body returned.
-type streamReader struct {
-	peerID types.ID
-	typ    streamType
-
-	tr     *Transport
-	picker *urlPicker
-	status *peerStatus
-	recvc  chan<- raftpb.Message
-	propc  chan<- raftpb.Message
-
-	rl *rate.Limiter // alters the frequency of dial retrial attempts
-
-	errorc chan<- error
-
-	mu     sync.Mutex
-	paused bool
-	closer io.Closer
-
-	ctx    context.Context
-	cancel context.CancelFunc
-	done   chan struct{}
-}
-
-func (cr *streamReader) start() {
-	cr.done = make(chan struct{})
-	if cr.errorc == nil {
-		cr.errorc = cr.tr.ErrorC
-	}
-	if cr.ctx == nil {
-		cr.ctx, cr.cancel = context.WithCancel(context.Background())
-	}
-	go cr.run()
-}
-
-func (cr *streamReader) run() {
-	t := cr.typ
-	plog.Infof("started streaming with peer %s (%s reader)", cr.peerID, t)
-	for {
-		rc, err := cr.dial(t)
-		if err != nil {
-			if err != errUnsupportedStreamType {
-				cr.status.deactivate(failureType{source: t.String(), action: "dial"}, err.Error())
-			}
-		} else {
-			cr.status.activate()
-			plog.Infof("established a TCP streaming connection with peer %s (%s reader)", cr.peerID, cr.typ)
-			err = cr.decodeLoop(rc, t)
-			plog.Warningf("lost the TCP streaming connection with peer %s (%s reader)", cr.peerID, cr.typ)
-			switch {
-			// all data is read out
-			case err == io.EOF:
-			// connection is closed by the remote
-			case transport.IsClosedConnError(err):
-			default:
-				cr.status.deactivate(failureType{source: t.String(), action: "read"}, err.Error())
-			}
-		}
-		// Wait for a while before new dial attempt
-		err = cr.rl.Wait(cr.ctx)
-		if cr.ctx.Err() != nil {
-			plog.Infof("stopped streaming with peer %s (%s reader)", cr.peerID, t)
-			close(cr.done)
-			return
-		}
-		if err != nil {
-			plog.Errorf("streaming with peer %s (%s reader) rate limiter error: %v", cr.peerID, t, err)
-		}
-	}
-}
-
-func (cr *streamReader) decodeLoop(rc io.ReadCloser, t streamType) error {
-	var dec decoder
-	cr.mu.Lock()
-	switch t {
-	case streamTypeMsgAppV2:
-		dec = newMsgAppV2Decoder(rc, cr.tr.ID, cr.peerID)
-	case streamTypeMessage:
-		dec = &messageDecoder{r: rc}
-	default:
-		plog.Panicf("unhandled stream type %s", t)
-	}
-	select {
-	case <-cr.ctx.Done():
-		cr.mu.Unlock()
-		if err := rc.Close(); err != nil {
-			return err
-		}
-		return io.EOF
-	default:
-		cr.closer = rc
-	}
-	cr.mu.Unlock()
-
-	for {
-		m, err := dec.decode()
-		if err != nil {
-			cr.mu.Lock()
-			cr.close()
-			cr.mu.Unlock()
-			return err
-		}
-
-		receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(m.Size()))
-
-		cr.mu.Lock()
-		paused := cr.paused
-		cr.mu.Unlock()
-
-		if paused {
-			continue
-		}
-
-		if isLinkHeartbeatMessage(&m) {
-			// raft is not interested in link layer
-			// heartbeat message, so we should ignore
-			// it.
-			continue
-		}
-
-		recvc := cr.recvc
-		if m.Type == raftpb.MsgProp {
-			recvc = cr.propc
-		}
-
-		select {
-		case recvc <- m:
-		default:
-			if cr.status.isActive() {
-				plog.MergeWarningf("dropped internal raft message from %s since receiving buffer is full (overloaded network)", types.ID(m.From))
-			}
-			plog.Debugf("dropped %s from %s since receiving buffer is full", m.Type, types.ID(m.From))
-			recvFailures.WithLabelValues(types.ID(m.From).String()).Inc()
-		}
-	}
-}
-
-func (cr *streamReader) stop() {
-	cr.mu.Lock()
-	cr.cancel()
-	cr.close()
-	cr.mu.Unlock()
-	<-cr.done
-}
-
-func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) {
-	u := cr.picker.pick()
-	uu := u
-	uu.Path = path.Join(t.endpoint(), cr.tr.ID.String())
-
-	req, err := http.NewRequest("GET", uu.String(), nil)
-	if err != nil {
-		cr.picker.unreachable(u)
-		return nil, fmt.Errorf("failed to make http request to %v (%v)", u, err)
-	}
-	req.Header.Set("X-Server-From", cr.tr.ID.String())
-	req.Header.Set("X-Server-Version", version.Version)
-	req.Header.Set("X-Min-Cluster-Version", version.MinClusterVersion)
-	req.Header.Set("X-Etcd-Cluster-ID", cr.tr.ClusterID.String())
-	req.Header.Set("X-Raft-To", cr.peerID.String())
-
-	setPeerURLsHeader(req, cr.tr.URLs)
-
-	req = req.WithContext(cr.ctx)
-
-	cr.mu.Lock()
-	select {
-	case <-cr.ctx.Done():
-		cr.mu.Unlock()
-		return nil, fmt.Errorf("stream reader is stopped")
-	default:
-	}
-	cr.mu.Unlock()
-
-	resp, err := cr.tr.streamRt.RoundTrip(req)
-	if err != nil {
-		cr.picker.unreachable(u)
-		return nil, err
-	}
-
-	rv := serverVersion(resp.Header)
-	lv := semver.Must(semver.NewVersion(version.Version))
-	if compareMajorMinorVersion(rv, lv) == -1 && !checkStreamSupport(rv, t) {
-		httputil.GracefulClose(resp)
-		cr.picker.unreachable(u)
-		return nil, errUnsupportedStreamType
-	}
-
-	switch resp.StatusCode {
-	case http.StatusGone:
-		httputil.GracefulClose(resp)
-		cr.picker.unreachable(u)
-		reportCriticalError(errMemberRemoved, cr.errorc)
-		return nil, errMemberRemoved
-	case http.StatusOK:
-		return resp.Body, nil
-	case http.StatusNotFound:
-		httputil.GracefulClose(resp)
-		cr.picker.unreachable(u)
-		return nil, fmt.Errorf("peer %s failed to find local node %s", cr.peerID, cr.tr.ID)
-	case http.StatusPreconditionFailed:
-		b, err := ioutil.ReadAll(resp.Body)
-		if err != nil {
-			cr.picker.unreachable(u)
-			return nil, err
-		}
-		httputil.GracefulClose(resp)
-		cr.picker.unreachable(u)
-
-		switch strings.TrimSuffix(string(b), "\n") {
-		case errIncompatibleVersion.Error():
-			plog.Errorf("request sent was ignored by peer %s (server version incompatible)", cr.peerID)
-			return nil, errIncompatibleVersion
-		case errClusterIDMismatch.Error():
-			plog.Errorf("request sent was ignored (cluster ID mismatch: peer[%s]=%s, local=%s)",
-				cr.peerID, resp.Header.Get("X-Etcd-Cluster-ID"), cr.tr.ClusterID)
-			return nil, errClusterIDMismatch
-		default:
-			return nil, fmt.Errorf("unhandled error %q when precondition failed", string(b))
-		}
-	default:
-		httputil.GracefulClose(resp)
-		cr.picker.unreachable(u)
-		return nil, fmt.Errorf("unhandled http status %d", resp.StatusCode)
-	}
-}
-
-func (cr *streamReader) close() {
-	if cr.closer != nil {
-		if err := cr.closer.Close(); err != nil {
-			plog.Errorf("peer %s (reader) connection close error: %v", cr.peerID, err)
-		}
-	}
-	cr.closer = nil
-}
-
-func (cr *streamReader) pause() {
-	cr.mu.Lock()
-	defer cr.mu.Unlock()
-	cr.paused = true
-}
-
-func (cr *streamReader) resume() {
-	cr.mu.Lock()
-	defer cr.mu.Unlock()
-	cr.paused = false
-}
-
-// checkStreamSupport checks whether the stream type is supported in the
-// given version.
-func checkStreamSupport(v *semver.Version, t streamType) bool {
-	nv := &semver.Version{Major: v.Major, Minor: v.Minor}
-	for _, s := range supportedStream[nv.String()] {
-		if s == t {
-			return true
-		}
-	}
-	return false
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/transport.go b/vendor/github.com/coreos/etcd/rafthttp/transport.go
deleted file mode 100644
index 16e854c..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/transport.go
+++ /dev/null
@@ -1,438 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"context"
-	"net/http"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/etcdserver/stats"
-	"github.com/coreos/etcd/pkg/logutil"
-	"github.com/coreos/etcd/pkg/transport"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/raft"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/snap"
-
-	"github.com/coreos/pkg/capnslog"
-	"github.com/xiang90/probing"
-	"golang.org/x/time/rate"
-)
-
-var plog = logutil.NewMergeLogger(capnslog.NewPackageLogger("github.com/coreos/etcd", "rafthttp"))
-
-type Raft interface {
-	Process(ctx context.Context, m raftpb.Message) error
-	IsIDRemoved(id uint64) bool
-	ReportUnreachable(id uint64)
-	ReportSnapshot(id uint64, status raft.SnapshotStatus)
-}
-
-type Transporter interface {
-	// Start starts the given Transporter.
-	// Start MUST be called before calling other functions in the interface.
-	Start() error
-	// Handler returns the HTTP handler of the transporter.
-	// A transporter HTTP handler handles the HTTP requests
-	// from remote peers.
-	// The handler MUST be used to handle RaftPrefix(/raft)
-	// endpoint.
-	Handler() http.Handler
-	// Send sends out the given messages to the remote peers.
-	// Each message has a To field, which is an id that maps
-	// to an existing peer in the transport.
-	// If the id cannot be found in the transport, the message
-	// will be ignored.
-	Send(m []raftpb.Message)
-	// SendSnapshot sends out the given snapshot message to a remote peer.
-	// The behavior of SendSnapshot is similar to Send.
-	SendSnapshot(m snap.Message)
-	// AddRemote adds a remote with given peer urls into the transport.
-	// A remote helps newly joined member to catch up the progress of cluster,
-	// and will not be used after that.
-	// It is the caller's responsibility to ensure the urls are all valid,
-	// or it panics.
-	AddRemote(id types.ID, urls []string)
-	// AddPeer adds a peer with given peer urls into the transport.
-	// It is the caller's responsibility to ensure the urls are all valid,
-	// or it panics.
-	// Peer urls are used to connect to the remote peer.
-	AddPeer(id types.ID, urls []string)
-	// RemovePeer removes the peer with given id.
-	RemovePeer(id types.ID)
-	// RemoveAllPeers removes all the existing peers in the transport.
-	RemoveAllPeers()
-	// UpdatePeer updates the peer urls of the peer with the given id.
-	// It is the caller's responsibility to ensure the urls are all valid,
-	// or it panics.
-	UpdatePeer(id types.ID, urls []string)
-	// ActiveSince returns the time that the connection with the peer
-	// of the given id becomes active.
-	// If the connection is active since peer was added, it returns the adding time.
-	// If the connection is currently inactive, it returns zero time.
-	ActiveSince(id types.ID) time.Time
-	// ActivePeers returns the number of active peers.
-	ActivePeers() int
-	// Stop closes the connections and stops the transporter.
-	Stop()
-}
-
-// Transport implements Transporter interface. It provides the functionality
-// to send raft messages to peers, and receive raft messages from peers.
-// User should call Handler method to get a handler to serve requests
-// received from peerURLs.
-// User needs to call Start before calling other functions, and call
-// Stop when the Transport is no longer used.
-type Transport struct {
-	DialTimeout time.Duration // maximum duration before timing out dial of the request
-	// DialRetryFrequency defines the frequency of streamReader dial retrial attempts;
-	// a distinct rate limiter is created per every peer (default value: 10 events/sec)
-	DialRetryFrequency rate.Limit
-
-	TLSInfo transport.TLSInfo // TLS information used when creating connection
-
-	ID          types.ID   // local member ID
-	URLs        types.URLs // local peer URLs
-	ClusterID   types.ID   // raft cluster ID for request validation
-	Raft        Raft       // raft state machine, to which the Transport forwards received messages and reports status
-	Snapshotter *snap.Snapshotter
-	ServerStats *stats.ServerStats // used to record general transportation statistics
-	// used to record transportation statistics with followers when
-	// performing as leader in raft protocol
-	LeaderStats *stats.LeaderStats
-	// ErrorC is used to report detected critical errors, e.g.,
-	// the member has been permanently removed from the cluster
-	// When an error is received from ErrorC, user should stop raft state
-	// machine and thus stop the Transport.
-	ErrorC chan error
-
-	streamRt   http.RoundTripper // roundTripper used by streams
-	pipelineRt http.RoundTripper // roundTripper used by pipelines
-
-	mu      sync.RWMutex         // protect the remote and peer map
-	remotes map[types.ID]*remote // remotes map that helps newly joined member to catch up
-	peers   map[types.ID]Peer    // peers map
-
-	pipelineProber probing.Prober
-	streamProber   probing.Prober
-}
-
-func (t *Transport) Start() error {
-	var err error
-	t.streamRt, err = newStreamRoundTripper(t.TLSInfo, t.DialTimeout)
-	if err != nil {
-		return err
-	}
-	t.pipelineRt, err = NewRoundTripper(t.TLSInfo, t.DialTimeout)
-	if err != nil {
-		return err
-	}
-	t.remotes = make(map[types.ID]*remote)
-	t.peers = make(map[types.ID]Peer)
-	t.pipelineProber = probing.NewProber(t.pipelineRt)
-	t.streamProber = probing.NewProber(t.streamRt)
-
-	// If client didn't provide dial retry frequency, use the default
-	// (100ms backoff between attempts to create a new stream),
-	// so it doesn't bring too much overhead when retry.
-	if t.DialRetryFrequency == 0 {
-		t.DialRetryFrequency = rate.Every(100 * time.Millisecond)
-	}
-	return nil
-}
-
-func (t *Transport) Handler() http.Handler {
-	pipelineHandler := newPipelineHandler(t, t.Raft, t.ClusterID)
-	streamHandler := newStreamHandler(t, t, t.Raft, t.ID, t.ClusterID)
-	snapHandler := newSnapshotHandler(t, t.Raft, t.Snapshotter, t.ClusterID)
-	mux := http.NewServeMux()
-	mux.Handle(RaftPrefix, pipelineHandler)
-	mux.Handle(RaftStreamPrefix+"/", streamHandler)
-	mux.Handle(RaftSnapshotPrefix, snapHandler)
-	mux.Handle(ProbingPrefix, probing.NewHandler())
-	return mux
-}
-
-func (t *Transport) Get(id types.ID) Peer {
-	t.mu.RLock()
-	defer t.mu.RUnlock()
-	return t.peers[id]
-}
-
-func (t *Transport) Send(msgs []raftpb.Message) {
-	for _, m := range msgs {
-		if m.To == 0 {
-			// ignore intentionally dropped message
-			continue
-		}
-		to := types.ID(m.To)
-
-		t.mu.RLock()
-		p, pok := t.peers[to]
-		g, rok := t.remotes[to]
-		t.mu.RUnlock()
-
-		if pok {
-			if m.Type == raftpb.MsgApp {
-				t.ServerStats.SendAppendReq(m.Size())
-			}
-			p.send(m)
-			continue
-		}
-
-		if rok {
-			g.send(m)
-			continue
-		}
-
-		plog.Debugf("ignored message %s (sent to unknown peer %s)", m.Type, to)
-	}
-}
-
-func (t *Transport) Stop() {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	for _, r := range t.remotes {
-		r.stop()
-	}
-	for _, p := range t.peers {
-		p.stop()
-	}
-	t.pipelineProber.RemoveAll()
-	t.streamProber.RemoveAll()
-	if tr, ok := t.streamRt.(*http.Transport); ok {
-		tr.CloseIdleConnections()
-	}
-	if tr, ok := t.pipelineRt.(*http.Transport); ok {
-		tr.CloseIdleConnections()
-	}
-	t.peers = nil
-	t.remotes = nil
-}
-
-// CutPeer drops messages to the specified peer.
-func (t *Transport) CutPeer(id types.ID) {
-	t.mu.RLock()
-	p, pok := t.peers[id]
-	g, gok := t.remotes[id]
-	t.mu.RUnlock()
-
-	if pok {
-		p.(Pausable).Pause()
-	}
-	if gok {
-		g.Pause()
-	}
-}
-
-// MendPeer recovers the message dropping behavior of the given peer.
-func (t *Transport) MendPeer(id types.ID) {
-	t.mu.RLock()
-	p, pok := t.peers[id]
-	g, gok := t.remotes[id]
-	t.mu.RUnlock()
-
-	if pok {
-		p.(Pausable).Resume()
-	}
-	if gok {
-		g.Resume()
-	}
-}
-
-func (t *Transport) AddRemote(id types.ID, us []string) {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	if t.remotes == nil {
-		// there's no clean way to shutdown the golang http server
-		// (see: https://github.com/golang/go/issues/4674) before
-		// stopping the transport; ignore any new connections.
-		return
-	}
-	if _, ok := t.peers[id]; ok {
-		return
-	}
-	if _, ok := t.remotes[id]; ok {
-		return
-	}
-	urls, err := types.NewURLs(us)
-	if err != nil {
-		plog.Panicf("newURLs %+v should never fail: %+v", us, err)
-	}
-	t.remotes[id] = startRemote(t, urls, id)
-}
-
-func (t *Transport) AddPeer(id types.ID, us []string) {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-
-	if t.peers == nil {
-		panic("transport stopped")
-	}
-	if _, ok := t.peers[id]; ok {
-		return
-	}
-	urls, err := types.NewURLs(us)
-	if err != nil {
-		plog.Panicf("newURLs %+v should never fail: %+v", us, err)
-	}
-	fs := t.LeaderStats.Follower(id.String())
-	t.peers[id] = startPeer(t, urls, id, fs)
-	addPeerToProber(t.pipelineProber, id.String(), us, RoundTripperNameSnapshot, rtts)
-	addPeerToProber(t.streamProber, id.String(), us, RoundTripperNameRaftMessage, rtts)
-	plog.Infof("added peer %s", id)
-}
-
-func (t *Transport) RemovePeer(id types.ID) {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	t.removePeer(id)
-}
-
-func (t *Transport) RemoveAllPeers() {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	for id := range t.peers {
-		t.removePeer(id)
-	}
-}
-
-// the caller of this function must have the peers mutex.
-func (t *Transport) removePeer(id types.ID) {
-	if peer, ok := t.peers[id]; ok {
-		peer.stop()
-	} else {
-		plog.Panicf("unexpected removal of unknown peer '%d'", id)
-	}
-	delete(t.peers, id)
-	delete(t.LeaderStats.Followers, id.String())
-	t.pipelineProber.Remove(id.String())
-	t.streamProber.Remove(id.String())
-	plog.Infof("removed peer %s", id)
-}
-
-func (t *Transport) UpdatePeer(id types.ID, us []string) {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	// TODO: return error or just panic?
-	if _, ok := t.peers[id]; !ok {
-		return
-	}
-	urls, err := types.NewURLs(us)
-	if err != nil {
-		plog.Panicf("newURLs %+v should never fail: %+v", us, err)
-	}
-	t.peers[id].update(urls)
-
-	t.pipelineProber.Remove(id.String())
-	addPeerToProber(t.pipelineProber, id.String(), us, RoundTripperNameSnapshot, rtts)
-	t.streamProber.Remove(id.String())
-	addPeerToProber(t.streamProber, id.String(), us, RoundTripperNameRaftMessage, rtts)
-	plog.Infof("updated peer %s", id)
-}
-
-func (t *Transport) ActiveSince(id types.ID) time.Time {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	if p, ok := t.peers[id]; ok {
-		return p.activeSince()
-	}
-	return time.Time{}
-}
-
-func (t *Transport) SendSnapshot(m snap.Message) {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	p := t.peers[types.ID(m.To)]
-	if p == nil {
-		m.CloseWithError(errMemberNotFound)
-		return
-	}
-	p.sendSnap(m)
-}
-
-// Pausable is a testing interface for pausing transport traffic.
-type Pausable interface {
-	Pause()
-	Resume()
-}
-
-func (t *Transport) Pause() {
-	for _, p := range t.peers {
-		p.(Pausable).Pause()
-	}
-}
-
-func (t *Transport) Resume() {
-	for _, p := range t.peers {
-		p.(Pausable).Resume()
-	}
-}
-
-// ActivePeers returns a channel that closes when an initial
-// peer connection has been established. Use this to wait until the
-// first peer connection becomes active.
-func (t *Transport) ActivePeers() (cnt int) {
-	t.mu.RLock()
-	defer t.mu.RUnlock()
-	for _, p := range t.peers {
-		if !p.activeSince().IsZero() {
-			cnt++
-		}
-	}
-	return cnt
-}
-
-type nopTransporter struct{}
-
-func NewNopTransporter() Transporter {
-	return &nopTransporter{}
-}
-
-func (s *nopTransporter) Start() error                        { return nil }
-func (s *nopTransporter) Handler() http.Handler               { return nil }
-func (s *nopTransporter) Send(m []raftpb.Message)             {}
-func (s *nopTransporter) SendSnapshot(m snap.Message)         {}
-func (s *nopTransporter) AddRemote(id types.ID, us []string)  {}
-func (s *nopTransporter) AddPeer(id types.ID, us []string)    {}
-func (s *nopTransporter) RemovePeer(id types.ID)              {}
-func (s *nopTransporter) RemoveAllPeers()                     {}
-func (s *nopTransporter) UpdatePeer(id types.ID, us []string) {}
-func (s *nopTransporter) ActiveSince(id types.ID) time.Time   { return time.Time{} }
-func (s *nopTransporter) ActivePeers() int                    { return 0 }
-func (s *nopTransporter) Stop()                               {}
-func (s *nopTransporter) Pause()                              {}
-func (s *nopTransporter) Resume()                             {}
-
-type snapTransporter struct {
-	nopTransporter
-	snapDoneC chan snap.Message
-	snapDir   string
-}
-
-func NewSnapTransporter(snapDir string) (Transporter, <-chan snap.Message) {
-	ch := make(chan snap.Message, 1)
-	tr := &snapTransporter{snapDoneC: ch, snapDir: snapDir}
-	return tr, ch
-}
-
-func (s *snapTransporter) SendSnapshot(m snap.Message) {
-	ss := snap.New(s.snapDir)
-	ss.SaveDBFrom(m.ReadCloser, m.Snapshot.Metadata.Index+1)
-	m.CloseWithError(nil)
-	s.snapDoneC <- m
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/urlpick.go b/vendor/github.com/coreos/etcd/rafthttp/urlpick.go
deleted file mode 100644
index 61839de..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/urlpick.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"net/url"
-	"sync"
-
-	"github.com/coreos/etcd/pkg/types"
-)
-
-type urlPicker struct {
-	mu     sync.Mutex // guards urls and picked
-	urls   types.URLs
-	picked int
-}
-
-func newURLPicker(urls types.URLs) *urlPicker {
-	return &urlPicker{
-		urls: urls,
-	}
-}
-
-func (p *urlPicker) update(urls types.URLs) {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	p.urls = urls
-	p.picked = 0
-}
-
-func (p *urlPicker) pick() url.URL {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	return p.urls[p.picked]
-}
-
-// unreachable notices the picker that the given url is unreachable,
-// and it should use other possible urls.
-func (p *urlPicker) unreachable(u url.URL) {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	if u == p.urls[p.picked] {
-		p.picked = (p.picked + 1) % len(p.urls)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/rafthttp/util.go b/vendor/github.com/coreos/etcd/rafthttp/util.go
deleted file mode 100644
index 6ec3641..0000000
--- a/vendor/github.com/coreos/etcd/rafthttp/util.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rafthttp
-
-import (
-	"fmt"
-	"io"
-	"net"
-	"net/http"
-	"net/url"
-	"strings"
-	"time"
-
-	"github.com/coreos/etcd/pkg/transport"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/coreos/etcd/version"
-	"github.com/coreos/go-semver/semver"
-)
-
-var (
-	errMemberRemoved  = fmt.Errorf("the member has been permanently removed from the cluster")
-	errMemberNotFound = fmt.Errorf("member not found")
-)
-
-// NewListener returns a listener for raft message transfer between peers.
-// It uses timeout listener to identify broken streams promptly.
-func NewListener(u url.URL, tlsinfo *transport.TLSInfo) (net.Listener, error) {
-	return transport.NewTimeoutListener(u.Host, u.Scheme, tlsinfo, ConnReadTimeout, ConnWriteTimeout)
-}
-
-// NewRoundTripper returns a roundTripper used to send requests
-// to rafthttp listener of remote peers.
-func NewRoundTripper(tlsInfo transport.TLSInfo, dialTimeout time.Duration) (http.RoundTripper, error) {
-	// It uses timeout transport to pair with remote timeout listeners.
-	// It sets no read/write timeout, because message in requests may
-	// take long time to write out before reading out the response.
-	return transport.NewTimeoutTransport(tlsInfo, dialTimeout, 0, 0)
-}
-
-// newStreamRoundTripper returns a roundTripper used to send stream requests
-// to rafthttp listener of remote peers.
-// Read/write timeout is set for stream roundTripper to promptly
-// find out broken status, which minimizes the number of messages
-// sent on broken connection.
-func newStreamRoundTripper(tlsInfo transport.TLSInfo, dialTimeout time.Duration) (http.RoundTripper, error) {
-	return transport.NewTimeoutTransport(tlsInfo, dialTimeout, ConnReadTimeout, ConnWriteTimeout)
-}
-
-// createPostRequest creates a HTTP POST request that sends raft message.
-func createPostRequest(u url.URL, path string, body io.Reader, ct string, urls types.URLs, from, cid types.ID) *http.Request {
-	uu := u
-	uu.Path = path
-	req, err := http.NewRequest("POST", uu.String(), body)
-	if err != nil {
-		plog.Panicf("unexpected new request error (%v)", err)
-	}
-	req.Header.Set("Content-Type", ct)
-	req.Header.Set("X-Server-From", from.String())
-	req.Header.Set("X-Server-Version", version.Version)
-	req.Header.Set("X-Min-Cluster-Version", version.MinClusterVersion)
-	req.Header.Set("X-Etcd-Cluster-ID", cid.String())
-	setPeerURLsHeader(req, urls)
-
-	return req
-}
-
-// checkPostResponse checks the response of the HTTP POST request that sends
-// raft message.
-func checkPostResponse(resp *http.Response, body []byte, req *http.Request, to types.ID) error {
-	switch resp.StatusCode {
-	case http.StatusPreconditionFailed:
-		switch strings.TrimSuffix(string(body), "\n") {
-		case errIncompatibleVersion.Error():
-			plog.Errorf("request sent was ignored by peer %s (server version incompatible)", to)
-			return errIncompatibleVersion
-		case errClusterIDMismatch.Error():
-			plog.Errorf("request sent was ignored (cluster ID mismatch: remote[%s]=%s, local=%s)",
-				to, resp.Header.Get("X-Etcd-Cluster-ID"), req.Header.Get("X-Etcd-Cluster-ID"))
-			return errClusterIDMismatch
-		default:
-			return fmt.Errorf("unhandled error %q when precondition failed", string(body))
-		}
-	case http.StatusForbidden:
-		return errMemberRemoved
-	case http.StatusNoContent:
-		return nil
-	default:
-		return fmt.Errorf("unexpected http status %s while posting to %q", http.StatusText(resp.StatusCode), req.URL.String())
-	}
-}
-
-// reportCriticalError reports the given error through sending it into
-// the given error channel.
-// If the error channel is filled up when sending error, it drops the error
-// because the fact that error has happened is reported, which is
-// good enough.
-func reportCriticalError(err error, errc chan<- error) {
-	select {
-	case errc <- err:
-	default:
-	}
-}
-
-// compareMajorMinorVersion returns an integer comparing two versions based on
-// their major and minor version. The result will be 0 if a==b, -1 if a < b,
-// and 1 if a > b.
-func compareMajorMinorVersion(a, b *semver.Version) int {
-	na := &semver.Version{Major: a.Major, Minor: a.Minor}
-	nb := &semver.Version{Major: b.Major, Minor: b.Minor}
-	switch {
-	case na.LessThan(*nb):
-		return -1
-	case nb.LessThan(*na):
-		return 1
-	default:
-		return 0
-	}
-}
-
-// serverVersion returns the server version from the given header.
-func serverVersion(h http.Header) *semver.Version {
-	verStr := h.Get("X-Server-Version")
-	// backward compatibility with etcd 2.0
-	if verStr == "" {
-		verStr = "2.0.0"
-	}
-	return semver.Must(semver.NewVersion(verStr))
-}
-
-// serverVersion returns the min cluster version from the given header.
-func minClusterVersion(h http.Header) *semver.Version {
-	verStr := h.Get("X-Min-Cluster-Version")
-	// backward compatibility with etcd 2.0
-	if verStr == "" {
-		verStr = "2.0.0"
-	}
-	return semver.Must(semver.NewVersion(verStr))
-}
-
-// checkVersionCompability checks whether the given version is compatible
-// with the local version.
-func checkVersionCompability(name string, server, minCluster *semver.Version) error {
-	localServer := semver.Must(semver.NewVersion(version.Version))
-	localMinCluster := semver.Must(semver.NewVersion(version.MinClusterVersion))
-	if compareMajorMinorVersion(server, localMinCluster) == -1 {
-		return fmt.Errorf("remote version is too low: remote[%s]=%s, local=%s", name, server, localServer)
-	}
-	if compareMajorMinorVersion(minCluster, localServer) == 1 {
-		return fmt.Errorf("local version is too low: remote[%s]=%s, local=%s", name, server, localServer)
-	}
-	return nil
-}
-
-// setPeerURLsHeader reports local urls for peer discovery
-func setPeerURLsHeader(req *http.Request, urls types.URLs) {
-	if urls == nil {
-		// often not set in unit tests
-		return
-	}
-	peerURLs := make([]string, urls.Len())
-	for i := range urls {
-		peerURLs[i] = urls[i].String()
-	}
-	req.Header.Set("X-PeerURLs", strings.Join(peerURLs, ","))
-}
-
-// addRemoteFromRequest adds a remote peer according to an http request header
-func addRemoteFromRequest(tr Transporter, r *http.Request) {
-	if from, err := types.IDFromString(r.Header.Get("X-Server-From")); err == nil {
-		if urls := r.Header.Get("X-PeerURLs"); urls != "" {
-			tr.AddRemote(from, strings.Split(urls, ","))
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/snap/db.go b/vendor/github.com/coreos/etcd/snap/db.go
deleted file mode 100644
index dcbd3bd..0000000
--- a/vendor/github.com/coreos/etcd/snap/db.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package snap
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"time"
-
-	"github.com/coreos/etcd/pkg/fileutil"
-)
-
-var ErrNoDBSnapshot = errors.New("snap: snapshot file doesn't exist")
-
-// SaveDBFrom saves snapshot of the database from the given reader. It
-// guarantees the save operation is atomic.
-func (s *Snapshotter) SaveDBFrom(r io.Reader, id uint64) (int64, error) {
-	start := time.Now()
-
-	f, err := ioutil.TempFile(s.dir, "tmp")
-	if err != nil {
-		return 0, err
-	}
-	var n int64
-	n, err = io.Copy(f, r)
-	if err == nil {
-		fsyncStart := time.Now()
-		err = fileutil.Fsync(f)
-		snapDBFsyncSec.Observe(time.Since(fsyncStart).Seconds())
-	}
-	f.Close()
-	if err != nil {
-		os.Remove(f.Name())
-		return n, err
-	}
-	fn := s.dbFilePath(id)
-	if fileutil.Exist(fn) {
-		os.Remove(f.Name())
-		return n, nil
-	}
-	err = os.Rename(f.Name(), fn)
-	if err != nil {
-		os.Remove(f.Name())
-		return n, err
-	}
-
-	plog.Infof("saved database snapshot to disk [total bytes: %d]", n)
-
-	snapDBSaveSec.Observe(time.Since(start).Seconds())
-	return n, nil
-}
-
-// DBFilePath returns the file path for the snapshot of the database with
-// given id. If the snapshot does not exist, it returns error.
-func (s *Snapshotter) DBFilePath(id uint64) (string, error) {
-	if _, err := fileutil.ReadDir(s.dir); err != nil {
-		return "", err
-	}
-	if fn := s.dbFilePath(id); fileutil.Exist(fn) {
-		return fn, nil
-	}
-	return "", ErrNoDBSnapshot
-}
-
-func (s *Snapshotter) dbFilePath(id uint64) string {
-	return filepath.Join(s.dir, fmt.Sprintf("%016x.snap.db", id))
-}
diff --git a/vendor/github.com/coreos/etcd/snap/message.go b/vendor/github.com/coreos/etcd/snap/message.go
deleted file mode 100644
index d73713f..0000000
--- a/vendor/github.com/coreos/etcd/snap/message.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package snap
-
-import (
-	"io"
-
-	"github.com/coreos/etcd/pkg/ioutil"
-	"github.com/coreos/etcd/raft/raftpb"
-)
-
-// Message is a struct that contains a raft Message and a ReadCloser. The type
-// of raft message MUST be MsgSnap, which contains the raft meta-data and an
-// additional data []byte field that contains the snapshot of the actual state
-// machine.
-// Message contains the ReadCloser field for handling large snapshot. This avoid
-// copying the entire snapshot into a byte array, which consumes a lot of memory.
-//
-// User of Message should close the Message after sending it.
-type Message struct {
-	raftpb.Message
-	ReadCloser io.ReadCloser
-	TotalSize  int64
-	closeC     chan bool
-}
-
-func NewMessage(rs raftpb.Message, rc io.ReadCloser, rcSize int64) *Message {
-	return &Message{
-		Message:    rs,
-		ReadCloser: ioutil.NewExactReadCloser(rc, rcSize),
-		TotalSize:  int64(rs.Size()) + rcSize,
-		closeC:     make(chan bool, 1),
-	}
-}
-
-// CloseNotify returns a channel that receives a single value
-// when the message sent is finished. true indicates the sent
-// is successful.
-func (m Message) CloseNotify() <-chan bool {
-	return m.closeC
-}
-
-func (m Message) CloseWithError(err error) {
-	if cerr := m.ReadCloser.Close(); cerr != nil {
-		err = cerr
-	}
-	if err == nil {
-		m.closeC <- true
-	} else {
-		m.closeC <- false
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/snap/metrics.go b/vendor/github.com/coreos/etcd/snap/metrics.go
deleted file mode 100644
index 0d3b7e6..0000000
--- a/vendor/github.com/coreos/etcd/snap/metrics.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package snap
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	// TODO: save_fsync latency?
-	saveDurations = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "snap",
-		Name:      "save_total_duration_seconds",
-		Help:      "The total latency distributions of save called by snapshot.",
-		Buckets:   prometheus.ExponentialBuckets(0.001, 2, 14),
-	})
-
-	marshallingDurations = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "snap",
-		Name:      "save_marshalling_duration_seconds",
-		Help:      "The marshalling cost distributions of save called by snapshot.",
-		Buckets:   prometheus.ExponentialBuckets(0.001, 2, 14),
-	})
-
-	snapDBSaveSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "snap_db",
-		Name:      "save_total_duration_seconds",
-		Help:      "The total latency distributions of v3 snapshot save",
-
-		// lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2
-		// highest bucket start of 0.1 sec * 2^9 == 51.2 sec
-		Buckets: prometheus.ExponentialBuckets(0.1, 2, 10),
-	})
-
-	snapDBFsyncSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "snap_db",
-		Name:      "fsync_duration_seconds",
-		Help:      "The latency distributions of fsyncing .snap.db file",
-
-		// lowest bucket start of upper bound 0.001 sec (1 ms) with factor 2
-		// highest bucket start of 0.001 sec * 2^13 == 8.192 sec
-		Buckets: prometheus.ExponentialBuckets(0.001, 2, 14),
-	})
-)
-
-func init() {
-	prometheus.MustRegister(saveDurations)
-	prometheus.MustRegister(marshallingDurations)
-	prometheus.MustRegister(snapDBSaveSec)
-	prometheus.MustRegister(snapDBFsyncSec)
-}
diff --git a/vendor/github.com/coreos/etcd/snap/snappb/snap.proto b/vendor/github.com/coreos/etcd/snap/snappb/snap.proto
deleted file mode 100644
index cd3d21d..0000000
--- a/vendor/github.com/coreos/etcd/snap/snappb/snap.proto
+++ /dev/null
@@ -1,14 +0,0 @@
-syntax = "proto2";
-package snappb;
-
-import "gogoproto/gogo.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.sizer_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-option (gogoproto.goproto_getters_all) = false;
-
-message snapshot {
-	optional uint32 crc  = 1 [(gogoproto.nullable) = false];
-	optional bytes data  = 2;
-}
diff --git a/vendor/github.com/coreos/etcd/snap/snapshotter.go b/vendor/github.com/coreos/etcd/snap/snapshotter.go
deleted file mode 100644
index 0075559..0000000
--- a/vendor/github.com/coreos/etcd/snap/snapshotter.go
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package snap stores raft nodes' states with snapshots.
-package snap
-
-import (
-	"errors"
-	"fmt"
-	"hash/crc32"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"sort"
-	"strings"
-	"time"
-
-	pioutil "github.com/coreos/etcd/pkg/ioutil"
-	"github.com/coreos/etcd/pkg/pbutil"
-	"github.com/coreos/etcd/raft"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/snap/snappb"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-const (
-	snapSuffix = ".snap"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "snap")
-
-	ErrNoSnapshot    = errors.New("snap: no available snapshot")
-	ErrEmptySnapshot = errors.New("snap: empty snapshot")
-	ErrCRCMismatch   = errors.New("snap: crc mismatch")
-	crcTable         = crc32.MakeTable(crc32.Castagnoli)
-
-	// A map of valid files that can be present in the snap folder.
-	validFiles = map[string]bool{
-		"db": true,
-	}
-)
-
-type Snapshotter struct {
-	dir string
-}
-
-func New(dir string) *Snapshotter {
-	return &Snapshotter{
-		dir: dir,
-	}
-}
-
-func (s *Snapshotter) SaveSnap(snapshot raftpb.Snapshot) error {
-	if raft.IsEmptySnap(snapshot) {
-		return nil
-	}
-	return s.save(&snapshot)
-}
-
-func (s *Snapshotter) save(snapshot *raftpb.Snapshot) error {
-	start := time.Now()
-
-	fname := fmt.Sprintf("%016x-%016x%s", snapshot.Metadata.Term, snapshot.Metadata.Index, snapSuffix)
-	b := pbutil.MustMarshal(snapshot)
-	crc := crc32.Update(0, crcTable, b)
-	snap := snappb.Snapshot{Crc: crc, Data: b}
-	d, err := snap.Marshal()
-	if err != nil {
-		return err
-	} else {
-		marshallingDurations.Observe(float64(time.Since(start)) / float64(time.Second))
-	}
-
-	err = pioutil.WriteAndSyncFile(filepath.Join(s.dir, fname), d, 0666)
-	if err == nil {
-		saveDurations.Observe(float64(time.Since(start)) / float64(time.Second))
-	} else {
-		err1 := os.Remove(filepath.Join(s.dir, fname))
-		if err1 != nil {
-			plog.Errorf("failed to remove broken snapshot file %s", filepath.Join(s.dir, fname))
-		}
-	}
-	return err
-}
-
-func (s *Snapshotter) Load() (*raftpb.Snapshot, error) {
-	names, err := s.snapNames()
-	if err != nil {
-		return nil, err
-	}
-	var snap *raftpb.Snapshot
-	for _, name := range names {
-		if snap, err = loadSnap(s.dir, name); err == nil {
-			break
-		}
-	}
-	if err != nil {
-		return nil, ErrNoSnapshot
-	}
-	return snap, nil
-}
-
-func loadSnap(dir, name string) (*raftpb.Snapshot, error) {
-	fpath := filepath.Join(dir, name)
-	snap, err := Read(fpath)
-	if err != nil {
-		renameBroken(fpath)
-	}
-	return snap, err
-}
-
-// Read reads the snapshot named by snapname and returns the snapshot.
-func Read(snapname string) (*raftpb.Snapshot, error) {
-	b, err := ioutil.ReadFile(snapname)
-	if err != nil {
-		plog.Errorf("cannot read file %v: %v", snapname, err)
-		return nil, err
-	}
-
-	if len(b) == 0 {
-		plog.Errorf("unexpected empty snapshot")
-		return nil, ErrEmptySnapshot
-	}
-
-	var serializedSnap snappb.Snapshot
-	if err = serializedSnap.Unmarshal(b); err != nil {
-		plog.Errorf("corrupted snapshot file %v: %v", snapname, err)
-		return nil, err
-	}
-
-	if len(serializedSnap.Data) == 0 || serializedSnap.Crc == 0 {
-		plog.Errorf("unexpected empty snapshot")
-		return nil, ErrEmptySnapshot
-	}
-
-	crc := crc32.Update(0, crcTable, serializedSnap.Data)
-	if crc != serializedSnap.Crc {
-		plog.Errorf("corrupted snapshot file %v: crc mismatch", snapname)
-		return nil, ErrCRCMismatch
-	}
-
-	var snap raftpb.Snapshot
-	if err = snap.Unmarshal(serializedSnap.Data); err != nil {
-		plog.Errorf("corrupted snapshot file %v: %v", snapname, err)
-		return nil, err
-	}
-	return &snap, nil
-}
-
-// snapNames returns the filename of the snapshots in logical time order (from newest to oldest).
-// If there is no available snapshots, an ErrNoSnapshot will be returned.
-func (s *Snapshotter) snapNames() ([]string, error) {
-	dir, err := os.Open(s.dir)
-	if err != nil {
-		return nil, err
-	}
-	defer dir.Close()
-	names, err := dir.Readdirnames(-1)
-	if err != nil {
-		return nil, err
-	}
-	snaps := checkSuffix(names)
-	if len(snaps) == 0 {
-		return nil, ErrNoSnapshot
-	}
-	sort.Sort(sort.Reverse(sort.StringSlice(snaps)))
-	return snaps, nil
-}
-
-func checkSuffix(names []string) []string {
-	snaps := []string{}
-	for i := range names {
-		if strings.HasSuffix(names[i], snapSuffix) {
-			snaps = append(snaps, names[i])
-		} else {
-			// If we find a file which is not a snapshot then check if it's
-			// a vaild file. If not throw out a warning.
-			if _, ok := validFiles[names[i]]; !ok {
-				plog.Warningf("skipped unexpected non snapshot file %v", names[i])
-			}
-		}
-	}
-	return snaps
-}
-
-func renameBroken(path string) {
-	brokenPath := path + ".broken"
-	if err := os.Rename(path, brokenPath); err != nil {
-		plog.Warningf("cannot rename broken snapshot file %v to %v: %v", path, brokenPath, err)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/store/doc.go b/vendor/github.com/coreos/etcd/store/doc.go
deleted file mode 100644
index 612df92..0000000
--- a/vendor/github.com/coreos/etcd/store/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package store defines etcd's in-memory key/value store.
-package store
diff --git a/vendor/github.com/coreos/etcd/store/event.go b/vendor/github.com/coreos/etcd/store/event.go
deleted file mode 100644
index efcddb0..0000000
--- a/vendor/github.com/coreos/etcd/store/event.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-const (
-	Get              = "get"
-	Create           = "create"
-	Set              = "set"
-	Update           = "update"
-	Delete           = "delete"
-	CompareAndSwap   = "compareAndSwap"
-	CompareAndDelete = "compareAndDelete"
-	Expire           = "expire"
-)
-
-type Event struct {
-	Action    string      `json:"action"`
-	Node      *NodeExtern `json:"node,omitempty"`
-	PrevNode  *NodeExtern `json:"prevNode,omitempty"`
-	EtcdIndex uint64      `json:"-"`
-	Refresh   bool        `json:"refresh,omitempty"`
-}
-
-func newEvent(action string, key string, modifiedIndex, createdIndex uint64) *Event {
-	n := &NodeExtern{
-		Key:           key,
-		ModifiedIndex: modifiedIndex,
-		CreatedIndex:  createdIndex,
-	}
-
-	return &Event{
-		Action: action,
-		Node:   n,
-	}
-}
-
-func (e *Event) IsCreated() bool {
-	if e.Action == Create {
-		return true
-	}
-	return e.Action == Set && e.PrevNode == nil
-}
-
-func (e *Event) Index() uint64 {
-	return e.Node.ModifiedIndex
-}
-
-func (e *Event) Clone() *Event {
-	return &Event{
-		Action:    e.Action,
-		EtcdIndex: e.EtcdIndex,
-		Node:      e.Node.Clone(),
-		PrevNode:  e.PrevNode.Clone(),
-	}
-}
-
-func (e *Event) SetRefresh() {
-	e.Refresh = true
-}
diff --git a/vendor/github.com/coreos/etcd/store/event_history.go b/vendor/github.com/coreos/etcd/store/event_history.go
deleted file mode 100644
index 235d87a..0000000
--- a/vendor/github.com/coreos/etcd/store/event_history.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-import (
-	"fmt"
-	"path"
-	"strings"
-	"sync"
-
-	etcdErr "github.com/coreos/etcd/error"
-)
-
-type EventHistory struct {
-	Queue      eventQueue
-	StartIndex uint64
-	LastIndex  uint64
-	rwl        sync.RWMutex
-}
-
-func newEventHistory(capacity int) *EventHistory {
-	return &EventHistory{
-		Queue: eventQueue{
-			Capacity: capacity,
-			Events:   make([]*Event, capacity),
-		},
-	}
-}
-
-// addEvent function adds event into the eventHistory
-func (eh *EventHistory) addEvent(e *Event) *Event {
-	eh.rwl.Lock()
-	defer eh.rwl.Unlock()
-
-	eh.Queue.insert(e)
-
-	eh.LastIndex = e.Index()
-
-	eh.StartIndex = eh.Queue.Events[eh.Queue.Front].Index()
-
-	return e
-}
-
-// scan enumerates events from the index history and stops at the first point
-// where the key matches.
-func (eh *EventHistory) scan(key string, recursive bool, index uint64) (*Event, *etcdErr.Error) {
-	eh.rwl.RLock()
-	defer eh.rwl.RUnlock()
-
-	// index should be after the event history's StartIndex
-	if index < eh.StartIndex {
-		return nil,
-			etcdErr.NewError(etcdErr.EcodeEventIndexCleared,
-				fmt.Sprintf("the requested history has been cleared [%v/%v]",
-					eh.StartIndex, index), 0)
-	}
-
-	// the index should come before the size of the queue minus the duplicate count
-	if index > eh.LastIndex { // future index
-		return nil, nil
-	}
-
-	offset := index - eh.StartIndex
-	i := (eh.Queue.Front + int(offset)) % eh.Queue.Capacity
-
-	for {
-		e := eh.Queue.Events[i]
-
-		if !e.Refresh {
-			ok := (e.Node.Key == key)
-
-			if recursive {
-				// add tailing slash
-				nkey := path.Clean(key)
-				if nkey[len(nkey)-1] != '/' {
-					nkey = nkey + "/"
-				}
-
-				ok = ok || strings.HasPrefix(e.Node.Key, nkey)
-			}
-
-			if (e.Action == Delete || e.Action == Expire) && e.PrevNode != nil && e.PrevNode.Dir {
-				ok = ok || strings.HasPrefix(key, e.PrevNode.Key)
-			}
-
-			if ok {
-				return e, nil
-			}
-		}
-
-		i = (i + 1) % eh.Queue.Capacity
-
-		if i == eh.Queue.Back {
-			return nil, nil
-		}
-	}
-}
-
-// clone will be protected by a stop-world lock
-// do not need to obtain internal lock
-func (eh *EventHistory) clone() *EventHistory {
-	clonedQueue := eventQueue{
-		Capacity: eh.Queue.Capacity,
-		Events:   make([]*Event, eh.Queue.Capacity),
-		Size:     eh.Queue.Size,
-		Front:    eh.Queue.Front,
-		Back:     eh.Queue.Back,
-	}
-
-	copy(clonedQueue.Events, eh.Queue.Events)
-	return &EventHistory{
-		StartIndex: eh.StartIndex,
-		Queue:      clonedQueue,
-		LastIndex:  eh.LastIndex,
-	}
-
-}
diff --git a/vendor/github.com/coreos/etcd/store/event_queue.go b/vendor/github.com/coreos/etcd/store/event_queue.go
deleted file mode 100644
index 767b835..0000000
--- a/vendor/github.com/coreos/etcd/store/event_queue.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-type eventQueue struct {
-	Events   []*Event
-	Size     int
-	Front    int
-	Back     int
-	Capacity int
-}
-
-func (eq *eventQueue) insert(e *Event) {
-	eq.Events[eq.Back] = e
-	eq.Back = (eq.Back + 1) % eq.Capacity
-
-	if eq.Size == eq.Capacity { //dequeue
-		eq.Front = (eq.Front + 1) % eq.Capacity
-	} else {
-		eq.Size++
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/store/metrics.go b/vendor/github.com/coreos/etcd/store/metrics.go
deleted file mode 100644
index 077c0fa..0000000
--- a/vendor/github.com/coreos/etcd/store/metrics.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-import (
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-// Set of raw Prometheus metrics.
-// Labels
-// * action = declared in event.go
-// * outcome = Outcome
-// Do not increment directly, use Report* methods.
-var (
-	readCounter = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "reads_total",
-			Help:      "Total number of reads action by (get/getRecursive), local to this member.",
-		}, []string{"action"})
-
-	writeCounter = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "writes_total",
-			Help:      "Total number of writes (e.g. set/compareAndDelete) seen by this member.",
-		}, []string{"action"})
-
-	readFailedCounter = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "reads_failed_total",
-			Help:      "Failed read actions by (get/getRecursive), local to this member.",
-		}, []string{"action"})
-
-	writeFailedCounter = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "writes_failed_total",
-			Help:      "Failed write actions (e.g. set/compareAndDelete), seen by this member.",
-		}, []string{"action"})
-
-	expireCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "expires_total",
-			Help:      "Total number of expired keys.",
-		})
-
-	watchRequests = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "watch_requests_total",
-			Help:      "Total number of incoming watch requests (new or reestablished).",
-		})
-
-	watcherCount = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "watchers",
-			Help:      "Count of currently active watchers.",
-		})
-)
-
-const (
-	GetRecursive = "getRecursive"
-)
-
-func init() {
-	if prometheus.Register(readCounter) != nil {
-		// Tests will try to double register since the tests use both
-		// store and store_test packages; ignore second attempts.
-		return
-	}
-	prometheus.MustRegister(writeCounter)
-	prometheus.MustRegister(expireCounter)
-	prometheus.MustRegister(watchRequests)
-	prometheus.MustRegister(watcherCount)
-}
-
-func reportReadSuccess(read_action string) {
-	readCounter.WithLabelValues(read_action).Inc()
-}
-
-func reportReadFailure(read_action string) {
-	readCounter.WithLabelValues(read_action).Inc()
-	readFailedCounter.WithLabelValues(read_action).Inc()
-}
-
-func reportWriteSuccess(write_action string) {
-	writeCounter.WithLabelValues(write_action).Inc()
-}
-
-func reportWriteFailure(write_action string) {
-	writeCounter.WithLabelValues(write_action).Inc()
-	writeFailedCounter.WithLabelValues(write_action).Inc()
-}
-
-func reportExpiredKey() {
-	expireCounter.Inc()
-}
-
-func reportWatchRequest() {
-	watchRequests.Inc()
-}
-
-func reportWatcherAdded() {
-	watcherCount.Inc()
-}
-
-func reportWatcherRemoved() {
-	watcherCount.Dec()
-}
diff --git a/vendor/github.com/coreos/etcd/store/node.go b/vendor/github.com/coreos/etcd/store/node.go
deleted file mode 100644
index c3c8743..0000000
--- a/vendor/github.com/coreos/etcd/store/node.go
+++ /dev/null
@@ -1,395 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-import (
-	"path"
-	"sort"
-	"time"
-
-	etcdErr "github.com/coreos/etcd/error"
-	"github.com/jonboulle/clockwork"
-)
-
-// explanations of Compare function result
-const (
-	CompareMatch = iota
-	CompareIndexNotMatch
-	CompareValueNotMatch
-	CompareNotMatch
-)
-
-var Permanent time.Time
-
-// node is the basic element in the store system.
-// A key-value pair will have a string value
-// A directory will have a children map
-type node struct {
-	Path string
-
-	CreatedIndex  uint64
-	ModifiedIndex uint64
-
-	Parent *node `json:"-"` // should not encode this field! avoid circular dependency.
-
-	ExpireTime time.Time
-	Value      string           // for key-value pair
-	Children   map[string]*node // for directory
-
-	// A reference to the store this node is attached to.
-	store *store
-}
-
-// newKV creates a Key-Value pair
-func newKV(store *store, nodePath string, value string, createdIndex uint64, parent *node, expireTime time.Time) *node {
-	return &node{
-		Path:          nodePath,
-		CreatedIndex:  createdIndex,
-		ModifiedIndex: createdIndex,
-		Parent:        parent,
-		store:         store,
-		ExpireTime:    expireTime,
-		Value:         value,
-	}
-}
-
-// newDir creates a directory
-func newDir(store *store, nodePath string, createdIndex uint64, parent *node, expireTime time.Time) *node {
-	return &node{
-		Path:          nodePath,
-		CreatedIndex:  createdIndex,
-		ModifiedIndex: createdIndex,
-		Parent:        parent,
-		ExpireTime:    expireTime,
-		Children:      make(map[string]*node),
-		store:         store,
-	}
-}
-
-// IsHidden function checks if the node is a hidden node. A hidden node
-// will begin with '_'
-// A hidden node will not be shown via get command under a directory
-// For example if we have /foo/_hidden and /foo/notHidden, get "/foo"
-// will only return /foo/notHidden
-func (n *node) IsHidden() bool {
-	_, name := path.Split(n.Path)
-
-	return name[0] == '_'
-}
-
-// IsPermanent function checks if the node is a permanent one.
-func (n *node) IsPermanent() bool {
-	// we use a uninitialized time.Time to indicate the node is a
-	// permanent one.
-	// the uninitialized time.Time should equal zero.
-	return n.ExpireTime.IsZero()
-}
-
-// IsDir function checks whether the node is a directory.
-// If the node is a directory, the function will return true.
-// Otherwise the function will return false.
-func (n *node) IsDir() bool {
-	return n.Children != nil
-}
-
-// Read function gets the value of the node.
-// If the receiver node is not a key-value pair, a "Not A File" error will be returned.
-func (n *node) Read() (string, *etcdErr.Error) {
-	if n.IsDir() {
-		return "", etcdErr.NewError(etcdErr.EcodeNotFile, "", n.store.CurrentIndex)
-	}
-
-	return n.Value, nil
-}
-
-// Write function set the value of the node to the given value.
-// If the receiver node is a directory, a "Not A File" error will be returned.
-func (n *node) Write(value string, index uint64) *etcdErr.Error {
-	if n.IsDir() {
-		return etcdErr.NewError(etcdErr.EcodeNotFile, "", n.store.CurrentIndex)
-	}
-
-	n.Value = value
-	n.ModifiedIndex = index
-
-	return nil
-}
-
-func (n *node) expirationAndTTL(clock clockwork.Clock) (*time.Time, int64) {
-	if !n.IsPermanent() {
-		/* compute ttl as:
-		   ceiling( (expireTime - timeNow) / nanosecondsPerSecond )
-		   which ranges from 1..n
-		   rather than as:
-		   ( (expireTime - timeNow) / nanosecondsPerSecond ) + 1
-		   which ranges 1..n+1
-		*/
-		ttlN := n.ExpireTime.Sub(clock.Now())
-		ttl := ttlN / time.Second
-		if (ttlN % time.Second) > 0 {
-			ttl++
-		}
-		t := n.ExpireTime.UTC()
-		return &t, int64(ttl)
-	}
-	return nil, 0
-}
-
-// List function return a slice of nodes under the receiver node.
-// If the receiver node is not a directory, a "Not A Directory" error will be returned.
-func (n *node) List() ([]*node, *etcdErr.Error) {
-	if !n.IsDir() {
-		return nil, etcdErr.NewError(etcdErr.EcodeNotDir, "", n.store.CurrentIndex)
-	}
-
-	nodes := make([]*node, len(n.Children))
-
-	i := 0
-	for _, node := range n.Children {
-		nodes[i] = node
-		i++
-	}
-
-	return nodes, nil
-}
-
-// GetChild function returns the child node under the directory node.
-// On success, it returns the file node
-func (n *node) GetChild(name string) (*node, *etcdErr.Error) {
-	if !n.IsDir() {
-		return nil, etcdErr.NewError(etcdErr.EcodeNotDir, n.Path, n.store.CurrentIndex)
-	}
-
-	child, ok := n.Children[name]
-
-	if ok {
-		return child, nil
-	}
-
-	return nil, nil
-}
-
-// Add function adds a node to the receiver node.
-// If the receiver is not a directory, a "Not A Directory" error will be returned.
-// If there is an existing node with the same name under the directory, a "Already Exist"
-// error will be returned
-func (n *node) Add(child *node) *etcdErr.Error {
-	if !n.IsDir() {
-		return etcdErr.NewError(etcdErr.EcodeNotDir, "", n.store.CurrentIndex)
-	}
-
-	_, name := path.Split(child.Path)
-
-	if _, ok := n.Children[name]; ok {
-		return etcdErr.NewError(etcdErr.EcodeNodeExist, "", n.store.CurrentIndex)
-	}
-
-	n.Children[name] = child
-
-	return nil
-}
-
-// Remove function remove the node.
-func (n *node) Remove(dir, recursive bool, callback func(path string)) *etcdErr.Error {
-	if !n.IsDir() { // key-value pair
-		_, name := path.Split(n.Path)
-
-		// find its parent and remove the node from the map
-		if n.Parent != nil && n.Parent.Children[name] == n {
-			delete(n.Parent.Children, name)
-		}
-
-		if callback != nil {
-			callback(n.Path)
-		}
-
-		if !n.IsPermanent() {
-			n.store.ttlKeyHeap.remove(n)
-		}
-
-		return nil
-	}
-
-	if !dir {
-		// cannot delete a directory without dir set to true
-		return etcdErr.NewError(etcdErr.EcodeNotFile, n.Path, n.store.CurrentIndex)
-	}
-
-	if len(n.Children) != 0 && !recursive {
-		// cannot delete a directory if it is not empty and the operation
-		// is not recursive
-		return etcdErr.NewError(etcdErr.EcodeDirNotEmpty, n.Path, n.store.CurrentIndex)
-	}
-
-	for _, child := range n.Children { // delete all children
-		child.Remove(true, true, callback)
-	}
-
-	// delete self
-	_, name := path.Split(n.Path)
-	if n.Parent != nil && n.Parent.Children[name] == n {
-		delete(n.Parent.Children, name)
-
-		if callback != nil {
-			callback(n.Path)
-		}
-
-		if !n.IsPermanent() {
-			n.store.ttlKeyHeap.remove(n)
-		}
-	}
-
-	return nil
-}
-
-func (n *node) Repr(recursive, sorted bool, clock clockwork.Clock) *NodeExtern {
-	if n.IsDir() {
-		node := &NodeExtern{
-			Key:           n.Path,
-			Dir:           true,
-			ModifiedIndex: n.ModifiedIndex,
-			CreatedIndex:  n.CreatedIndex,
-		}
-		node.Expiration, node.TTL = n.expirationAndTTL(clock)
-
-		if !recursive {
-			return node
-		}
-
-		children, _ := n.List()
-		node.Nodes = make(NodeExterns, len(children))
-
-		// we do not use the index in the children slice directly
-		// we need to skip the hidden one
-		i := 0
-
-		for _, child := range children {
-
-			if child.IsHidden() { // get will not list hidden node
-				continue
-			}
-
-			node.Nodes[i] = child.Repr(recursive, sorted, clock)
-
-			i++
-		}
-
-		// eliminate hidden nodes
-		node.Nodes = node.Nodes[:i]
-		if sorted {
-			sort.Sort(node.Nodes)
-		}
-
-		return node
-	}
-
-	// since n.Value could be changed later, so we need to copy the value out
-	value := n.Value
-	node := &NodeExtern{
-		Key:           n.Path,
-		Value:         &value,
-		ModifiedIndex: n.ModifiedIndex,
-		CreatedIndex:  n.CreatedIndex,
-	}
-	node.Expiration, node.TTL = n.expirationAndTTL(clock)
-	return node
-}
-
-func (n *node) UpdateTTL(expireTime time.Time) {
-	if !n.IsPermanent() {
-		if expireTime.IsZero() {
-			// from ttl to permanent
-			n.ExpireTime = expireTime
-			// remove from ttl heap
-			n.store.ttlKeyHeap.remove(n)
-			return
-		}
-
-		// update ttl
-		n.ExpireTime = expireTime
-		// update ttl heap
-		n.store.ttlKeyHeap.update(n)
-		return
-	}
-
-	if expireTime.IsZero() {
-		return
-	}
-
-	// from permanent to ttl
-	n.ExpireTime = expireTime
-	// push into ttl heap
-	n.store.ttlKeyHeap.push(n)
-}
-
-// Compare function compares node index and value with provided ones.
-// second result value explains result and equals to one of Compare.. constants
-func (n *node) Compare(prevValue string, prevIndex uint64) (ok bool, which int) {
-	indexMatch := (prevIndex == 0 || n.ModifiedIndex == prevIndex)
-	valueMatch := (prevValue == "" || n.Value == prevValue)
-	ok = valueMatch && indexMatch
-	switch {
-	case valueMatch && indexMatch:
-		which = CompareMatch
-	case indexMatch && !valueMatch:
-		which = CompareValueNotMatch
-	case valueMatch && !indexMatch:
-		which = CompareIndexNotMatch
-	default:
-		which = CompareNotMatch
-	}
-	return ok, which
-}
-
-// Clone function clone the node recursively and return the new node.
-// If the node is a directory, it will clone all the content under this directory.
-// If the node is a key-value pair, it will clone the pair.
-func (n *node) Clone() *node {
-	if !n.IsDir() {
-		newkv := newKV(n.store, n.Path, n.Value, n.CreatedIndex, n.Parent, n.ExpireTime)
-		newkv.ModifiedIndex = n.ModifiedIndex
-		return newkv
-	}
-
-	clone := newDir(n.store, n.Path, n.CreatedIndex, n.Parent, n.ExpireTime)
-	clone.ModifiedIndex = n.ModifiedIndex
-
-	for key, child := range n.Children {
-		clone.Children[key] = child.Clone()
-	}
-
-	return clone
-}
-
-// recoverAndclean function help to do recovery.
-// Two things need to be done: 1. recovery structure; 2. delete expired nodes
-//
-// If the node is a directory, it will help recover children's parent pointer and recursively
-// call this function on its children.
-// We check the expire last since we need to recover the whole structure first and add all the
-// notifications into the event history.
-func (n *node) recoverAndclean() {
-	if n.IsDir() {
-		for _, child := range n.Children {
-			child.Parent = n
-			child.store = n.store
-			child.recoverAndclean()
-		}
-	}
-
-	if !n.ExpireTime.IsZero() {
-		n.store.ttlKeyHeap.push(n)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/store/node_extern.go b/vendor/github.com/coreos/etcd/store/node_extern.go
deleted file mode 100644
index 7ba870c..0000000
--- a/vendor/github.com/coreos/etcd/store/node_extern.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-import (
-	"sort"
-	"time"
-
-	"github.com/jonboulle/clockwork"
-)
-
-// NodeExtern is the external representation of the
-// internal node with additional fields
-// PrevValue is the previous value of the node
-// TTL is time to live in second
-type NodeExtern struct {
-	Key           string      `json:"key,omitempty"`
-	Value         *string     `json:"value,omitempty"`
-	Dir           bool        `json:"dir,omitempty"`
-	Expiration    *time.Time  `json:"expiration,omitempty"`
-	TTL           int64       `json:"ttl,omitempty"`
-	Nodes         NodeExterns `json:"nodes,omitempty"`
-	ModifiedIndex uint64      `json:"modifiedIndex,omitempty"`
-	CreatedIndex  uint64      `json:"createdIndex,omitempty"`
-}
-
-func (eNode *NodeExtern) loadInternalNode(n *node, recursive, sorted bool, clock clockwork.Clock) {
-	if n.IsDir() { // node is a directory
-		eNode.Dir = true
-
-		children, _ := n.List()
-		eNode.Nodes = make(NodeExterns, len(children))
-
-		// we do not use the index in the children slice directly
-		// we need to skip the hidden one
-		i := 0
-
-		for _, child := range children {
-			if child.IsHidden() { // get will not return hidden nodes
-				continue
-			}
-
-			eNode.Nodes[i] = child.Repr(recursive, sorted, clock)
-			i++
-		}
-
-		// eliminate hidden nodes
-		eNode.Nodes = eNode.Nodes[:i]
-
-		if sorted {
-			sort.Sort(eNode.Nodes)
-		}
-
-	} else { // node is a file
-		value, _ := n.Read()
-		eNode.Value = &value
-	}
-
-	eNode.Expiration, eNode.TTL = n.expirationAndTTL(clock)
-}
-
-func (eNode *NodeExtern) Clone() *NodeExtern {
-	if eNode == nil {
-		return nil
-	}
-	nn := &NodeExtern{
-		Key:           eNode.Key,
-		Dir:           eNode.Dir,
-		TTL:           eNode.TTL,
-		ModifiedIndex: eNode.ModifiedIndex,
-		CreatedIndex:  eNode.CreatedIndex,
-	}
-	if eNode.Value != nil {
-		s := *eNode.Value
-		nn.Value = &s
-	}
-	if eNode.Expiration != nil {
-		t := *eNode.Expiration
-		nn.Expiration = &t
-	}
-	if eNode.Nodes != nil {
-		nn.Nodes = make(NodeExterns, len(eNode.Nodes))
-		for i, n := range eNode.Nodes {
-			nn.Nodes[i] = n.Clone()
-		}
-	}
-	return nn
-}
-
-type NodeExterns []*NodeExtern
-
-// interfaces for sorting
-
-func (ns NodeExterns) Len() int {
-	return len(ns)
-}
-
-func (ns NodeExterns) Less(i, j int) bool {
-	return ns[i].Key < ns[j].Key
-}
-
-func (ns NodeExterns) Swap(i, j int) {
-	ns[i], ns[j] = ns[j], ns[i]
-}
diff --git a/vendor/github.com/coreos/etcd/store/stats.go b/vendor/github.com/coreos/etcd/store/stats.go
deleted file mode 100644
index ce464dd..0000000
--- a/vendor/github.com/coreos/etcd/store/stats.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-import (
-	"encoding/json"
-	"sync/atomic"
-)
-
-const (
-	SetSuccess = iota
-	SetFail
-	DeleteSuccess
-	DeleteFail
-	CreateSuccess
-	CreateFail
-	UpdateSuccess
-	UpdateFail
-	CompareAndSwapSuccess
-	CompareAndSwapFail
-	GetSuccess
-	GetFail
-	ExpireCount
-	CompareAndDeleteSuccess
-	CompareAndDeleteFail
-)
-
-type Stats struct {
-	// Number of get requests
-
-	GetSuccess uint64 `json:"getsSuccess"`
-	GetFail    uint64 `json:"getsFail"`
-
-	// Number of sets requests
-
-	SetSuccess uint64 `json:"setsSuccess"`
-	SetFail    uint64 `json:"setsFail"`
-
-	// Number of delete requests
-
-	DeleteSuccess uint64 `json:"deleteSuccess"`
-	DeleteFail    uint64 `json:"deleteFail"`
-
-	// Number of update requests
-
-	UpdateSuccess uint64 `json:"updateSuccess"`
-	UpdateFail    uint64 `json:"updateFail"`
-
-	// Number of create requests
-
-	CreateSuccess uint64 `json:"createSuccess"`
-	CreateFail    uint64 `json:"createFail"`
-
-	// Number of testAndSet requests
-
-	CompareAndSwapSuccess uint64 `json:"compareAndSwapSuccess"`
-	CompareAndSwapFail    uint64 `json:"compareAndSwapFail"`
-
-	// Number of compareAndDelete requests
-
-	CompareAndDeleteSuccess uint64 `json:"compareAndDeleteSuccess"`
-	CompareAndDeleteFail    uint64 `json:"compareAndDeleteFail"`
-
-	ExpireCount uint64 `json:"expireCount"`
-
-	Watchers uint64 `json:"watchers"`
-}
-
-func newStats() *Stats {
-	s := new(Stats)
-	return s
-}
-
-func (s *Stats) clone() *Stats {
-	return &Stats{
-		GetSuccess:              s.GetSuccess,
-		GetFail:                 s.GetFail,
-		SetSuccess:              s.SetSuccess,
-		SetFail:                 s.SetFail,
-		DeleteSuccess:           s.DeleteSuccess,
-		DeleteFail:              s.DeleteFail,
-		UpdateSuccess:           s.UpdateSuccess,
-		UpdateFail:              s.UpdateFail,
-		CreateSuccess:           s.CreateSuccess,
-		CreateFail:              s.CreateFail,
-		CompareAndSwapSuccess:   s.CompareAndSwapSuccess,
-		CompareAndSwapFail:      s.CompareAndSwapFail,
-		CompareAndDeleteSuccess: s.CompareAndDeleteSuccess,
-		CompareAndDeleteFail:    s.CompareAndDeleteFail,
-		ExpireCount:             s.ExpireCount,
-		Watchers:                s.Watchers,
-	}
-}
-
-func (s *Stats) toJson() []byte {
-	b, _ := json.Marshal(s)
-	return b
-}
-
-func (s *Stats) Inc(field int) {
-	switch field {
-	case SetSuccess:
-		atomic.AddUint64(&s.SetSuccess, 1)
-	case SetFail:
-		atomic.AddUint64(&s.SetFail, 1)
-	case CreateSuccess:
-		atomic.AddUint64(&s.CreateSuccess, 1)
-	case CreateFail:
-		atomic.AddUint64(&s.CreateFail, 1)
-	case DeleteSuccess:
-		atomic.AddUint64(&s.DeleteSuccess, 1)
-	case DeleteFail:
-		atomic.AddUint64(&s.DeleteFail, 1)
-	case GetSuccess:
-		atomic.AddUint64(&s.GetSuccess, 1)
-	case GetFail:
-		atomic.AddUint64(&s.GetFail, 1)
-	case UpdateSuccess:
-		atomic.AddUint64(&s.UpdateSuccess, 1)
-	case UpdateFail:
-		atomic.AddUint64(&s.UpdateFail, 1)
-	case CompareAndSwapSuccess:
-		atomic.AddUint64(&s.CompareAndSwapSuccess, 1)
-	case CompareAndSwapFail:
-		atomic.AddUint64(&s.CompareAndSwapFail, 1)
-	case CompareAndDeleteSuccess:
-		atomic.AddUint64(&s.CompareAndDeleteSuccess, 1)
-	case CompareAndDeleteFail:
-		atomic.AddUint64(&s.CompareAndDeleteFail, 1)
-	case ExpireCount:
-		atomic.AddUint64(&s.ExpireCount, 1)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/store/store.go b/vendor/github.com/coreos/etcd/store/store.go
deleted file mode 100644
index edf7f21..0000000
--- a/vendor/github.com/coreos/etcd/store/store.go
+++ /dev/null
@@ -1,791 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-import (
-	"encoding/json"
-	"fmt"
-	"path"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-
-	etcdErr "github.com/coreos/etcd/error"
-	"github.com/coreos/etcd/pkg/types"
-	"github.com/jonboulle/clockwork"
-)
-
-// The default version to set when the store is first initialized.
-const defaultVersion = 2
-
-var minExpireTime time.Time
-
-func init() {
-	minExpireTime, _ = time.Parse(time.RFC3339, "2000-01-01T00:00:00Z")
-}
-
-type Store interface {
-	Version() int
-	Index() uint64
-
-	Get(nodePath string, recursive, sorted bool) (*Event, error)
-	Set(nodePath string, dir bool, value string, expireOpts TTLOptionSet) (*Event, error)
-	Update(nodePath string, newValue string, expireOpts TTLOptionSet) (*Event, error)
-	Create(nodePath string, dir bool, value string, unique bool,
-		expireOpts TTLOptionSet) (*Event, error)
-	CompareAndSwap(nodePath string, prevValue string, prevIndex uint64,
-		value string, expireOpts TTLOptionSet) (*Event, error)
-	Delete(nodePath string, dir, recursive bool) (*Event, error)
-	CompareAndDelete(nodePath string, prevValue string, prevIndex uint64) (*Event, error)
-
-	Watch(prefix string, recursive, stream bool, sinceIndex uint64) (Watcher, error)
-
-	Save() ([]byte, error)
-	Recovery(state []byte) error
-
-	Clone() Store
-	SaveNoCopy() ([]byte, error)
-
-	JsonStats() []byte
-	DeleteExpiredKeys(cutoff time.Time)
-
-	HasTTLKeys() bool
-}
-
-type TTLOptionSet struct {
-	ExpireTime time.Time
-	Refresh    bool
-}
-
-type store struct {
-	Root           *node
-	WatcherHub     *watcherHub
-	CurrentIndex   uint64
-	Stats          *Stats
-	CurrentVersion int
-	ttlKeyHeap     *ttlKeyHeap  // need to recovery manually
-	worldLock      sync.RWMutex // stop the world lock
-	clock          clockwork.Clock
-	readonlySet    types.Set
-}
-
-// New creates a store where the given namespaces will be created as initial directories.
-func New(namespaces ...string) Store {
-	s := newStore(namespaces...)
-	s.clock = clockwork.NewRealClock()
-	return s
-}
-
-func newStore(namespaces ...string) *store {
-	s := new(store)
-	s.CurrentVersion = defaultVersion
-	s.Root = newDir(s, "/", s.CurrentIndex, nil, Permanent)
-	for _, namespace := range namespaces {
-		s.Root.Add(newDir(s, namespace, s.CurrentIndex, s.Root, Permanent))
-	}
-	s.Stats = newStats()
-	s.WatcherHub = newWatchHub(1000)
-	s.ttlKeyHeap = newTtlKeyHeap()
-	s.readonlySet = types.NewUnsafeSet(append(namespaces, "/")...)
-	return s
-}
-
-// Version retrieves current version of the store.
-func (s *store) Version() int {
-	return s.CurrentVersion
-}
-
-// Index retrieves the current index of the store.
-func (s *store) Index() uint64 {
-	s.worldLock.RLock()
-	defer s.worldLock.RUnlock()
-	return s.CurrentIndex
-}
-
-// Get returns a get event.
-// If recursive is true, it will return all the content under the node path.
-// If sorted is true, it will sort the content by keys.
-func (s *store) Get(nodePath string, recursive, sorted bool) (*Event, error) {
-	var err *etcdErr.Error
-
-	s.worldLock.RLock()
-	defer s.worldLock.RUnlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(GetSuccess)
-			if recursive {
-				reportReadSuccess(GetRecursive)
-			} else {
-				reportReadSuccess(Get)
-			}
-			return
-		}
-
-		s.Stats.Inc(GetFail)
-		if recursive {
-			reportReadFailure(GetRecursive)
-		} else {
-			reportReadFailure(Get)
-		}
-	}()
-
-	n, err := s.internalGet(nodePath)
-	if err != nil {
-		return nil, err
-	}
-
-	e := newEvent(Get, nodePath, n.ModifiedIndex, n.CreatedIndex)
-	e.EtcdIndex = s.CurrentIndex
-	e.Node.loadInternalNode(n, recursive, sorted, s.clock)
-
-	return e, nil
-}
-
-// Create creates the node at nodePath. Create will help to create intermediate directories with no ttl.
-// If the node has already existed, create will fail.
-// If any node on the path is a file, create will fail.
-func (s *store) Create(nodePath string, dir bool, value string, unique bool, expireOpts TTLOptionSet) (*Event, error) {
-	var err *etcdErr.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(CreateSuccess)
-			reportWriteSuccess(Create)
-			return
-		}
-
-		s.Stats.Inc(CreateFail)
-		reportWriteFailure(Create)
-	}()
-
-	e, err := s.internalCreate(nodePath, dir, value, unique, false, expireOpts.ExpireTime, Create)
-	if err != nil {
-		return nil, err
-	}
-
-	e.EtcdIndex = s.CurrentIndex
-	s.WatcherHub.notify(e)
-
-	return e, nil
-}
-
-// Set creates or replace the node at nodePath.
-func (s *store) Set(nodePath string, dir bool, value string, expireOpts TTLOptionSet) (*Event, error) {
-	var err *etcdErr.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(SetSuccess)
-			reportWriteSuccess(Set)
-			return
-		}
-
-		s.Stats.Inc(SetFail)
-		reportWriteFailure(Set)
-	}()
-
-	// Get prevNode value
-	n, getErr := s.internalGet(nodePath)
-	if getErr != nil && getErr.ErrorCode != etcdErr.EcodeKeyNotFound {
-		err = getErr
-		return nil, err
-	}
-
-	if expireOpts.Refresh {
-		if getErr != nil {
-			err = getErr
-			return nil, err
-		} else {
-			value = n.Value
-		}
-	}
-
-	// Set new value
-	e, err := s.internalCreate(nodePath, dir, value, false, true, expireOpts.ExpireTime, Set)
-	if err != nil {
-		return nil, err
-	}
-	e.EtcdIndex = s.CurrentIndex
-
-	// Put prevNode into event
-	if getErr == nil {
-		prev := newEvent(Get, nodePath, n.ModifiedIndex, n.CreatedIndex)
-		prev.Node.loadInternalNode(n, false, false, s.clock)
-		e.PrevNode = prev.Node
-	}
-
-	if !expireOpts.Refresh {
-		s.WatcherHub.notify(e)
-	} else {
-		e.SetRefresh()
-		s.WatcherHub.add(e)
-	}
-
-	return e, nil
-}
-
-// returns user-readable cause of failed comparison
-func getCompareFailCause(n *node, which int, prevValue string, prevIndex uint64) string {
-	switch which {
-	case CompareIndexNotMatch:
-		return fmt.Sprintf("[%v != %v]", prevIndex, n.ModifiedIndex)
-	case CompareValueNotMatch:
-		return fmt.Sprintf("[%v != %v]", prevValue, n.Value)
-	default:
-		return fmt.Sprintf("[%v != %v] [%v != %v]", prevValue, n.Value, prevIndex, n.ModifiedIndex)
-	}
-}
-
-func (s *store) CompareAndSwap(nodePath string, prevValue string, prevIndex uint64,
-	value string, expireOpts TTLOptionSet) (*Event, error) {
-
-	var err *etcdErr.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(CompareAndSwapSuccess)
-			reportWriteSuccess(CompareAndSwap)
-			return
-		}
-
-		s.Stats.Inc(CompareAndSwapFail)
-		reportWriteFailure(CompareAndSwap)
-	}()
-
-	nodePath = path.Clean(path.Join("/", nodePath))
-	// we do not allow the user to change "/"
-	if s.readonlySet.Contains(nodePath) {
-		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", s.CurrentIndex)
-	}
-
-	n, err := s.internalGet(nodePath)
-	if err != nil {
-		return nil, err
-	}
-	if n.IsDir() { // can only compare and swap file
-		err = etcdErr.NewError(etcdErr.EcodeNotFile, nodePath, s.CurrentIndex)
-		return nil, err
-	}
-
-	// If both of the prevValue and prevIndex are given, we will test both of them.
-	// Command will be executed, only if both of the tests are successful.
-	if ok, which := n.Compare(prevValue, prevIndex); !ok {
-		cause := getCompareFailCause(n, which, prevValue, prevIndex)
-		err = etcdErr.NewError(etcdErr.EcodeTestFailed, cause, s.CurrentIndex)
-		return nil, err
-	}
-
-	if expireOpts.Refresh {
-		value = n.Value
-	}
-
-	// update etcd index
-	s.CurrentIndex++
-
-	e := newEvent(CompareAndSwap, nodePath, s.CurrentIndex, n.CreatedIndex)
-	e.EtcdIndex = s.CurrentIndex
-	e.PrevNode = n.Repr(false, false, s.clock)
-	eNode := e.Node
-
-	// if test succeed, write the value
-	n.Write(value, s.CurrentIndex)
-	n.UpdateTTL(expireOpts.ExpireTime)
-
-	// copy the value for safety
-	valueCopy := value
-	eNode.Value = &valueCopy
-	eNode.Expiration, eNode.TTL = n.expirationAndTTL(s.clock)
-
-	if !expireOpts.Refresh {
-		s.WatcherHub.notify(e)
-	} else {
-		e.SetRefresh()
-		s.WatcherHub.add(e)
-	}
-
-	return e, nil
-}
-
-// Delete deletes the node at the given path.
-// If the node is a directory, recursive must be true to delete it.
-func (s *store) Delete(nodePath string, dir, recursive bool) (*Event, error) {
-	var err *etcdErr.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(DeleteSuccess)
-			reportWriteSuccess(Delete)
-			return
-		}
-
-		s.Stats.Inc(DeleteFail)
-		reportWriteFailure(Delete)
-	}()
-
-	nodePath = path.Clean(path.Join("/", nodePath))
-	// we do not allow the user to change "/"
-	if s.readonlySet.Contains(nodePath) {
-		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", s.CurrentIndex)
-	}
-
-	// recursive implies dir
-	if recursive {
-		dir = true
-	}
-
-	n, err := s.internalGet(nodePath)
-	if err != nil { // if the node does not exist, return error
-		return nil, err
-	}
-
-	nextIndex := s.CurrentIndex + 1
-	e := newEvent(Delete, nodePath, nextIndex, n.CreatedIndex)
-	e.EtcdIndex = nextIndex
-	e.PrevNode = n.Repr(false, false, s.clock)
-	eNode := e.Node
-
-	if n.IsDir() {
-		eNode.Dir = true
-	}
-
-	callback := func(path string) { // notify function
-		// notify the watchers with deleted set true
-		s.WatcherHub.notifyWatchers(e, path, true)
-	}
-
-	err = n.Remove(dir, recursive, callback)
-	if err != nil {
-		return nil, err
-	}
-
-	// update etcd index
-	s.CurrentIndex++
-
-	s.WatcherHub.notify(e)
-
-	return e, nil
-}
-
-func (s *store) CompareAndDelete(nodePath string, prevValue string, prevIndex uint64) (*Event, error) {
-	var err *etcdErr.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(CompareAndDeleteSuccess)
-			reportWriteSuccess(CompareAndDelete)
-			return
-		}
-
-		s.Stats.Inc(CompareAndDeleteFail)
-		reportWriteFailure(CompareAndDelete)
-	}()
-
-	nodePath = path.Clean(path.Join("/", nodePath))
-
-	n, err := s.internalGet(nodePath)
-	if err != nil { // if the node does not exist, return error
-		return nil, err
-	}
-	if n.IsDir() { // can only compare and delete file
-		return nil, etcdErr.NewError(etcdErr.EcodeNotFile, nodePath, s.CurrentIndex)
-	}
-
-	// If both of the prevValue and prevIndex are given, we will test both of them.
-	// Command will be executed, only if both of the tests are successful.
-	if ok, which := n.Compare(prevValue, prevIndex); !ok {
-		cause := getCompareFailCause(n, which, prevValue, prevIndex)
-		return nil, etcdErr.NewError(etcdErr.EcodeTestFailed, cause, s.CurrentIndex)
-	}
-
-	// update etcd index
-	s.CurrentIndex++
-
-	e := newEvent(CompareAndDelete, nodePath, s.CurrentIndex, n.CreatedIndex)
-	e.EtcdIndex = s.CurrentIndex
-	e.PrevNode = n.Repr(false, false, s.clock)
-
-	callback := func(path string) { // notify function
-		// notify the watchers with deleted set true
-		s.WatcherHub.notifyWatchers(e, path, true)
-	}
-
-	err = n.Remove(false, false, callback)
-	if err != nil {
-		return nil, err
-	}
-
-	s.WatcherHub.notify(e)
-
-	return e, nil
-}
-
-func (s *store) Watch(key string, recursive, stream bool, sinceIndex uint64) (Watcher, error) {
-	s.worldLock.RLock()
-	defer s.worldLock.RUnlock()
-
-	key = path.Clean(path.Join("/", key))
-	if sinceIndex == 0 {
-		sinceIndex = s.CurrentIndex + 1
-	}
-	// WatcherHub does not know about the current index, so we need to pass it in
-	w, err := s.WatcherHub.watch(key, recursive, stream, sinceIndex, s.CurrentIndex)
-	if err != nil {
-		return nil, err
-	}
-
-	return w, nil
-}
-
-// walk walks all the nodePath and apply the walkFunc on each directory
-func (s *store) walk(nodePath string, walkFunc func(prev *node, component string) (*node, *etcdErr.Error)) (*node, *etcdErr.Error) {
-	components := strings.Split(nodePath, "/")
-
-	curr := s.Root
-	var err *etcdErr.Error
-
-	for i := 1; i < len(components); i++ {
-		if len(components[i]) == 0 { // ignore empty string
-			return curr, nil
-		}
-
-		curr, err = walkFunc(curr, components[i])
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	return curr, nil
-}
-
-// Update updates the value/ttl of the node.
-// If the node is a file, the value and the ttl can be updated.
-// If the node is a directory, only the ttl can be updated.
-func (s *store) Update(nodePath string, newValue string, expireOpts TTLOptionSet) (*Event, error) {
-	var err *etcdErr.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(UpdateSuccess)
-			reportWriteSuccess(Update)
-			return
-		}
-
-		s.Stats.Inc(UpdateFail)
-		reportWriteFailure(Update)
-	}()
-
-	nodePath = path.Clean(path.Join("/", nodePath))
-	// we do not allow the user to change "/"
-	if s.readonlySet.Contains(nodePath) {
-		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", s.CurrentIndex)
-	}
-
-	currIndex, nextIndex := s.CurrentIndex, s.CurrentIndex+1
-
-	n, err := s.internalGet(nodePath)
-	if err != nil { // if the node does not exist, return error
-		return nil, err
-	}
-	if n.IsDir() && len(newValue) != 0 {
-		// if the node is a directory, we cannot update value to non-empty
-		return nil, etcdErr.NewError(etcdErr.EcodeNotFile, nodePath, currIndex)
-	}
-
-	if expireOpts.Refresh {
-		newValue = n.Value
-	}
-
-	e := newEvent(Update, nodePath, nextIndex, n.CreatedIndex)
-	e.EtcdIndex = nextIndex
-	e.PrevNode = n.Repr(false, false, s.clock)
-	eNode := e.Node
-
-	n.Write(newValue, nextIndex)
-
-	if n.IsDir() {
-		eNode.Dir = true
-	} else {
-		// copy the value for safety
-		newValueCopy := newValue
-		eNode.Value = &newValueCopy
-	}
-
-	// update ttl
-	n.UpdateTTL(expireOpts.ExpireTime)
-
-	eNode.Expiration, eNode.TTL = n.expirationAndTTL(s.clock)
-
-	if !expireOpts.Refresh {
-		s.WatcherHub.notify(e)
-	} else {
-		e.SetRefresh()
-		s.WatcherHub.add(e)
-	}
-
-	s.CurrentIndex = nextIndex
-
-	return e, nil
-}
-
-func (s *store) internalCreate(nodePath string, dir bool, value string, unique, replace bool,
-	expireTime time.Time, action string) (*Event, *etcdErr.Error) {
-
-	currIndex, nextIndex := s.CurrentIndex, s.CurrentIndex+1
-
-	if unique { // append unique item under the node path
-		nodePath += "/" + fmt.Sprintf("%020s", strconv.FormatUint(nextIndex, 10))
-	}
-
-	nodePath = path.Clean(path.Join("/", nodePath))
-
-	// we do not allow the user to change "/"
-	if s.readonlySet.Contains(nodePath) {
-		return nil, etcdErr.NewError(etcdErr.EcodeRootROnly, "/", currIndex)
-	}
-
-	// Assume expire times that are way in the past are
-	// This can occur when the time is serialized to JS
-	if expireTime.Before(minExpireTime) {
-		expireTime = Permanent
-	}
-
-	dirName, nodeName := path.Split(nodePath)
-
-	// walk through the nodePath, create dirs and get the last directory node
-	d, err := s.walk(dirName, s.checkDir)
-
-	if err != nil {
-		s.Stats.Inc(SetFail)
-		reportWriteFailure(action)
-		err.Index = currIndex
-		return nil, err
-	}
-
-	e := newEvent(action, nodePath, nextIndex, nextIndex)
-	eNode := e.Node
-
-	n, _ := d.GetChild(nodeName)
-
-	// force will try to replace an existing file
-	if n != nil {
-		if replace {
-			if n.IsDir() {
-				return nil, etcdErr.NewError(etcdErr.EcodeNotFile, nodePath, currIndex)
-			}
-			e.PrevNode = n.Repr(false, false, s.clock)
-
-			n.Remove(false, false, nil)
-		} else {
-			return nil, etcdErr.NewError(etcdErr.EcodeNodeExist, nodePath, currIndex)
-		}
-	}
-
-	if !dir { // create file
-		// copy the value for safety
-		valueCopy := value
-		eNode.Value = &valueCopy
-
-		n = newKV(s, nodePath, value, nextIndex, d, expireTime)
-
-	} else { // create directory
-		eNode.Dir = true
-
-		n = newDir(s, nodePath, nextIndex, d, expireTime)
-	}
-
-	// we are sure d is a directory and does not have the children with name n.Name
-	d.Add(n)
-
-	// node with TTL
-	if !n.IsPermanent() {
-		s.ttlKeyHeap.push(n)
-
-		eNode.Expiration, eNode.TTL = n.expirationAndTTL(s.clock)
-	}
-
-	s.CurrentIndex = nextIndex
-
-	return e, nil
-}
-
-// InternalGet gets the node of the given nodePath.
-func (s *store) internalGet(nodePath string) (*node, *etcdErr.Error) {
-	nodePath = path.Clean(path.Join("/", nodePath))
-
-	walkFunc := func(parent *node, name string) (*node, *etcdErr.Error) {
-
-		if !parent.IsDir() {
-			err := etcdErr.NewError(etcdErr.EcodeNotDir, parent.Path, s.CurrentIndex)
-			return nil, err
-		}
-
-		child, ok := parent.Children[name]
-		if ok {
-			return child, nil
-		}
-
-		return nil, etcdErr.NewError(etcdErr.EcodeKeyNotFound, path.Join(parent.Path, name), s.CurrentIndex)
-	}
-
-	f, err := s.walk(nodePath, walkFunc)
-
-	if err != nil {
-		return nil, err
-	}
-	return f, nil
-}
-
-// DeleteExpiredKeys will delete all expired keys
-func (s *store) DeleteExpiredKeys(cutoff time.Time) {
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	for {
-		node := s.ttlKeyHeap.top()
-		if node == nil || node.ExpireTime.After(cutoff) {
-			break
-		}
-
-		s.CurrentIndex++
-		e := newEvent(Expire, node.Path, s.CurrentIndex, node.CreatedIndex)
-		e.EtcdIndex = s.CurrentIndex
-		e.PrevNode = node.Repr(false, false, s.clock)
-		if node.IsDir() {
-			e.Node.Dir = true
-		}
-
-		callback := func(path string) { // notify function
-			// notify the watchers with deleted set true
-			s.WatcherHub.notifyWatchers(e, path, true)
-		}
-
-		s.ttlKeyHeap.pop()
-		node.Remove(true, true, callback)
-
-		reportExpiredKey()
-		s.Stats.Inc(ExpireCount)
-
-		s.WatcherHub.notify(e)
-	}
-
-}
-
-// checkDir will check whether the component is a directory under parent node.
-// If it is a directory, this function will return the pointer to that node.
-// If it does not exist, this function will create a new directory and return the pointer to that node.
-// If it is a file, this function will return error.
-func (s *store) checkDir(parent *node, dirName string) (*node, *etcdErr.Error) {
-	node, ok := parent.Children[dirName]
-
-	if ok {
-		if node.IsDir() {
-			return node, nil
-		}
-
-		return nil, etcdErr.NewError(etcdErr.EcodeNotDir, node.Path, s.CurrentIndex)
-	}
-
-	n := newDir(s, path.Join(parent.Path, dirName), s.CurrentIndex+1, parent, Permanent)
-
-	parent.Children[dirName] = n
-
-	return n, nil
-}
-
-// Save saves the static state of the store system.
-// It will not be able to save the state of watchers.
-// It will not save the parent field of the node. Or there will
-// be cyclic dependencies issue for the json package.
-func (s *store) Save() ([]byte, error) {
-	b, err := json.Marshal(s.Clone())
-	if err != nil {
-		return nil, err
-	}
-
-	return b, nil
-}
-
-func (s *store) SaveNoCopy() ([]byte, error) {
-	b, err := json.Marshal(s)
-	if err != nil {
-		return nil, err
-	}
-
-	return b, nil
-}
-
-func (s *store) Clone() Store {
-	s.worldLock.Lock()
-
-	clonedStore := newStore()
-	clonedStore.CurrentIndex = s.CurrentIndex
-	clonedStore.Root = s.Root.Clone()
-	clonedStore.WatcherHub = s.WatcherHub.clone()
-	clonedStore.Stats = s.Stats.clone()
-	clonedStore.CurrentVersion = s.CurrentVersion
-
-	s.worldLock.Unlock()
-	return clonedStore
-}
-
-// Recovery recovers the store system from a static state
-// It needs to recover the parent field of the nodes.
-// It needs to delete the expired nodes since the saved time and also
-// needs to create monitoring go routines.
-func (s *store) Recovery(state []byte) error {
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-	err := json.Unmarshal(state, s)
-
-	if err != nil {
-		return err
-	}
-
-	s.ttlKeyHeap = newTtlKeyHeap()
-
-	s.Root.recoverAndclean()
-	return nil
-}
-
-func (s *store) JsonStats() []byte {
-	s.Stats.Watchers = uint64(s.WatcherHub.count)
-	return s.Stats.toJson()
-}
-
-func (s *store) HasTTLKeys() bool {
-	s.worldLock.RLock()
-	defer s.worldLock.RUnlock()
-	return s.ttlKeyHeap.Len() != 0
-}
diff --git a/vendor/github.com/coreos/etcd/store/ttl_key_heap.go b/vendor/github.com/coreos/etcd/store/ttl_key_heap.go
deleted file mode 100644
index 21ae9b7..0000000
--- a/vendor/github.com/coreos/etcd/store/ttl_key_heap.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-import (
-	"container/heap"
-)
-
-// An TTLKeyHeap is a min-heap of TTLKeys order by expiration time
-type ttlKeyHeap struct {
-	array  []*node
-	keyMap map[*node]int
-}
-
-func newTtlKeyHeap() *ttlKeyHeap {
-	h := &ttlKeyHeap{keyMap: make(map[*node]int)}
-	heap.Init(h)
-	return h
-}
-
-func (h ttlKeyHeap) Len() int {
-	return len(h.array)
-}
-
-func (h ttlKeyHeap) Less(i, j int) bool {
-	return h.array[i].ExpireTime.Before(h.array[j].ExpireTime)
-}
-
-func (h ttlKeyHeap) Swap(i, j int) {
-	// swap node
-	h.array[i], h.array[j] = h.array[j], h.array[i]
-
-	// update map
-	h.keyMap[h.array[i]] = i
-	h.keyMap[h.array[j]] = j
-}
-
-func (h *ttlKeyHeap) Push(x interface{}) {
-	n, _ := x.(*node)
-	h.keyMap[n] = len(h.array)
-	h.array = append(h.array, n)
-}
-
-func (h *ttlKeyHeap) Pop() interface{} {
-	old := h.array
-	n := len(old)
-	x := old[n-1]
-	// Set slice element to nil, so GC can recycle the node.
-	// This is due to golang GC doesn't support partial recycling:
-	// https://github.com/golang/go/issues/9618
-	old[n-1] = nil
-	h.array = old[0 : n-1]
-	delete(h.keyMap, x)
-	return x
-}
-
-func (h *ttlKeyHeap) top() *node {
-	if h.Len() != 0 {
-		return h.array[0]
-	}
-	return nil
-}
-
-func (h *ttlKeyHeap) pop() *node {
-	x := heap.Pop(h)
-	n, _ := x.(*node)
-	return n
-}
-
-func (h *ttlKeyHeap) push(x interface{}) {
-	heap.Push(h, x)
-}
-
-func (h *ttlKeyHeap) update(n *node) {
-	index, ok := h.keyMap[n]
-	if ok {
-		heap.Remove(h, index)
-		heap.Push(h, n)
-	}
-}
-
-func (h *ttlKeyHeap) remove(n *node) {
-	index, ok := h.keyMap[n]
-	if ok {
-		heap.Remove(h, index)
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/store/watcher.go b/vendor/github.com/coreos/etcd/store/watcher.go
deleted file mode 100644
index a236ec7..0000000
--- a/vendor/github.com/coreos/etcd/store/watcher.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-type Watcher interface {
-	EventChan() chan *Event
-	StartIndex() uint64 // The EtcdIndex at which the Watcher was created
-	Remove()
-}
-
-type watcher struct {
-	eventChan  chan *Event
-	stream     bool
-	recursive  bool
-	sinceIndex uint64
-	startIndex uint64
-	hub        *watcherHub
-	removed    bool
-	remove     func()
-}
-
-func (w *watcher) EventChan() chan *Event {
-	return w.eventChan
-}
-
-func (w *watcher) StartIndex() uint64 {
-	return w.startIndex
-}
-
-// notify function notifies the watcher. If the watcher interests in the given path,
-// the function will return true.
-func (w *watcher) notify(e *Event, originalPath bool, deleted bool) bool {
-	// watcher is interested the path in three cases and under one condition
-	// the condition is that the event happens after the watcher's sinceIndex
-
-	// 1. the path at which the event happens is the path the watcher is watching at.
-	// For example if the watcher is watching at "/foo" and the event happens at "/foo",
-	// the watcher must be interested in that event.
-
-	// 2. the watcher is a recursive watcher, it interests in the event happens after
-	// its watching path. For example if watcher A watches at "/foo" and it is a recursive
-	// one, it will interest in the event happens at "/foo/bar".
-
-	// 3. when we delete a directory, we need to force notify all the watchers who watches
-	// at the file we need to delete.
-	// For example a watcher is watching at "/foo/bar". And we deletes "/foo". The watcher
-	// should get notified even if "/foo" is not the path it is watching.
-	if (w.recursive || originalPath || deleted) && e.Index() >= w.sinceIndex {
-		// We cannot block here if the eventChan capacity is full, otherwise
-		// etcd will hang. eventChan capacity is full when the rate of
-		// notifications are higher than our send rate.
-		// If this happens, we close the channel.
-		select {
-		case w.eventChan <- e:
-		default:
-			// We have missed a notification. Remove the watcher.
-			// Removing the watcher also closes the eventChan.
-			w.remove()
-		}
-		return true
-	}
-	return false
-}
-
-// Remove removes the watcher from watcherHub
-// The actual remove function is guaranteed to only be executed once
-func (w *watcher) Remove() {
-	w.hub.mutex.Lock()
-	defer w.hub.mutex.Unlock()
-
-	close(w.eventChan)
-	if w.remove != nil {
-		w.remove()
-	}
-}
-
-// nopWatcher is a watcher that receives nothing, always blocking.
-type nopWatcher struct{}
-
-func NewNopWatcher() Watcher                 { return &nopWatcher{} }
-func (w *nopWatcher) EventChan() chan *Event { return nil }
-func (w *nopWatcher) StartIndex() uint64     { return 0 }
-func (w *nopWatcher) Remove()                {}
diff --git a/vendor/github.com/coreos/etcd/store/watcher_hub.go b/vendor/github.com/coreos/etcd/store/watcher_hub.go
deleted file mode 100644
index 13c23e3..0000000
--- a/vendor/github.com/coreos/etcd/store/watcher_hub.go
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-import (
-	"container/list"
-	"path"
-	"strings"
-	"sync"
-	"sync/atomic"
-
-	etcdErr "github.com/coreos/etcd/error"
-)
-
-// A watcherHub contains all subscribed watchers
-// watchers is a map with watched path as key and watcher as value
-// EventHistory keeps the old events for watcherHub. It is used to help
-// watcher to get a continuous event history. Or a watcher might miss the
-// event happens between the end of the first watch command and the start
-// of the second command.
-type watcherHub struct {
-	// count must be the first element to keep 64-bit alignment for atomic
-	// access
-
-	count int64 // current number of watchers.
-
-	mutex        sync.Mutex
-	watchers     map[string]*list.List
-	EventHistory *EventHistory
-}
-
-// newWatchHub creates a watcherHub. The capacity determines how many events we will
-// keep in the eventHistory.
-// Typically, we only need to keep a small size of history[smaller than 20K].
-// Ideally, it should smaller than 20K/s[max throughput] * 2 * 50ms[RTT] = 2000
-func newWatchHub(capacity int) *watcherHub {
-	return &watcherHub{
-		watchers:     make(map[string]*list.List),
-		EventHistory: newEventHistory(capacity),
-	}
-}
-
-// Watch function returns a Watcher.
-// If recursive is true, the first change after index under key will be sent to the event channel of the watcher.
-// If recursive is false, the first change after index at key will be sent to the event channel of the watcher.
-// If index is zero, watch will start from the current index + 1.
-func (wh *watcherHub) watch(key string, recursive, stream bool, index, storeIndex uint64) (Watcher, *etcdErr.Error) {
-	reportWatchRequest()
-	event, err := wh.EventHistory.scan(key, recursive, index)
-
-	if err != nil {
-		err.Index = storeIndex
-		return nil, err
-	}
-
-	w := &watcher{
-		eventChan:  make(chan *Event, 100), // use a buffered channel
-		recursive:  recursive,
-		stream:     stream,
-		sinceIndex: index,
-		startIndex: storeIndex,
-		hub:        wh,
-	}
-
-	wh.mutex.Lock()
-	defer wh.mutex.Unlock()
-	// If the event exists in the known history, append the EtcdIndex and return immediately
-	if event != nil {
-		ne := event.Clone()
-		ne.EtcdIndex = storeIndex
-		w.eventChan <- ne
-		return w, nil
-	}
-
-	l, ok := wh.watchers[key]
-
-	var elem *list.Element
-
-	if ok { // add the new watcher to the back of the list
-		elem = l.PushBack(w)
-	} else { // create a new list and add the new watcher
-		l = list.New()
-		elem = l.PushBack(w)
-		wh.watchers[key] = l
-	}
-
-	w.remove = func() {
-		if w.removed { // avoid removing it twice
-			return
-		}
-		w.removed = true
-		l.Remove(elem)
-		atomic.AddInt64(&wh.count, -1)
-		reportWatcherRemoved()
-		if l.Len() == 0 {
-			delete(wh.watchers, key)
-		}
-	}
-
-	atomic.AddInt64(&wh.count, 1)
-	reportWatcherAdded()
-
-	return w, nil
-}
-
-func (wh *watcherHub) add(e *Event) {
-	wh.EventHistory.addEvent(e)
-}
-
-// notify function accepts an event and notify to the watchers.
-func (wh *watcherHub) notify(e *Event) {
-	e = wh.EventHistory.addEvent(e) // add event into the eventHistory
-
-	segments := strings.Split(e.Node.Key, "/")
-
-	currPath := "/"
-
-	// walk through all the segments of the path and notify the watchers
-	// if the path is "/foo/bar", it will notify watchers with path "/",
-	// "/foo" and "/foo/bar"
-
-	for _, segment := range segments {
-		currPath = path.Join(currPath, segment)
-		// notify the watchers who interests in the changes of current path
-		wh.notifyWatchers(e, currPath, false)
-	}
-}
-
-func (wh *watcherHub) notifyWatchers(e *Event, nodePath string, deleted bool) {
-	wh.mutex.Lock()
-	defer wh.mutex.Unlock()
-
-	l, ok := wh.watchers[nodePath]
-	if ok {
-		curr := l.Front()
-
-		for curr != nil {
-			next := curr.Next() // save reference to the next one in the list
-
-			w, _ := curr.Value.(*watcher)
-
-			originalPath := (e.Node.Key == nodePath)
-			if (originalPath || !isHidden(nodePath, e.Node.Key)) && w.notify(e, originalPath, deleted) {
-				if !w.stream { // do not remove the stream watcher
-					// if we successfully notify a watcher
-					// we need to remove the watcher from the list
-					// and decrease the counter
-					w.removed = true
-					l.Remove(curr)
-					atomic.AddInt64(&wh.count, -1)
-					reportWatcherRemoved()
-				}
-			}
-
-			curr = next // update current to the next element in the list
-		}
-
-		if l.Len() == 0 {
-			// if we have notified all watcher in the list
-			// we can delete the list
-			delete(wh.watchers, nodePath)
-		}
-	}
-}
-
-// clone function clones the watcherHub and return the cloned one.
-// only clone the static content. do not clone the current watchers.
-func (wh *watcherHub) clone() *watcherHub {
-	clonedHistory := wh.EventHistory.clone()
-
-	return &watcherHub{
-		EventHistory: clonedHistory,
-	}
-}
-
-// isHidden checks to see if key path is considered hidden to watch path i.e. the
-// last element is hidden or it's within a hidden directory
-func isHidden(watchPath, keyPath string) bool {
-	// When deleting a directory, watchPath might be deeper than the actual keyPath
-	// For example, when deleting /foo we also need to notify watchers on /foo/bar.
-	if len(watchPath) > len(keyPath) {
-		return false
-	}
-	// if watch path is just a "/", after path will start without "/"
-	// add a "/" to deal with the special case when watchPath is "/"
-	afterPath := path.Clean("/" + keyPath[len(watchPath):])
-	return strings.Contains(afterPath, "/_")
-}
diff --git a/vendor/github.com/coreos/etcd/test b/vendor/github.com/coreos/etcd/test
deleted file mode 100755
index da356f5..0000000
--- a/vendor/github.com/coreos/etcd/test
+++ /dev/null
@@ -1,632 +0,0 @@
-#!/usr/bin/env bash
-#
-# Run all etcd tests
-# ./test
-# ./test -v
-#
-#
-# Run specified test pass
-#
-# $ PASSES=unit ./test
-# $ PASSES=integration ./test
-#
-#
-# Run tests for one package
-# Each pass has different default timeout, if you just run tests in one package or 1 test case then you can set TIMEOUT
-# flag for different expectation
-#
-# $ PASSES=unit PKG=./wal TIMEOUT=1m ./test
-# $ PASSES=integration PKG=client/integration TIMEOUT=1m ./test
-#
-#
-# Run specified unit tests in one package
-# To run all the tests with prefix of "TestNew", set "TESTCASE=TestNew ";
-# to run only "TestNew", set "TESTCASE="\bTestNew\b""
-#
-# $ PASSES=unit PKG=./wal TESTCASE=TestNew TIMEOUT=1m ./test
-# $ PASSES=unit PKG=./wal TESTCASE="\bTestNew\b" TIMEOUT=1m ./test
-# $ PASSES=integration PKG=client/integration TESTCASE="\bTestV2NoRetryEOF\b" TIMEOUT=1m ./test
-#
-#
-# Run code coverage
-# COVERDIR must either be a absolute path or a relative path to the etcd root
-# $ COVERDIR=coverage PASSES="build_cov cov" ./test
-set -e
-
-source ./build
-
-# build before setting up test GOPATH
-if [[ "${PASSES}" == *"functional"* ]]; then
-	./functional/build
-fi
-
-# build tests with vendored dependencies
-etcd_setup_gopath
-
-if [ -z "$PASSES" ]; then
-	PASSES="fmt bom dep build unit"
-fi
-
-USERPKG=${PKG:-}
-
-# Invoke ./tests/cover.test.bash for HTML output
-COVER=${COVER:-"-cover"}
-
-# Hack: gofmt ./ will recursively check the .git directory. So use *.go for gofmt.
-IGNORE_PKGS="(cmd/|etcdserverpb|rafttest|gopath.proto|v3lockpb|v3electionpb)"
-INTEGRATION_PKGS="(integration|e2e|contrib|functional)"
-
-# all github.com/coreos/etcd/whatever pkgs that are not auto-generated / tools
-# shellcheck disable=SC1117
-PKGS=$(find . -name \*.go | while read -r a; do dirname "$a"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | grep -vE "(tools/|contrib/|e2e|pb)" | sed "s|\.|${REPO_PATH}|g" | xargs echo)
-# pkg1,pkg2,pkg3
-PKGS_COMMA=${PKGS// /,}
-
-# shellcheck disable=SC1117
-TEST_PKGS=$(find . -name \*_test.go | while read -r a; do dirname "$a"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | sed "s|\./||g")
-
-# shellcheck disable=SC1117
-FORMATTABLE=$(find . -name \*.go | while read -r a; do echo "$(dirname "$a")/*.go"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | sed "s|\./||g")
-
-TESTABLE_AND_FORMATTABLE=$(echo "$TEST_PKGS" | grep -vE "$INTEGRATION_PKGS")
-
-# check if user provided PKG override
-if [ -z "${USERPKG}" ]; then
-	TEST=$TESTABLE_AND_FORMATTABLE
-	FMT=$FORMATTABLE
-else
-	# strip out leading dotslashes and trailing slashes from PKG=./foo/
-	TEST=${USERPKG/#./}
-	TEST=${TEST/#\//}
-	TEST=${TEST/%\//}
-	# only run gofmt on packages provided by user
-	FMT="$TEST"
-fi
-
-# shellcheck disable=SC2206
-FMT=($FMT)
-
-# prepend REPO_PATH to each local package
-split=$TEST
-TEST=""
-for a in $split; do TEST="$TEST ${REPO_PATH}/${a}"; done
-
-# shellcheck disable=SC2206
-TEST=($TEST)
-
-# TODO: 'client' pkg fails with gosimple from generated files
-# TODO: 'rafttest' is failing with unused
-STATIC_ANALYSIS_PATHS=$(find . -name \*.go | while read -r a; do dirname "$a"; done | sort | uniq | grep -vE "$IGNORE_PKGS" | grep -v 'client')
-# shellcheck disable=SC2206
-STATIC_ANALYSIS_PATHS=($STATIC_ANALYSIS_PATHS)
-
-if [ -z "$GOARCH" ]; then
-	GOARCH=$(go env GOARCH);
-fi
-
-# determine whether target supports race detection
-if [ "$GOARCH" == "amd64" ]; then
-	RACE="--race"
-fi
-
-RUN_ARG=""
-if [ ! -z "${TESTCASE}" ]; then
-	RUN_ARG="-run=${TESTCASE}"
-fi
-
-function unit_pass {
-	echo "Running unit tests..."
-	GO_TEST_FLAG=""
-	if [ "${VERBOSE}" == "1" ]; then
-		GO_TEST_FLAG="-v"
-	fi
-	if [ "${VERBOSE}" == "2" ]; then
-		GO_TEST_FLAG="-v"
-		export CLIENT_DEBUG=1
-	fi
-
-	if [ "${RUN_ARG}" == "" ]; then
-	    RUN_ARG="-run=Test"
-	fi
-
-	# check if user provided time out, especially useful when just run one test case
-	# expectation could be different
-	USERTIMEOUT=""
-	if [ -z "${TIMEOUT}" ]; then
-		USERTIMEOUT="3m"
-	else
-		USERTIMEOUT="${TIMEOUT}"
-	fi
-	go test ${GO_TEST_FLAG} -timeout "${USERTIMEOUT}"  "${COVER}" ${RACE} -cpu 4 ${RUN_ARG} "$@" "${TEST[@]}"
-}
-
-function integration_pass {
-	echo "Running integration tests..."
-
-	# check if user provided time out, especially useful when just run one test case
-	# expectation could be different
-	USERTIMEOUT=""
-	if [ -z "${TIMEOUT}" ]; then
-		USERTIMEOUT="20m"
-	else
-		USERTIMEOUT="${TIMEOUT}"
-	fi
-
-	# if TESTCASE and PKG set, run specified test case in specified PKG
-	# if TESTCASE set, PKG not set, run specified test case in all integration and integration_extra packages
-	# if TESTCASE not set, PKG set, run all test cases in specified package
-	# if TESTCASE not set, PKG not set, run all tests in all integration and integration_extra packages
-	if [ -z "${TESTCASE}" ] && [ -z "${USERPKG}" ]; then
-		go test -timeout "${USERTIMEOUT}" -v -cpu 4 "$@" "${REPO_PATH}/integration"
-		integration_extra "$@"
-	else
-		if [ -z "${USERPKG}" ]; then
-			INTEGTESTPKG=("${REPO_PATH}/integration"
-						  "${REPO_PATH}/client/integration"
-						  "${REPO_PATH}/clientv3/integration"
-						  "${REPO_PATH}/store")
-		else
-			INTEGTESTPKG=("${TEST[@]}")
-		fi
-		go test -timeout "${USERTIMEOUT}" -v -cpu 4 "${RUN_ARG}"  "$@" "${INTEGTESTPKG[@]}"
-	fi
-}
-
-function integration_extra {
-	go test -timeout 1m -v ${RACE} -cpu 4 "$@" "${REPO_PATH}/client/integration"
-	go test -timeout 25m -v ${RACE} -cpu 4 "$@" "${REPO_PATH}/clientv3/integration"
-}
-
-function functional_pass {
-  	# Clean up any data and logs from previous runs
-  	rm -rf /tmp/etcd-functional-* /tmp/etcd-functional-*.backup
-
-	for a in 1 2 3; do
-		./bin/etcd-agent --network tcp --address 127.0.0.1:${a}9027 &
-		pid="$!"
-		agent_pids="${agent_pids} $pid"
-	done
-
-	for a in 1 2 3; do
-		echo "Waiting for 'etcd-agent' on ${a}9027..."
-		while ! nc -z localhost ${a}9027; do
-			sleep 1
-		done
-	done
-
-	echo "functional test START!"
-	./bin/etcd-tester --config ./functional.yaml && echo "'etcd-tester' succeeded"
-	ETCD_TESTER_EXIT_CODE=$?
-	echo "ETCD_TESTER_EXIT_CODE:" ${ETCD_TESTER_EXIT_CODE}
-
-	# shellcheck disable=SC2206
-	agent_pids=($agent_pids)
-	kill -s TERM "${agent_pids[@]}" || true
-
-	if [[ "${ETCD_TESTER_EXIT_CODE}" -ne "0" ]]; then
-		echo "--- FAIL: exit code" ${ETCD_TESTER_EXIT_CODE}
-		exit ${ETCD_TESTER_EXIT_CODE}
-	fi
-	echo "functional test PASS!"
-}
-
-function cov_pass {
-	echo "Running code coverage..."
-	# install gocovmerge before running code coverage from github.com/wadey/gocovmerge
-	# gocovmerge merges coverage files
-	if ! which gocovmerge >/dev/null; then
-		echo "gocovmerge not installed"
-		exit 255
-	fi
-
-	if [ -z "$COVERDIR" ]; then
-		echo "COVERDIR undeclared"
-		exit 255
-	fi
-
-	if [ ! -f "bin/etcd_test" ]; then
-		echo "etcd_test binary not found"
-		exit 255
-	fi
-
-	mkdir -p "$COVERDIR"
-
-	# run code coverage for unit and integration tests
-	GOCOVFLAGS="-covermode=set -coverpkg ${PKGS_COMMA} -v -timeout 20m"
-	# shellcheck disable=SC2206
-	GOCOVFLAGS=($GOCOVFLAGS)
-	failed=""
-	for t in $(echo "${TEST_PKGS}" | grep -vE "(e2e|functional)"); do
-		tf=$(echo "$t" | tr / _)
-		# cache package compilation data for faster repeated builds
-		go test "${GOCOVFLAGS[@]}" -i "${REPO_PATH}/$t" || true
-		# uses -run=Test to skip examples because clientv3/ example tests will leak goroutines
-		go test "${GOCOVFLAGS[@]}" -run=Test -coverprofile "$COVERDIR/${tf}.coverprofile"  "${REPO_PATH}/$t" || failed="$failed $t"
-	done
-
-	# v2v3 tests
-	go test -tags v2v3 "${GOCOVFLAGS[@]}" -coverprofile "$COVERDIR/store-v2v3.coverprofile" "${REPO_PATH}/clientv3/integration" || failed="$failed store-v2v3"
-
-	# proxy tests
-	go test -tags cluster_proxy "${GOCOVFLAGS[@]}" -coverprofile "$COVERDIR/proxy_integration.coverprofile" "${REPO_PATH}/integration" || failed="$failed proxy-integration"
-	go test -tags cluster_proxy "${GOCOVFLAGS[@]}" -coverprofile "$COVERDIR/proxy_clientv3.coverprofile" "${REPO_PATH}/clientv3/integration" || failed="$failed proxy-clientv3/integration"
-
-	# run code coverage for e2e tests
-	# use 30m timeout because e2e coverage takes longer
-	# due to many tests cause etcd process to wait
-	# on leadership transfer timeout during gracefully shutdown
-	echo Testing e2e without proxy...
-	go test -tags cov -timeout 30m -v "${REPO_PATH}/e2e" || failed="$failed e2e"
-	echo Testing e2e with proxy...
-	go test -tags "cov cluster_proxy" -timeout 30m -v "${REPO_PATH}/e2e" || failed="$failed e2e-proxy"
-
-	# incrementally merge to get coverage data even if some coverage files are corrupted
-	# optimistically assume etcdserver package's coverage file is OK since gocovmerge
-	# expects to start with a non-empty file
-	cp "$COVERDIR"/etcdserver.coverprofile "$COVERDIR"/cover.out
-	for f in "$COVERDIR"/*.coverprofile; do
-		echo "merging test coverage file ${f}"
-		gocovmerge "$f" "$COVERDIR"/cover.out  >"$COVERDIR"/cover.tmp || failed="$failed $f"
-		if [ -s "$COVERDIR"/cover.tmp ]; then
-			mv "$COVERDIR"/cover.tmp "$COVERDIR"/cover.out
-		fi
-	done
-	# strip out generated files (using GNU-style sed)
-	sed --in-place '/generated.go/d' "$COVERDIR"/cover.out || true
-
-	# held failures to generate the full coverage file, now fail
-	if [ -n "$failed" ]; then
-		for f in $failed; do
-			echo "--- FAIL:" "$f"
-		done
-		exit 255
-	fi
-}
-
-function e2e_pass {
-	echo "Running e2e tests..."
-
-	# check if user provided time out, especially useful when just run one test case
-	# expectation could be different
-	USERTIMEOUT=""
-	if [ -z "${TIMEOUT}" ]; then
-		USERTIMEOUT="20m"
-	else
-		USERTIMEOUT="${TIMEOUT}"
-	fi
-
-	go test -timeout "${USERTIMEOUT}" -v -cpu 4 "${RUN_ARG}"  "$@" "${REPO_PATH}/e2e"
-}
-
-function integration_e2e_pass {
-	echo "Running integration and e2e tests..."
-
-	go test -timeout 20m -v -cpu 4 "$@" "${REPO_PATH}/e2e" &
-	e2epid="$!"
-	go test -timeout 20m -v -cpu 4 "$@" "${REPO_PATH}/integration" &
-	intpid="$!"
-	wait $e2epid
-	wait $intpid
-	integration_extra "$@"
-}
-
-function grpcproxy_pass {
-	go test -timeout 20m -v ${RACE} -tags cluster_proxy -cpu 4 "$@" "${REPO_PATH}/integration"
-	go test -timeout 20m -v ${RACE} -tags cluster_proxy -cpu 4 "$@" "${REPO_PATH}/clientv3/integration"
-	go test -timeout 20m -v -tags cluster_proxy "$@" "${REPO_PATH}/e2e"
-}
-
-function release_pass {
-	rm -f ./bin/etcd-last-release
-	# to grab latest patch release; bump this up for every minor release
-	UPGRADE_VER=$(git tag -l --sort=-version:refname "v3.3.*" | head -1)
-	if [ -n "$MANUAL_VER" ]; then
-		# in case, we need to test against different version
-		UPGRADE_VER=$MANUAL_VER
-	fi
-	if [[ -z ${UPGRADE_VER} ]]; then
-		UPGRADE_VER="v3.3.0"
-		echo "fallback to" ${UPGRADE_VER}
-	fi
-
-	local file="etcd-$UPGRADE_VER-linux-$GOARCH.tar.gz"
-	echo "Downloading $file"
-
-	set +e
-	curl --fail -L "https://github.com/coreos/etcd/releases/download/$UPGRADE_VER/$file" -o "/tmp/$file"
-	local result=$?
-	set -e
-	case $result in
-		0)	;;
-		*)	echo "--- FAIL:" ${result}
-			exit $result
-			;;
-	esac
-
-	tar xzvf "/tmp/$file" -C /tmp/ --strip-components=1
-	mkdir -p ./bin
-	mv /tmp/etcd ./bin/etcd-last-release
-}
-
-function shellcheck_pass {
-	if which shellcheck >/dev/null; then
-		shellcheckResult=$(shellcheck -fgcc build test scripts/*.sh 2>&1 || true)
-		if [ -n "${shellcheckResult}" ]; then
-			echo -e "shellcheck checking failed:\\n${shellcheckResult}"
-			exit 255
-		fi
-	fi
-}
-
-function markdown_you_pass {
-	# eschew you
-	yous=$(find . -name \*.md -exec grep -E --color "[Yy]ou[r]?[ '.,;]" {} + | grep -v /v2/ || true)
-	if [ ! -z "$yous" ]; then
-		echo -e "found 'you' in documentation:\\n${yous}"
-		exit 255
-	fi
-}
-
-function markdown_marker_pass {
-	# TODO: check other markdown files when marker handles headers with '[]'
-	if which marker >/dev/null; then
-		markerResult=$(marker --skip-http --root ./Documentation 2>&1 || true)
-		if [ -n "${markerResult}" ]; then
-			echo -e "marker checking failed:\\n${markerResult}"
-			exit 255
-		fi
-	else
-		echo "Skipping marker..."
-	fi
-}
-
-function goword_pass {
-	if which goword >/dev/null; then
-		# get all go files to process
-		gofiles=$(find "${FMT[@]}" -iname '*.go' 2>/dev/null)
-		# shellcheck disable=SC2206
-		gofiles_all=($gofiles)
-		# ignore tests and protobuf files
-		# shellcheck disable=SC1117
-		gofiles=$(echo "${gofiles_all[@]}" | sort | uniq | sed "s/ /\n/g" | grep -vE "(\\_test.go|\\.pb\\.go)")
-		# shellcheck disable=SC2206
-		gofiles=($gofiles)
-		# only check for broken exported godocs
-		gowordRes=$(goword -use-spell=false "${gofiles[@]}" | grep godoc-export | sort)
-		if [ ! -z "$gowordRes" ]; then
-			echo -e "goword checking failed:\\n${gowordRes}"
-			exit 255
-		fi
-		# check some spelling
-		gowordRes=$(goword -ignore-file=.words clientv3/{*,*/*}.go 2>&1 | grep spell | sort)
-		if [ ! -z "$gowordRes" ]; then
-			echo -e "goword checking failed:\\n${gowordRes}"
-			exit 255
-		fi
-	else
-		echo "Skipping goword..."
-	fi
-}
-
-function gofmt_pass {
-	fmtRes=$(gofmt -l -s -d "${FMT[@]}")
-	if [ -n "${fmtRes}" ]; then
-		echo -e "gofmt checking failed:\\n${fmtRes}"
-		exit 255
-	fi
-}
-
-function govet_pass {
-	vetRes=$(go vet "${TEST[@]}")
-	if [ -n "${vetRes}" ]; then
-		echo -e "govet checking failed:\\n${vetRes}"
-		exit 255
-	fi
-}
-
-function govet_shadow_pass {
-	fmtpkgs=$(for a in "${FMT[@]}"; do dirname "$a"; done | sort | uniq | grep -v "\\.")
-	# shellcheck disable=SC2206
-	fmtpkgs=($fmtpkgs)
-	vetRes=$(go tool vet -all -shadow "${fmtpkgs[@]}" 2>&1 | grep -v '/gw/' || true)
-	if [ -n "${vetRes}" ]; then
-		echo -e "govet -all -shadow checking failed:\\n${vetRes}"
-		exit 255
-	fi
-}
-
-function gosimple_pass {
-	if which gosimple >/dev/null; then
-		gosimpleResult=$(gosimple "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
-		if [ -n "${gosimpleResult}" ]; then
-			echo -e "gosimple checking failed:\\n${gosimpleResult}"
-			exit 255
-		fi
-	else
-		echo "Skipping gosimple..."
-	fi
-}
-
-function unused_pass {
-	if which unused >/dev/null; then
-		unusedResult=$(unused "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
-		if [ -n "${unusedResult}" ]; then
-			echo -e "unused checking failed:\\n${unusedResult}"
-			exit 255
-		fi
-	else
-		echo "Skipping unused..."
-	fi
-}
-
-function staticcheck_pass {
-	if which staticcheck >/dev/null; then
-		staticcheckResult=$(staticcheck "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
-		if [ -n "${staticcheckResult}" ]; then
-			# TODO: resolve these after go1.8 migration
-			# See https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck
-			STATIC_CHECK_MASK="SA(1012|1019|2002)"
-			if echo "${staticcheckResult}" | grep -vE "$STATIC_CHECK_MASK"; then
-				echo -e "staticcheck checking failed:\\n${staticcheckResult}"
-				exit 255
-			else
-				suppressed=$(echo "${staticcheckResult}" | sed 's/ /\n/g' | grep "(SA" | sort | uniq -c)
-				echo -e "staticcheck suppressed warnings:\\n${suppressed}"
-			fi
-		fi
-	else
-		echo "Skipping staticcheck..."
-	fi
-}
-
-function ineffassign_pass {
-	if which ineffassign >/dev/null; then
-		ineffassignResult=$(ineffassign "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
-		if [ -n "${ineffassignResult}" ]; then
-			echo -e "ineffassign checking failed:\\n${ineffassignResult}"
-			exit 255
-		fi
-	else
-		echo "Skipping ineffassign..."
-	fi
-}
-
-function nakedret_pass {
-	if which nakedret >/dev/null; then
-		nakedretResult=$(nakedret "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
-		if [ -n "${nakedretResult}" ]; then
-			echo -e "nakedret checking failed:\\n${nakedretResult}"
-			exit 255
-		fi
-	else
-		echo "Skipping nakedret..."
-	fi
-}
-
-function license_header_pass {
-	licRes=""
-	files=$(find . -type f -iname '*.go' ! -path './cmd/*' ! -path './gopath.proto/*')
-	for file in $files; do
-		if ! head -n3 "${file}" | grep -Eq "(Copyright|generated|GENERATED)" ; then
-			licRes="${licRes}"$(echo -e "  ${file}")
-		fi
-	done
-	if [ -n "${licRes}" ]; then
-		echo -e "license header checking failed:\\n${licRes}"
-		exit 255
-	fi
-}
-
-function receiver_name_pass {
-	# shellcheck disable=SC1117
-	recvs=$(grep 'func ([^*]' {*,*/*,*/*/*}.go  | grep -Ev "(generated|pb/)" | tr  ':' ' ' |  \
-		awk ' { print $2" "$3" "$4" "$1 }' | sed "s/[a-zA-Z\.]*go//g" |  sort  | uniq  | \
-		grep -Ev  "(Descriptor|Proto|_)"  | awk ' { print $3" "$4 } ' | sort | uniq -c | grep -v ' 1 ' | awk ' { print $2 } ')
-	if [ -n "${recvs}" ]; then
-		# shellcheck disable=SC2206
-		recvs=($recvs)
-		for recv in "${recvs[@]}"; do
-			echo "Mismatched receiver for $recv..."
-			grep "$recv" "${FMT[@]}" | grep 'func ('
-		done
-		exit 255
-	fi
-}
-
-function commit_title_pass {
-	git log --oneline "$(git merge-base HEAD master)"...HEAD | while read -r l; do
-		commitMsg=$(echo "$l" | cut -f2- -d' ')
-		if [[ "$commitMsg" == Merge* ]]; then
-			# ignore "Merge pull" commits
-			continue
-		fi
-		if [[ "$commitMsg" == Revert* ]]; then
-			# ignore revert commits
-			continue
-		fi
-
-		pkgPrefix=$(echo "$commitMsg" | cut -f1 -d':')
-		spaceCommas=$(echo "$commitMsg" | sed 's/ /\n/g' | grep -c ',$' || echo 0)
-		commaSpaces=$(echo "$commitMsg" | sed 's/,/\n/g' | grep -c '^ ' || echo 0)
-		if [[ $(echo "$commitMsg" | grep -c ":..*") == 0 || "$commitMsg" == "$pkgPrefix" || "$spaceCommas" != "$commaSpaces" ]]; then
-			echo "$l"...
-			echo "Expected commit title format '<package>{\", \"<package>}: <description>'"
-			echo "Got: $l"
-			exit 255
-		fi
-	done
-}
-
-function fmt_pass {
-	toggle_failpoints disable
-
-	for p in shellcheck \
-			markdown_you \
-			markdown_marker \
-			goword \
-			gofmt \
-			govet \
-			govet_shadow \
-			gosimple \
-			unused \
-			staticcheck \
-			ineffassign \
-			nakedret \
-			license_header \
-			receiver_name \
-			commit_title \
-			; do
-		echo "'$p' started at $(date)"
-		"${p}"_pass "$@"
-		echo "'$p' completed at $(date)"
-	done
-}
-
-function bom_pass {
-	if ! which license-bill-of-materials >/dev/null; then
-		return
-	fi
-	echo "Checking bill of materials..."
-	license-bill-of-materials \
-		--override-file bill-of-materials.override.json \
-		github.com/coreos/etcd github.com/coreos/etcd/etcdctl >bom-now.json || true
-	if ! diff bill-of-materials.json bom-now.json; then
-		echo "vendored licenses do not match given bill of materials"
-		exit 255
-	fi
-	rm bom-now.json
-}
-
-function dep_pass {
-	echo "Checking package dependencies..."
-	# don't pull in etcdserver package
-	pushd clientv3 >/dev/null
-	badpkg="(etcdserver$|mvcc$|backend$|grpc-gateway)"
-	deps=$(go list -f '{{ .Deps }}'  | sed 's/ /\n/g' | grep -E "${badpkg}" || echo "")
-	popd >/dev/null
-	if [ ! -z "$deps" ]; then
-		echo -e "clientv3 has masked dependencies:\\n${deps}"
-		exit 255
-	fi
-}
-
-function build_cov_pass {
-	out="bin"
-	if [ -n "${BINDIR}" ]; then out="${BINDIR}"; fi
-	go test -tags cov -c -covermode=set -coverpkg="$PKGS_COMMA" -o "${out}/etcd_test"
-	go test -tags cov -c -covermode=set -coverpkg="$PKGS_COMMA" -o "${out}/etcdctl_test" "${REPO_PATH}/etcdctl"
-}
-
-# fail fast on static tests
-function build_pass {
-	echo "Checking build..."
-	GO_BUILD_FLAGS="-v" etcd_build
-}
-
-for pass in $PASSES; do
-	echo "Starting '$pass' pass at $(date)"
-	"${pass}"_pass "$@"
-	echo "Finished '$pass' pass at $(date)"
-done
-
-echo "Success"
diff --git a/vendor/github.com/coreos/etcd/version/version.go b/vendor/github.com/coreos/etcd/version/version.go
deleted file mode 100644
index c52accc..0000000
--- a/vendor/github.com/coreos/etcd/version/version.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package version implements etcd version parsing and contains latest version
-// information.
-package version
-
-import (
-	"fmt"
-	"strings"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-var (
-	// MinClusterVersion is the min cluster version this etcd binary is compatible with.
-	MinClusterVersion = "3.0.0"
-	Version           = "3.3.11"
-	APIVersion        = "unknown"
-
-	// Git SHA Value will be set during build
-	GitSHA = "Not provided (use ./build instead of go build)"
-)
-
-func init() {
-	ver, err := semver.NewVersion(Version)
-	if err == nil {
-		APIVersion = fmt.Sprintf("%d.%d", ver.Major, ver.Minor)
-	}
-}
-
-type Versions struct {
-	Server  string `json:"etcdserver"`
-	Cluster string `json:"etcdcluster"`
-	// TODO: raft state machine version
-}
-
-// Cluster only keeps the major.minor.
-func Cluster(v string) string {
-	vs := strings.Split(v, ".")
-	if len(vs) <= 2 {
-		return v
-	}
-	return fmt.Sprintf("%s.%s", vs[0], vs[1])
-}
diff --git a/vendor/github.com/coreos/etcd/wal/decoder.go b/vendor/github.com/coreos/etcd/wal/decoder.go
deleted file mode 100644
index 6a217f8..0000000
--- a/vendor/github.com/coreos/etcd/wal/decoder.go
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package wal
-
-import (
-	"bufio"
-	"encoding/binary"
-	"hash"
-	"io"
-	"sync"
-
-	"github.com/coreos/etcd/pkg/crc"
-	"github.com/coreos/etcd/pkg/pbutil"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/wal/walpb"
-)
-
-const minSectorSize = 512
-
-// frameSizeBytes is frame size in bytes, including record size and padding size.
-const frameSizeBytes = 8
-
-type decoder struct {
-	mu  sync.Mutex
-	brs []*bufio.Reader
-
-	// lastValidOff file offset following the last valid decoded record
-	lastValidOff int64
-	crc          hash.Hash32
-}
-
-func newDecoder(r ...io.Reader) *decoder {
-	readers := make([]*bufio.Reader, len(r))
-	for i := range r {
-		readers[i] = bufio.NewReader(r[i])
-	}
-	return &decoder{
-		brs: readers,
-		crc: crc.New(0, crcTable),
-	}
-}
-
-func (d *decoder) decode(rec *walpb.Record) error {
-	rec.Reset()
-	d.mu.Lock()
-	defer d.mu.Unlock()
-	return d.decodeRecord(rec)
-}
-
-func (d *decoder) decodeRecord(rec *walpb.Record) error {
-	if len(d.brs) == 0 {
-		return io.EOF
-	}
-
-	l, err := readInt64(d.brs[0])
-	if err == io.EOF || (err == nil && l == 0) {
-		// hit end of file or preallocated space
-		d.brs = d.brs[1:]
-		if len(d.brs) == 0 {
-			return io.EOF
-		}
-		d.lastValidOff = 0
-		return d.decodeRecord(rec)
-	}
-	if err != nil {
-		return err
-	}
-
-	recBytes, padBytes := decodeFrameSize(l)
-
-	data := make([]byte, recBytes+padBytes)
-	if _, err = io.ReadFull(d.brs[0], data); err != nil {
-		// ReadFull returns io.EOF only if no bytes were read
-		// the decoder should treat this as an ErrUnexpectedEOF instead.
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		return err
-	}
-	if err := rec.Unmarshal(data[:recBytes]); err != nil {
-		if d.isTornEntry(data) {
-			return io.ErrUnexpectedEOF
-		}
-		return err
-	}
-
-	// skip crc checking if the record type is crcType
-	if rec.Type != crcType {
-		d.crc.Write(rec.Data)
-		if err := rec.Validate(d.crc.Sum32()); err != nil {
-			if d.isTornEntry(data) {
-				return io.ErrUnexpectedEOF
-			}
-			return err
-		}
-	}
-	// record decoded as valid; point last valid offset to end of record
-	d.lastValidOff += frameSizeBytes + recBytes + padBytes
-	return nil
-}
-
-func decodeFrameSize(lenField int64) (recBytes int64, padBytes int64) {
-	// the record size is stored in the lower 56 bits of the 64-bit length
-	recBytes = int64(uint64(lenField) & ^(uint64(0xff) << 56))
-	// non-zero padding is indicated by set MSb / a negative length
-	if lenField < 0 {
-		// padding is stored in lower 3 bits of length MSB
-		padBytes = int64((uint64(lenField) >> 56) & 0x7)
-	}
-	return recBytes, padBytes
-}
-
-// isTornEntry determines whether the last entry of the WAL was partially written
-// and corrupted because of a torn write.
-func (d *decoder) isTornEntry(data []byte) bool {
-	if len(d.brs) != 1 {
-		return false
-	}
-
-	fileOff := d.lastValidOff + frameSizeBytes
-	curOff := 0
-	chunks := [][]byte{}
-	// split data on sector boundaries
-	for curOff < len(data) {
-		chunkLen := int(minSectorSize - (fileOff % minSectorSize))
-		if chunkLen > len(data)-curOff {
-			chunkLen = len(data) - curOff
-		}
-		chunks = append(chunks, data[curOff:curOff+chunkLen])
-		fileOff += int64(chunkLen)
-		curOff += chunkLen
-	}
-
-	// if any data for a sector chunk is all 0, it's a torn write
-	for _, sect := range chunks {
-		isZero := true
-		for _, v := range sect {
-			if v != 0 {
-				isZero = false
-				break
-			}
-		}
-		if isZero {
-			return true
-		}
-	}
-	return false
-}
-
-func (d *decoder) updateCRC(prevCrc uint32) {
-	d.crc = crc.New(prevCrc, crcTable)
-}
-
-func (d *decoder) lastCRC() uint32 {
-	return d.crc.Sum32()
-}
-
-func (d *decoder) lastOffset() int64 { return d.lastValidOff }
-
-func mustUnmarshalEntry(d []byte) raftpb.Entry {
-	var e raftpb.Entry
-	pbutil.MustUnmarshal(&e, d)
-	return e
-}
-
-func mustUnmarshalState(d []byte) raftpb.HardState {
-	var s raftpb.HardState
-	pbutil.MustUnmarshal(&s, d)
-	return s
-}
-
-func readInt64(r io.Reader) (int64, error) {
-	var n int64
-	err := binary.Read(r, binary.LittleEndian, &n)
-	return n, err
-}
diff --git a/vendor/github.com/coreos/etcd/wal/doc.go b/vendor/github.com/coreos/etcd/wal/doc.go
deleted file mode 100644
index a3abd69..0000000
--- a/vendor/github.com/coreos/etcd/wal/doc.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/*
-Package wal provides an implementation of a write ahead log that is used by
-etcd.
-
-A WAL is created at a particular directory and is made up of a number of
-segmented WAL files. Inside of each file the raft state and entries are appended
-to it with the Save method:
-
-	metadata := []byte{}
-	w, err := wal.Create("/var/lib/etcd", metadata)
-	...
-	err := w.Save(s, ents)
-
-After saving a raft snapshot to disk, SaveSnapshot method should be called to
-record it. So WAL can match with the saved snapshot when restarting.
-
-	err := w.SaveSnapshot(walpb.Snapshot{Index: 10, Term: 2})
-
-When a user has finished using a WAL it must be closed:
-
-	w.Close()
-
-Each WAL file is a stream of WAL records. A WAL record is a length field and a wal record
-protobuf. The record protobuf contains a CRC, a type, and a data payload. The length field is a
-64-bit packed structure holding the length of the remaining logical record data in its lower
-56 bits and its physical padding in the first three bits of the most significant byte. Each
-record is 8-byte aligned so that the length field is never torn. The CRC contains the CRC32
-value of all record protobufs preceding the current record.
-
-WAL files are placed inside of the directory in the following format:
-$seq-$index.wal
-
-The first WAL file to be created will be 0000000000000000-0000000000000000.wal
-indicating an initial sequence of 0 and an initial raft index of 0. The first
-entry written to WAL MUST have raft index 0.
-
-WAL will cut its current tail wal file if its size exceeds 64MB. This will increment an internal
-sequence number and cause a new file to be created. If the last raft index saved
-was 0x20 and this is the first time cut has been called on this WAL then the sequence will
-increment from 0x0 to 0x1. The new file will be: 0000000000000001-0000000000000021.wal.
-If a second cut issues 0x10 entries with incremental index later then the file will be called:
-0000000000000002-0000000000000031.wal.
-
-At a later time a WAL can be opened at a particular snapshot. If there is no
-snapshot, an empty snapshot should be passed in.
-
-	w, err := wal.Open("/var/lib/etcd", walpb.Snapshot{Index: 10, Term: 2})
-	...
-
-The snapshot must have been written to the WAL.
-
-Additional items cannot be Saved to this WAL until all of the items from the given
-snapshot to the end of the WAL are read first:
-
-	metadata, state, ents, err := w.ReadAll()
-
-This will give you the metadata, the last raft.State and the slice of
-raft.Entry items in the log.
-
-*/
-package wal
diff --git a/vendor/github.com/coreos/etcd/wal/encoder.go b/vendor/github.com/coreos/etcd/wal/encoder.go
deleted file mode 100644
index e8040b8..0000000
--- a/vendor/github.com/coreos/etcd/wal/encoder.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package wal
-
-import (
-	"encoding/binary"
-	"hash"
-	"io"
-	"os"
-	"sync"
-
-	"github.com/coreos/etcd/pkg/crc"
-	"github.com/coreos/etcd/pkg/ioutil"
-	"github.com/coreos/etcd/wal/walpb"
-)
-
-// walPageBytes is the alignment for flushing records to the backing Writer.
-// It should be a multiple of the minimum sector size so that WAL can safely
-// distinguish between torn writes and ordinary data corruption.
-const walPageBytes = 8 * minSectorSize
-
-type encoder struct {
-	mu sync.Mutex
-	bw *ioutil.PageWriter
-
-	crc       hash.Hash32
-	buf       []byte
-	uint64buf []byte
-}
-
-func newEncoder(w io.Writer, prevCrc uint32, pageOffset int) *encoder {
-	return &encoder{
-		bw:  ioutil.NewPageWriter(w, walPageBytes, pageOffset),
-		crc: crc.New(prevCrc, crcTable),
-		// 1MB buffer
-		buf:       make([]byte, 1024*1024),
-		uint64buf: make([]byte, 8),
-	}
-}
-
-// newFileEncoder creates a new encoder with current file offset for the page writer.
-func newFileEncoder(f *os.File, prevCrc uint32) (*encoder, error) {
-	offset, err := f.Seek(0, io.SeekCurrent)
-	if err != nil {
-		return nil, err
-	}
-	return newEncoder(f, prevCrc, int(offset)), nil
-}
-
-func (e *encoder) encode(rec *walpb.Record) error {
-	e.mu.Lock()
-	defer e.mu.Unlock()
-
-	e.crc.Write(rec.Data)
-	rec.Crc = e.crc.Sum32()
-	var (
-		data []byte
-		err  error
-		n    int
-	)
-
-	if rec.Size() > len(e.buf) {
-		data, err = rec.Marshal()
-		if err != nil {
-			return err
-		}
-	} else {
-		n, err = rec.MarshalTo(e.buf)
-		if err != nil {
-			return err
-		}
-		data = e.buf[:n]
-	}
-
-	lenField, padBytes := encodeFrameSize(len(data))
-	if err = writeUint64(e.bw, lenField, e.uint64buf); err != nil {
-		return err
-	}
-
-	if padBytes != 0 {
-		data = append(data, make([]byte, padBytes)...)
-	}
-	_, err = e.bw.Write(data)
-	return err
-}
-
-func encodeFrameSize(dataBytes int) (lenField uint64, padBytes int) {
-	lenField = uint64(dataBytes)
-	// force 8 byte alignment so length never gets a torn write
-	padBytes = (8 - (dataBytes % 8)) % 8
-	if padBytes != 0 {
-		lenField |= uint64(0x80|padBytes) << 56
-	}
-	return lenField, padBytes
-}
-
-func (e *encoder) flush() error {
-	e.mu.Lock()
-	defer e.mu.Unlock()
-	return e.bw.Flush()
-}
-
-func writeUint64(w io.Writer, n uint64, buf []byte) error {
-	// http://golang.org/src/encoding/binary/binary.go
-	binary.LittleEndian.PutUint64(buf, n)
-	_, err := w.Write(buf)
-	return err
-}
diff --git a/vendor/github.com/coreos/etcd/wal/file_pipeline.go b/vendor/github.com/coreos/etcd/wal/file_pipeline.go
deleted file mode 100644
index 3a1c57c..0000000
--- a/vendor/github.com/coreos/etcd/wal/file_pipeline.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package wal
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-
-	"github.com/coreos/etcd/pkg/fileutil"
-)
-
-// filePipeline pipelines allocating disk space
-type filePipeline struct {
-	// dir to put files
-	dir string
-	// size of files to make, in bytes
-	size int64
-	// count number of files generated
-	count int
-
-	filec chan *fileutil.LockedFile
-	errc  chan error
-	donec chan struct{}
-}
-
-func newFilePipeline(dir string, fileSize int64) *filePipeline {
-	fp := &filePipeline{
-		dir:   dir,
-		size:  fileSize,
-		filec: make(chan *fileutil.LockedFile),
-		errc:  make(chan error, 1),
-		donec: make(chan struct{}),
-	}
-	go fp.run()
-	return fp
-}
-
-// Open returns a fresh file for writing. Rename the file before calling
-// Open again or there will be file collisions.
-func (fp *filePipeline) Open() (f *fileutil.LockedFile, err error) {
-	select {
-	case f = <-fp.filec:
-	case err = <-fp.errc:
-	}
-	return f, err
-}
-
-func (fp *filePipeline) Close() error {
-	close(fp.donec)
-	return <-fp.errc
-}
-
-func (fp *filePipeline) alloc() (f *fileutil.LockedFile, err error) {
-	// count % 2 so this file isn't the same as the one last published
-	fpath := filepath.Join(fp.dir, fmt.Sprintf("%d.tmp", fp.count%2))
-	if f, err = fileutil.LockFile(fpath, os.O_CREATE|os.O_WRONLY, fileutil.PrivateFileMode); err != nil {
-		return nil, err
-	}
-	if err = fileutil.Preallocate(f.File, fp.size, true); err != nil {
-		plog.Errorf("failed to allocate space when creating new wal file (%v)", err)
-		f.Close()
-		return nil, err
-	}
-	fp.count++
-	return f, nil
-}
-
-func (fp *filePipeline) run() {
-	defer close(fp.errc)
-	for {
-		f, err := fp.alloc()
-		if err != nil {
-			fp.errc <- err
-			return
-		}
-		select {
-		case fp.filec <- f:
-		case <-fp.donec:
-			os.Remove(f.Name())
-			f.Close()
-			return
-		}
-	}
-}
diff --git a/vendor/github.com/coreos/etcd/wal/metrics.go b/vendor/github.com/coreos/etcd/wal/metrics.go
deleted file mode 100644
index 9e089d3..0000000
--- a/vendor/github.com/coreos/etcd/wal/metrics.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package wal
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	syncDurations = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "disk",
-		Name:      "wal_fsync_duration_seconds",
-		Help:      "The latency distributions of fsync called by wal.",
-		Buckets:   prometheus.ExponentialBuckets(0.001, 2, 14),
-	})
-)
-
-func init() {
-	prometheus.MustRegister(syncDurations)
-}
diff --git a/vendor/github.com/coreos/etcd/wal/repair.go b/vendor/github.com/coreos/etcd/wal/repair.go
deleted file mode 100644
index 091036b..0000000
--- a/vendor/github.com/coreos/etcd/wal/repair.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package wal
-
-import (
-	"io"
-	"os"
-	"path/filepath"
-
-	"github.com/coreos/etcd/pkg/fileutil"
-	"github.com/coreos/etcd/wal/walpb"
-)
-
-// Repair tries to repair ErrUnexpectedEOF in the
-// last wal file by truncating.
-func Repair(dirpath string) bool {
-	f, err := openLast(dirpath)
-	if err != nil {
-		return false
-	}
-	defer f.Close()
-
-	rec := &walpb.Record{}
-	decoder := newDecoder(f)
-	for {
-		lastOffset := decoder.lastOffset()
-		err := decoder.decode(rec)
-		switch err {
-		case nil:
-			// update crc of the decoder when necessary
-			switch rec.Type {
-			case crcType:
-				crc := decoder.crc.Sum32()
-				// current crc of decoder must match the crc of the record.
-				// do no need to match 0 crc, since the decoder is a new one at this case.
-				if crc != 0 && rec.Validate(crc) != nil {
-					return false
-				}
-				decoder.updateCRC(rec.Crc)
-			}
-			continue
-		case io.EOF:
-			return true
-		case io.ErrUnexpectedEOF:
-			plog.Noticef("repairing %v", f.Name())
-			bf, bferr := os.Create(f.Name() + ".broken")
-			if bferr != nil {
-				plog.Errorf("could not repair %v, failed to create backup file", f.Name())
-				return false
-			}
-			defer bf.Close()
-
-			if _, err = f.Seek(0, io.SeekStart); err != nil {
-				plog.Errorf("could not repair %v, failed to read file", f.Name())
-				return false
-			}
-
-			if _, err = io.Copy(bf, f); err != nil {
-				plog.Errorf("could not repair %v, failed to copy file", f.Name())
-				return false
-			}
-
-			if err = f.Truncate(int64(lastOffset)); err != nil {
-				plog.Errorf("could not repair %v, failed to truncate file", f.Name())
-				return false
-			}
-			if err = fileutil.Fsync(f.File); err != nil {
-				plog.Errorf("could not repair %v, failed to sync file", f.Name())
-				return false
-			}
-			return true
-		default:
-			plog.Errorf("could not repair error (%v)", err)
-			return false
-		}
-	}
-}
-
-// openLast opens the last wal file for read and write.
-func openLast(dirpath string) (*fileutil.LockedFile, error) {
-	names, err := readWalNames(dirpath)
-	if err != nil {
-		return nil, err
-	}
-	last := filepath.Join(dirpath, names[len(names)-1])
-	return fileutil.LockFile(last, os.O_RDWR, fileutil.PrivateFileMode)
-}
diff --git a/vendor/github.com/coreos/etcd/wal/util.go b/vendor/github.com/coreos/etcd/wal/util.go
deleted file mode 100644
index 5c56e22..0000000
--- a/vendor/github.com/coreos/etcd/wal/util.go
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package wal
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-
-	"github.com/coreos/etcd/pkg/fileutil"
-)
-
-var (
-	badWalName = errors.New("bad wal name")
-)
-
-func Exist(dirpath string) bool {
-	names, err := fileutil.ReadDir(dirpath)
-	if err != nil {
-		return false
-	}
-	return len(names) != 0
-}
-
-// searchIndex returns the last array index of names whose raft index section is
-// equal to or smaller than the given index.
-// The given names MUST be sorted.
-func searchIndex(names []string, index uint64) (int, bool) {
-	for i := len(names) - 1; i >= 0; i-- {
-		name := names[i]
-		_, curIndex, err := parseWalName(name)
-		if err != nil {
-			plog.Panicf("parse correct name should never fail: %v", err)
-		}
-		if index >= curIndex {
-			return i, true
-		}
-	}
-	return -1, false
-}
-
-// names should have been sorted based on sequence number.
-// isValidSeq checks whether seq increases continuously.
-func isValidSeq(names []string) bool {
-	var lastSeq uint64
-	for _, name := range names {
-		curSeq, _, err := parseWalName(name)
-		if err != nil {
-			plog.Panicf("parse correct name should never fail: %v", err)
-		}
-		if lastSeq != 0 && lastSeq != curSeq-1 {
-			return false
-		}
-		lastSeq = curSeq
-	}
-	return true
-}
-func readWalNames(dirpath string) ([]string, error) {
-	names, err := fileutil.ReadDir(dirpath)
-	if err != nil {
-		return nil, err
-	}
-	wnames := checkWalNames(names)
-	if len(wnames) == 0 {
-		return nil, ErrFileNotFound
-	}
-	return wnames, nil
-}
-
-func checkWalNames(names []string) []string {
-	wnames := make([]string, 0)
-	for _, name := range names {
-		if _, _, err := parseWalName(name); err != nil {
-			// don't complain about left over tmp files
-			if !strings.HasSuffix(name, ".tmp") {
-				plog.Warningf("ignored file %v in wal", name)
-			}
-			continue
-		}
-		wnames = append(wnames, name)
-	}
-	return wnames
-}
-
-func parseWalName(str string) (seq, index uint64, err error) {
-	if !strings.HasSuffix(str, ".wal") {
-		return 0, 0, badWalName
-	}
-	_, err = fmt.Sscanf(str, "%016x-%016x.wal", &seq, &index)
-	return seq, index, err
-}
-
-func walName(seq, index uint64) string {
-	return fmt.Sprintf("%016x-%016x.wal", seq, index)
-}
diff --git a/vendor/github.com/coreos/etcd/wal/wal.go b/vendor/github.com/coreos/etcd/wal/wal.go
deleted file mode 100644
index 96d01a2..0000000
--- a/vendor/github.com/coreos/etcd/wal/wal.go
+++ /dev/null
@@ -1,675 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package wal
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"hash/crc32"
-	"io"
-	"os"
-	"path/filepath"
-	"sync"
-	"time"
-
-	"github.com/coreos/etcd/pkg/fileutil"
-	"github.com/coreos/etcd/pkg/pbutil"
-	"github.com/coreos/etcd/raft"
-	"github.com/coreos/etcd/raft/raftpb"
-	"github.com/coreos/etcd/wal/walpb"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-const (
-	metadataType int64 = iota + 1
-	entryType
-	stateType
-	crcType
-	snapshotType
-
-	// warnSyncDuration is the amount of time allotted to an fsync before
-	// logging a warning
-	warnSyncDuration = time.Second
-)
-
-var (
-	// SegmentSizeBytes is the preallocated size of each wal segment file.
-	// The actual size might be larger than this. In general, the default
-	// value should be used, but this is defined as an exported variable
-	// so that tests can set a different segment size.
-	SegmentSizeBytes int64 = 64 * 1000 * 1000 // 64MB
-
-	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "wal")
-
-	ErrMetadataConflict = errors.New("wal: conflicting metadata found")
-	ErrFileNotFound     = errors.New("wal: file not found")
-	ErrCRCMismatch      = errors.New("wal: crc mismatch")
-	ErrSnapshotMismatch = errors.New("wal: snapshot mismatch")
-	ErrSnapshotNotFound = errors.New("wal: snapshot not found")
-	crcTable            = crc32.MakeTable(crc32.Castagnoli)
-)
-
-// WAL is a logical representation of the stable storage.
-// WAL is either in read mode or append mode but not both.
-// A newly created WAL is in append mode, and ready for appending records.
-// A just opened WAL is in read mode, and ready for reading records.
-// The WAL will be ready for appending after reading out all the previous records.
-type WAL struct {
-	dir string // the living directory of the underlay files
-
-	// dirFile is a fd for the wal directory for syncing on Rename
-	dirFile *os.File
-
-	metadata []byte           // metadata recorded at the head of each WAL
-	state    raftpb.HardState // hardstate recorded at the head of WAL
-
-	start     walpb.Snapshot // snapshot to start reading
-	decoder   *decoder       // decoder to decode records
-	readClose func() error   // closer for decode reader
-
-	mu      sync.Mutex
-	enti    uint64   // index of the last entry saved to the wal
-	encoder *encoder // encoder to encode records
-
-	locks []*fileutil.LockedFile // the locked files the WAL holds (the name is increasing)
-	fp    *filePipeline
-}
-
-// Create creates a WAL ready for appending records. The given metadata is
-// recorded at the head of each WAL file, and can be retrieved with ReadAll.
-func Create(dirpath string, metadata []byte) (*WAL, error) {
-	if Exist(dirpath) {
-		return nil, os.ErrExist
-	}
-
-	// keep temporary wal directory so WAL initialization appears atomic
-	tmpdirpath := filepath.Clean(dirpath) + ".tmp"
-	if fileutil.Exist(tmpdirpath) {
-		if err := os.RemoveAll(tmpdirpath); err != nil {
-			return nil, err
-		}
-	}
-	if err := fileutil.CreateDirAll(tmpdirpath); err != nil {
-		return nil, err
-	}
-
-	p := filepath.Join(tmpdirpath, walName(0, 0))
-	f, err := fileutil.LockFile(p, os.O_WRONLY|os.O_CREATE, fileutil.PrivateFileMode)
-	if err != nil {
-		return nil, err
-	}
-	if _, err = f.Seek(0, io.SeekEnd); err != nil {
-		return nil, err
-	}
-	if err = fileutil.Preallocate(f.File, SegmentSizeBytes, true); err != nil {
-		return nil, err
-	}
-
-	w := &WAL{
-		dir:      dirpath,
-		metadata: metadata,
-	}
-	w.encoder, err = newFileEncoder(f.File, 0)
-	if err != nil {
-		return nil, err
-	}
-	w.locks = append(w.locks, f)
-	if err = w.saveCrc(0); err != nil {
-		return nil, err
-	}
-	if err = w.encoder.encode(&walpb.Record{Type: metadataType, Data: metadata}); err != nil {
-		return nil, err
-	}
-	if err = w.SaveSnapshot(walpb.Snapshot{}); err != nil {
-		return nil, err
-	}
-
-	if w, err = w.renameWal(tmpdirpath); err != nil {
-		return nil, err
-	}
-
-	// directory was renamed; sync parent dir to persist rename
-	pdir, perr := fileutil.OpenDir(filepath.Dir(w.dir))
-	if perr != nil {
-		return nil, perr
-	}
-	if perr = fileutil.Fsync(pdir); perr != nil {
-		return nil, perr
-	}
-	if perr = pdir.Close(); err != nil {
-		return nil, perr
-	}
-
-	return w, nil
-}
-
-func (w *WAL) renameWal(tmpdirpath string) (*WAL, error) {
-	if err := os.RemoveAll(w.dir); err != nil {
-		return nil, err
-	}
-	// On non-Windows platforms, hold the lock while renaming. Releasing
-	// the lock and trying to reacquire it quickly can be flaky because
-	// it's possible the process will fork to spawn a process while this is
-	// happening. The fds are set up as close-on-exec by the Go runtime,
-	// but there is a window between the fork and the exec where another
-	// process holds the lock.
-	if err := os.Rename(tmpdirpath, w.dir); err != nil {
-		if _, ok := err.(*os.LinkError); ok {
-			return w.renameWalUnlock(tmpdirpath)
-		}
-		return nil, err
-	}
-	w.fp = newFilePipeline(w.dir, SegmentSizeBytes)
-	df, err := fileutil.OpenDir(w.dir)
-	w.dirFile = df
-	return w, err
-}
-
-func (w *WAL) renameWalUnlock(tmpdirpath string) (*WAL, error) {
-	// rename of directory with locked files doesn't work on windows/cifs;
-	// close the WAL to release the locks so the directory can be renamed.
-	plog.Infof("releasing file lock to rename %q to %q", tmpdirpath, w.dir)
-	w.Close()
-	if err := os.Rename(tmpdirpath, w.dir); err != nil {
-		return nil, err
-	}
-	// reopen and relock
-	newWAL, oerr := Open(w.dir, walpb.Snapshot{})
-	if oerr != nil {
-		return nil, oerr
-	}
-	if _, _, _, err := newWAL.ReadAll(); err != nil {
-		newWAL.Close()
-		return nil, err
-	}
-	return newWAL, nil
-}
-
-// Open opens the WAL at the given snap.
-// The snap SHOULD have been previously saved to the WAL, or the following
-// ReadAll will fail.
-// The returned WAL is ready to read and the first record will be the one after
-// the given snap. The WAL cannot be appended to before reading out all of its
-// previous records.
-func Open(dirpath string, snap walpb.Snapshot) (*WAL, error) {
-	w, err := openAtIndex(dirpath, snap, true)
-	if err != nil {
-		return nil, err
-	}
-	if w.dirFile, err = fileutil.OpenDir(w.dir); err != nil {
-		return nil, err
-	}
-	return w, nil
-}
-
-// OpenForRead only opens the wal files for read.
-// Write on a read only wal panics.
-func OpenForRead(dirpath string, snap walpb.Snapshot) (*WAL, error) {
-	return openAtIndex(dirpath, snap, false)
-}
-
-func openAtIndex(dirpath string, snap walpb.Snapshot, write bool) (*WAL, error) {
-	names, err := readWalNames(dirpath)
-	if err != nil {
-		return nil, err
-	}
-
-	nameIndex, ok := searchIndex(names, snap.Index)
-	if !ok || !isValidSeq(names[nameIndex:]) {
-		return nil, ErrFileNotFound
-	}
-
-	// open the wal files
-	rcs := make([]io.ReadCloser, 0)
-	rs := make([]io.Reader, 0)
-	ls := make([]*fileutil.LockedFile, 0)
-	for _, name := range names[nameIndex:] {
-		p := filepath.Join(dirpath, name)
-		if write {
-			l, err := fileutil.TryLockFile(p, os.O_RDWR, fileutil.PrivateFileMode)
-			if err != nil {
-				closeAll(rcs...)
-				return nil, err
-			}
-			ls = append(ls, l)
-			rcs = append(rcs, l)
-		} else {
-			rf, err := os.OpenFile(p, os.O_RDONLY, fileutil.PrivateFileMode)
-			if err != nil {
-				closeAll(rcs...)
-				return nil, err
-			}
-			ls = append(ls, nil)
-			rcs = append(rcs, rf)
-		}
-		rs = append(rs, rcs[len(rcs)-1])
-	}
-
-	closer := func() error { return closeAll(rcs...) }
-
-	// create a WAL ready for reading
-	w := &WAL{
-		dir:       dirpath,
-		start:     snap,
-		decoder:   newDecoder(rs...),
-		readClose: closer,
-		locks:     ls,
-	}
-
-	if write {
-		// write reuses the file descriptors from read; don't close so
-		// WAL can append without dropping the file lock
-		w.readClose = nil
-		if _, _, err := parseWalName(filepath.Base(w.tail().Name())); err != nil {
-			closer()
-			return nil, err
-		}
-		w.fp = newFilePipeline(w.dir, SegmentSizeBytes)
-	}
-
-	return w, nil
-}
-
-// ReadAll reads out records of the current WAL.
-// If opened in write mode, it must read out all records until EOF. Or an error
-// will be returned.
-// If opened in read mode, it will try to read all records if possible.
-// If it cannot read out the expected snap, it will return ErrSnapshotNotFound.
-// If loaded snap doesn't match with the expected one, it will return
-// all the records and error ErrSnapshotMismatch.
-// TODO: detect not-last-snap error.
-// TODO: maybe loose the checking of match.
-// After ReadAll, the WAL will be ready for appending new records.
-func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb.Entry, err error) {
-	w.mu.Lock()
-	defer w.mu.Unlock()
-
-	rec := &walpb.Record{}
-	decoder := w.decoder
-
-	var match bool
-	for err = decoder.decode(rec); err == nil; err = decoder.decode(rec) {
-		switch rec.Type {
-		case entryType:
-			e := mustUnmarshalEntry(rec.Data)
-			if e.Index > w.start.Index {
-				ents = append(ents[:e.Index-w.start.Index-1], e)
-			}
-			w.enti = e.Index
-		case stateType:
-			state = mustUnmarshalState(rec.Data)
-		case metadataType:
-			if metadata != nil && !bytes.Equal(metadata, rec.Data) {
-				state.Reset()
-				return nil, state, nil, ErrMetadataConflict
-			}
-			metadata = rec.Data
-		case crcType:
-			crc := decoder.crc.Sum32()
-			// current crc of decoder must match the crc of the record.
-			// do no need to match 0 crc, since the decoder is a new one at this case.
-			if crc != 0 && rec.Validate(crc) != nil {
-				state.Reset()
-				return nil, state, nil, ErrCRCMismatch
-			}
-			decoder.updateCRC(rec.Crc)
-		case snapshotType:
-			var snap walpb.Snapshot
-			pbutil.MustUnmarshal(&snap, rec.Data)
-			if snap.Index == w.start.Index {
-				if snap.Term != w.start.Term {
-					state.Reset()
-					return nil, state, nil, ErrSnapshotMismatch
-				}
-				match = true
-			}
-		default:
-			state.Reset()
-			return nil, state, nil, fmt.Errorf("unexpected block type %d", rec.Type)
-		}
-	}
-
-	switch w.tail() {
-	case nil:
-		// We do not have to read out all entries in read mode.
-		// The last record maybe a partial written one, so
-		// ErrunexpectedEOF might be returned.
-		if err != io.EOF && err != io.ErrUnexpectedEOF {
-			state.Reset()
-			return nil, state, nil, err
-		}
-	default:
-		// We must read all of the entries if WAL is opened in write mode.
-		if err != io.EOF {
-			state.Reset()
-			return nil, state, nil, err
-		}
-		// decodeRecord() will return io.EOF if it detects a zero record,
-		// but this zero record may be followed by non-zero records from
-		// a torn write. Overwriting some of these non-zero records, but
-		// not all, will cause CRC errors on WAL open. Since the records
-		// were never fully synced to disk in the first place, it's safe
-		// to zero them out to avoid any CRC errors from new writes.
-		if _, err = w.tail().Seek(w.decoder.lastOffset(), io.SeekStart); err != nil {
-			return nil, state, nil, err
-		}
-		if err = fileutil.ZeroToEnd(w.tail().File); err != nil {
-			return nil, state, nil, err
-		}
-	}
-
-	err = nil
-	if !match {
-		err = ErrSnapshotNotFound
-	}
-
-	// close decoder, disable reading
-	if w.readClose != nil {
-		w.readClose()
-		w.readClose = nil
-	}
-	w.start = walpb.Snapshot{}
-
-	w.metadata = metadata
-
-	if w.tail() != nil {
-		// create encoder (chain crc with the decoder), enable appending
-		w.encoder, err = newFileEncoder(w.tail().File, w.decoder.lastCRC())
-		if err != nil {
-			return
-		}
-	}
-	w.decoder = nil
-
-	return metadata, state, ents, err
-}
-
-// cut closes current file written and creates a new one ready to append.
-// cut first creates a temp wal file and writes necessary headers into it.
-// Then cut atomically rename temp wal file to a wal file.
-func (w *WAL) cut() error {
-	// close old wal file; truncate to avoid wasting space if an early cut
-	off, serr := w.tail().Seek(0, io.SeekCurrent)
-	if serr != nil {
-		return serr
-	}
-	if err := w.tail().Truncate(off); err != nil {
-		return err
-	}
-	if err := w.sync(); err != nil {
-		return err
-	}
-
-	fpath := filepath.Join(w.dir, walName(w.seq()+1, w.enti+1))
-
-	// create a temp wal file with name sequence + 1, or truncate the existing one
-	newTail, err := w.fp.Open()
-	if err != nil {
-		return err
-	}
-
-	// update writer and save the previous crc
-	w.locks = append(w.locks, newTail)
-	prevCrc := w.encoder.crc.Sum32()
-	w.encoder, err = newFileEncoder(w.tail().File, prevCrc)
-	if err != nil {
-		return err
-	}
-	if err = w.saveCrc(prevCrc); err != nil {
-		return err
-	}
-	if err = w.encoder.encode(&walpb.Record{Type: metadataType, Data: w.metadata}); err != nil {
-		return err
-	}
-	if err = w.saveState(&w.state); err != nil {
-		return err
-	}
-	// atomically move temp wal file to wal file
-	if err = w.sync(); err != nil {
-		return err
-	}
-
-	off, err = w.tail().Seek(0, io.SeekCurrent)
-	if err != nil {
-		return err
-	}
-
-	if err = os.Rename(newTail.Name(), fpath); err != nil {
-		return err
-	}
-	if err = fileutil.Fsync(w.dirFile); err != nil {
-		return err
-	}
-
-	// reopen newTail with its new path so calls to Name() match the wal filename format
-	newTail.Close()
-
-	if newTail, err = fileutil.LockFile(fpath, os.O_WRONLY, fileutil.PrivateFileMode); err != nil {
-		return err
-	}
-	if _, err = newTail.Seek(off, io.SeekStart); err != nil {
-		return err
-	}
-
-	w.locks[len(w.locks)-1] = newTail
-
-	prevCrc = w.encoder.crc.Sum32()
-	w.encoder, err = newFileEncoder(w.tail().File, prevCrc)
-	if err != nil {
-		return err
-	}
-
-	plog.Infof("segmented wal file %v is created", fpath)
-	return nil
-}
-
-func (w *WAL) sync() error {
-	if w.encoder != nil {
-		if err := w.encoder.flush(); err != nil {
-			return err
-		}
-	}
-	start := time.Now()
-	err := fileutil.Fdatasync(w.tail().File)
-
-	duration := time.Since(start)
-	if duration > warnSyncDuration {
-		plog.Warningf("sync duration of %v, expected less than %v", duration, warnSyncDuration)
-	}
-	syncDurations.Observe(duration.Seconds())
-
-	return err
-}
-
-// ReleaseLockTo releases the locks, which has smaller index than the given index
-// except the largest one among them.
-// For example, if WAL is holding lock 1,2,3,4,5,6, ReleaseLockTo(4) will release
-// lock 1,2 but keep 3. ReleaseLockTo(5) will release 1,2,3 but keep 4.
-func (w *WAL) ReleaseLockTo(index uint64) error {
-	w.mu.Lock()
-	defer w.mu.Unlock()
-
-	if len(w.locks) == 0 {
-		return nil
-	}
-
-	var smaller int
-	found := false
-
-	for i, l := range w.locks {
-		_, lockIndex, err := parseWalName(filepath.Base(l.Name()))
-		if err != nil {
-			return err
-		}
-		if lockIndex >= index {
-			smaller = i - 1
-			found = true
-			break
-		}
-	}
-
-	// if no lock index is greater than the release index, we can
-	// release lock up to the last one(excluding).
-	if !found {
-		smaller = len(w.locks) - 1
-	}
-
-	if smaller <= 0 {
-		return nil
-	}
-
-	for i := 0; i < smaller; i++ {
-		if w.locks[i] == nil {
-			continue
-		}
-		w.locks[i].Close()
-	}
-	w.locks = w.locks[smaller:]
-
-	return nil
-}
-
-func (w *WAL) Close() error {
-	w.mu.Lock()
-	defer w.mu.Unlock()
-
-	if w.fp != nil {
-		w.fp.Close()
-		w.fp = nil
-	}
-
-	if w.tail() != nil {
-		if err := w.sync(); err != nil {
-			return err
-		}
-	}
-	for _, l := range w.locks {
-		if l == nil {
-			continue
-		}
-		if err := l.Close(); err != nil {
-			plog.Errorf("failed to unlock during closing wal: %s", err)
-		}
-	}
-
-	return w.dirFile.Close()
-}
-
-func (w *WAL) saveEntry(e *raftpb.Entry) error {
-	// TODO: add MustMarshalTo to reduce one allocation.
-	b := pbutil.MustMarshal(e)
-	rec := &walpb.Record{Type: entryType, Data: b}
-	if err := w.encoder.encode(rec); err != nil {
-		return err
-	}
-	w.enti = e.Index
-	return nil
-}
-
-func (w *WAL) saveState(s *raftpb.HardState) error {
-	if raft.IsEmptyHardState(*s) {
-		return nil
-	}
-	w.state = *s
-	b := pbutil.MustMarshal(s)
-	rec := &walpb.Record{Type: stateType, Data: b}
-	return w.encoder.encode(rec)
-}
-
-func (w *WAL) Save(st raftpb.HardState, ents []raftpb.Entry) error {
-	w.mu.Lock()
-	defer w.mu.Unlock()
-
-	// short cut, do not call sync
-	if raft.IsEmptyHardState(st) && len(ents) == 0 {
-		return nil
-	}
-
-	mustSync := raft.MustSync(st, w.state, len(ents))
-
-	// TODO(xiangli): no more reference operator
-	for i := range ents {
-		if err := w.saveEntry(&ents[i]); err != nil {
-			return err
-		}
-	}
-	if err := w.saveState(&st); err != nil {
-		return err
-	}
-
-	curOff, err := w.tail().Seek(0, io.SeekCurrent)
-	if err != nil {
-		return err
-	}
-	if curOff < SegmentSizeBytes {
-		if mustSync {
-			return w.sync()
-		}
-		return nil
-	}
-
-	return w.cut()
-}
-
-func (w *WAL) SaveSnapshot(e walpb.Snapshot) error {
-	b := pbutil.MustMarshal(&e)
-
-	w.mu.Lock()
-	defer w.mu.Unlock()
-
-	rec := &walpb.Record{Type: snapshotType, Data: b}
-	if err := w.encoder.encode(rec); err != nil {
-		return err
-	}
-	// update enti only when snapshot is ahead of last index
-	if w.enti < e.Index {
-		w.enti = e.Index
-	}
-	return w.sync()
-}
-
-func (w *WAL) saveCrc(prevCrc uint32) error {
-	return w.encoder.encode(&walpb.Record{Type: crcType, Crc: prevCrc})
-}
-
-func (w *WAL) tail() *fileutil.LockedFile {
-	if len(w.locks) > 0 {
-		return w.locks[len(w.locks)-1]
-	}
-	return nil
-}
-
-func (w *WAL) seq() uint64 {
-	t := w.tail()
-	if t == nil {
-		return 0
-	}
-	seq, _, err := parseWalName(filepath.Base(t.Name()))
-	if err != nil {
-		plog.Fatalf("bad wal name %s (%v)", t.Name(), err)
-	}
-	return seq
-}
-
-func closeAll(rcs ...io.ReadCloser) error {
-	for _, f := range rcs {
-		if err := f.Close(); err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/coreos/etcd/wal/walpb/record.go b/vendor/github.com/coreos/etcd/wal/walpb/record.go
deleted file mode 100644
index 30a05e0..0000000
--- a/vendor/github.com/coreos/etcd/wal/walpb/record.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package walpb
-
-import "errors"
-
-var (
-	ErrCRCMismatch = errors.New("walpb: crc mismatch")
-)
-
-func (rec *Record) Validate(crc uint32) error {
-	if rec.Crc == crc {
-		return nil
-	}
-	rec.Reset()
-	return ErrCRCMismatch
-}
diff --git a/vendor/github.com/coreos/etcd/wal/walpb/record.proto b/vendor/github.com/coreos/etcd/wal/walpb/record.proto
deleted file mode 100644
index b694cb2..0000000
--- a/vendor/github.com/coreos/etcd/wal/walpb/record.proto
+++ /dev/null
@@ -1,20 +0,0 @@
-syntax = "proto2";
-package walpb;
-
-import "gogoproto/gogo.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.sizer_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-option (gogoproto.goproto_getters_all) = false;
-
-message Record {
-	optional int64 type  = 1 [(gogoproto.nullable) = false];
-	optional uint32 crc  = 2 [(gogoproto.nullable) = false];
-	optional bytes data  = 3;
-}
-
-message Snapshot {
-	optional uint64 index = 1 [(gogoproto.nullable) = false];
-	optional uint64 term  = 2 [(gogoproto.nullable) = false];
-}
diff --git a/vendor/github.com/coreos/go-semver/LICENSE b/vendor/github.com/coreos/go-semver/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/vendor/github.com/coreos/go-semver/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/go-semver/semver/semver.go
deleted file mode 100644
index 110fc23..0000000
--- a/vendor/github.com/coreos/go-semver/semver/semver.go
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2013-2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Semantic Versions http://semver.org
-package semver
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"strconv"
-	"strings"
-)
-
-type Version struct {
-	Major      int64
-	Minor      int64
-	Patch      int64
-	PreRelease PreRelease
-	Metadata   string
-}
-
-type PreRelease string
-
-func splitOff(input *string, delim string) (val string) {
-	parts := strings.SplitN(*input, delim, 2)
-
-	if len(parts) == 2 {
-		*input = parts[0]
-		val = parts[1]
-	}
-
-	return val
-}
-
-func New(version string) *Version {
-	return Must(NewVersion(version))
-}
-
-func NewVersion(version string) (*Version, error) {
-	v := Version{}
-
-	if err := v.Set(version); err != nil {
-		return nil, err
-	}
-
-	return &v, nil
-}
-
-// Must is a helper for wrapping NewVersion and will panic if err is not nil.
-func Must(v *Version, err error) *Version {
-	if err != nil {
-		panic(err)
-	}
-	return v
-}
-
-// Set parses and updates v from the given version string. Implements flag.Value
-func (v *Version) Set(version string) error {
-	metadata := splitOff(&version, "+")
-	preRelease := PreRelease(splitOff(&version, "-"))
-	dotParts := strings.SplitN(version, ".", 3)
-
-	if len(dotParts) != 3 {
-		return fmt.Errorf("%s is not in dotted-tri format", version)
-	}
-
-	parsed := make([]int64, 3, 3)
-
-	for i, v := range dotParts[:3] {
-		val, err := strconv.ParseInt(v, 10, 64)
-		parsed[i] = val
-		if err != nil {
-			return err
-		}
-	}
-
-	v.Metadata = metadata
-	v.PreRelease = preRelease
-	v.Major = parsed[0]
-	v.Minor = parsed[1]
-	v.Patch = parsed[2]
-	return nil
-}
-
-func (v Version) String() string {
-	var buffer bytes.Buffer
-
-	fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch)
-
-	if v.PreRelease != "" {
-		fmt.Fprintf(&buffer, "-%s", v.PreRelease)
-	}
-
-	if v.Metadata != "" {
-		fmt.Fprintf(&buffer, "+%s", v.Metadata)
-	}
-
-	return buffer.String()
-}
-
-func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) error {
-	var data string
-	if err := unmarshal(&data); err != nil {
-		return err
-	}
-	return v.Set(data)
-}
-
-func (v Version) MarshalJSON() ([]byte, error) {
-	return []byte(`"` + v.String() + `"`), nil
-}
-
-func (v *Version) UnmarshalJSON(data []byte) error {
-	l := len(data)
-	if l == 0 || string(data) == `""` {
-		return nil
-	}
-	if l < 2 || data[0] != '"' || data[l-1] != '"' {
-		return errors.New("invalid semver string")
-	}
-	return v.Set(string(data[1 : l-1]))
-}
-
-// Compare tests if v is less than, equal to, or greater than versionB,
-// returning -1, 0, or +1 respectively.
-func (v Version) Compare(versionB Version) int {
-	if cmp := recursiveCompare(v.Slice(), versionB.Slice()); cmp != 0 {
-		return cmp
-	}
-	return preReleaseCompare(v, versionB)
-}
-
-// Equal tests if v is equal to versionB.
-func (v Version) Equal(versionB Version) bool {
-	return v.Compare(versionB) == 0
-}
-
-// LessThan tests if v is less than versionB.
-func (v Version) LessThan(versionB Version) bool {
-	return v.Compare(versionB) < 0
-}
-
-// Slice converts the comparable parts of the semver into a slice of integers.
-func (v Version) Slice() []int64 {
-	return []int64{v.Major, v.Minor, v.Patch}
-}
-
-func (p PreRelease) Slice() []string {
-	preRelease := string(p)
-	return strings.Split(preRelease, ".")
-}
-
-func preReleaseCompare(versionA Version, versionB Version) int {
-	a := versionA.PreRelease
-	b := versionB.PreRelease
-
-	/* Handle the case where if two versions are otherwise equal it is the
-	 * one without a PreRelease that is greater */
-	if len(a) == 0 && (len(b) > 0) {
-		return 1
-	} else if len(b) == 0 && (len(a) > 0) {
-		return -1
-	}
-
-	// If there is a prerelease, check and compare each part.
-	return recursivePreReleaseCompare(a.Slice(), b.Slice())
-}
-
-func recursiveCompare(versionA []int64, versionB []int64) int {
-	if len(versionA) == 0 {
-		return 0
-	}
-
-	a := versionA[0]
-	b := versionB[0]
-
-	if a > b {
-		return 1
-	} else if a < b {
-		return -1
-	}
-
-	return recursiveCompare(versionA[1:], versionB[1:])
-}
-
-func recursivePreReleaseCompare(versionA []string, versionB []string) int {
-	// A larger set of pre-release fields has a higher precedence than a smaller set,
-	// if all of the preceding identifiers are equal.
-	if len(versionA) == 0 {
-		if len(versionB) > 0 {
-			return -1
-		}
-		return 0
-	} else if len(versionB) == 0 {
-		// We're longer than versionB so return 1.
-		return 1
-	}
-
-	a := versionA[0]
-	b := versionB[0]
-
-	aInt := false
-	bInt := false
-
-	aI, err := strconv.Atoi(versionA[0])
-	if err == nil {
-		aInt = true
-	}
-
-	bI, err := strconv.Atoi(versionB[0])
-	if err == nil {
-		bInt = true
-	}
-
-	// Handle Integer Comparison
-	if aInt && bInt {
-		if aI > bI {
-			return 1
-		} else if aI < bI {
-			return -1
-		}
-	}
-
-	// Handle String Comparison
-	if a > b {
-		return 1
-	} else if a < b {
-		return -1
-	}
-
-	return recursivePreReleaseCompare(versionA[1:], versionB[1:])
-}
-
-// BumpMajor increments the Major field by 1 and resets all other fields to their default values
-func (v *Version) BumpMajor() {
-	v.Major += 1
-	v.Minor = 0
-	v.Patch = 0
-	v.PreRelease = PreRelease("")
-	v.Metadata = ""
-}
-
-// BumpMinor increments the Minor field by 1 and resets all other fields to their default values
-func (v *Version) BumpMinor() {
-	v.Minor += 1
-	v.Patch = 0
-	v.PreRelease = PreRelease("")
-	v.Metadata = ""
-}
-
-// BumpPatch increments the Patch field by 1 and resets all other fields to their default values
-func (v *Version) BumpPatch() {
-	v.Patch += 1
-	v.PreRelease = PreRelease("")
-	v.Metadata = ""
-}
diff --git a/vendor/github.com/coreos/go-semver/semver/sort.go b/vendor/github.com/coreos/go-semver/semver/sort.go
deleted file mode 100644
index e256b41..0000000
--- a/vendor/github.com/coreos/go-semver/semver/sort.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2013-2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package semver
-
-import (
-	"sort"
-)
-
-type Versions []*Version
-
-func (s Versions) Len() int {
-	return len(s)
-}
-
-func (s Versions) Swap(i, j int) {
-	s[i], s[j] = s[j], s[i]
-}
-
-func (s Versions) Less(i, j int) bool {
-	return s[i].LessThan(*s[j])
-}
-
-// Sort sorts the given slice of Version
-func Sort(versions []*Version) {
-	sort.Sort(Versions(versions))
-}
diff --git a/vendor/github.com/coreos/go-systemd/LICENSE b/vendor/github.com/coreos/go-systemd/LICENSE
deleted file mode 100644
index 37ec93a..0000000
--- a/vendor/github.com/coreos/go-systemd/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-Apache License
-Version 2.0, January 2004
-http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-"License" shall mean the terms and conditions for use, reproduction, and
-distribution as defined by Sections 1 through 9 of this document.
-
-"Licensor" shall mean the copyright owner or entity authorized by the copyright
-owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities
-that control, are controlled by, or are under common control with that entity.
-For the purposes of this definition, "control" means (i) the power, direct or
-indirect, to cause the direction or management of such entity, whether by
-contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
-outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising
-permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including
-but not limited to software source code, documentation source, and configuration
-files.
-
-"Object" form shall mean any form resulting from mechanical transformation or
-translation of a Source form, including but not limited to compiled object code,
-generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made
-available under the License, as indicated by a copyright notice that is included
-in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that
-is based on (or derived from) the Work and for which the editorial revisions,
-annotations, elaborations, or other modifications represent, as a whole, an
-original work of authorship. For the purposes of this License, Derivative Works
-shall not include works that remain separable from, or merely link (or bind by
-name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version
-of the Work and any modifications or additions to that Work or Derivative Works
-thereof, that is intentionally submitted to Licensor for inclusion in the Work
-by the copyright owner or by an individual or Legal Entity authorized to submit
-on behalf of the copyright owner. For the purposes of this definition,
-"submitted" means any form of electronic, verbal, or written communication sent
-to the Licensor or its representatives, including but not limited to
-communication on electronic mailing lists, source code control systems, and
-issue tracking systems that are managed by, or on behalf of, the Licensor for
-the purpose of discussing and improving the Work, but excluding communication
-that is conspicuously marked or otherwise designated in writing by the copyright
-owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
-of whom a Contribution has been received by Licensor and subsequently
-incorporated within the Work.
-
-2. Grant of Copyright License.
-
-Subject to the terms and conditions of this License, each Contributor hereby
-grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
-irrevocable copyright license to reproduce, prepare Derivative Works of,
-publicly display, publicly perform, sublicense, and distribute the Work and such
-Derivative Works in Source or Object form.
-
-3. Grant of Patent License.
-
-Subject to the terms and conditions of this License, each Contributor hereby
-grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
-irrevocable (except as stated in this section) patent license to make, have
-made, use, offer to sell, sell, import, and otherwise transfer the Work, where
-such license applies only to those patent claims licensable by such Contributor
-that are necessarily infringed by their Contribution(s) alone or by combination
-of their Contribution(s) with the Work to which such Contribution(s) was
-submitted. If You institute patent litigation against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that the Work or a
-Contribution incorporated within the Work constitutes direct or contributory
-patent infringement, then any patent licenses granted to You under this License
-for that Work shall terminate as of the date such litigation is filed.
-
-4. Redistribution.
-
-You may reproduce and distribute copies of the Work or Derivative Works thereof
-in any medium, with or without modifications, and in Source or Object form,
-provided that You meet the following conditions:
-
-You must give any other recipients of the Work or Derivative Works a copy of
-this License; and
-You must cause any modified files to carry prominent notices stating that You
-changed the files; and
-You must retain, in the Source form of any Derivative Works that You distribute,
-all copyright, patent, trademark, and attribution notices from the Source form
-of the Work, excluding those notices that do not pertain to any part of the
-Derivative Works; and
-If the Work includes a "NOTICE" text file as part of its distribution, then any
-Derivative Works that You distribute must include a readable copy of the
-attribution notices contained within such NOTICE file, excluding those notices
-that do not pertain to any part of the Derivative Works, in at least one of the
-following places: within a NOTICE text file distributed as part of the
-Derivative Works; within the Source form or documentation, if provided along
-with the Derivative Works; or, within a display generated by the Derivative
-Works, if and wherever such third-party notices normally appear. The contents of
-the NOTICE file are for informational purposes only and do not modify the
-License. You may add Your own attribution notices within Derivative Works that
-You distribute, alongside or as an addendum to the NOTICE text from the Work,
-provided that such additional attribution notices cannot be construed as
-modifying the License.
-You may add Your own copyright statement to Your modifications and may provide
-additional or different license terms and conditions for use, reproduction, or
-distribution of Your modifications, or for any such Derivative Works as a whole,
-provided Your use, reproduction, and distribution of the Work otherwise complies
-with the conditions stated in this License.
-
-5. Submission of Contributions.
-
-Unless You explicitly state otherwise, any Contribution intentionally submitted
-for inclusion in the Work by You to the Licensor shall be under the terms and
-conditions of this License, without any additional terms or conditions.
-Notwithstanding the above, nothing herein shall supersede or modify the terms of
-any separate license agreement you may have executed with Licensor regarding
-such Contributions.
-
-6. Trademarks.
-
-This License does not grant permission to use the trade names, trademarks,
-service marks, or product names of the Licensor, except as required for
-reasonable and customary use in describing the origin of the Work and
-reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty.
-
-Unless required by applicable law or agreed to in writing, Licensor provides the
-Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
-including, without limitation, any warranties or conditions of TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
-solely responsible for determining the appropriateness of using or
-redistributing the Work and assume any risks associated with Your exercise of
-permissions under this License.
-
-8. Limitation of Liability.
-
-In no event and under no legal theory, whether in tort (including negligence),
-contract, or otherwise, unless required by applicable law (such as deliberate
-and grossly negligent acts) or agreed to in writing, shall any Contributor be
-liable to You for damages, including any direct, indirect, special, incidental,
-or consequential damages of any character arising as a result of this License or
-out of the use or inability to use the Work (including but not limited to
-damages for loss of goodwill, work stoppage, computer failure or malfunction, or
-any and all other commercial damages or losses), even if such Contributor has
-been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability.
-
-While redistributing the Work or Derivative Works thereof, You may choose to
-offer, and charge a fee for, acceptance of support, warranty, indemnity, or
-other liability obligations and/or rights consistent with this License. However,
-in accepting such obligations, You may act only on Your own behalf and on Your
-sole responsibility, not on behalf of any other Contributor, and only if You
-agree to indemnify, defend, and hold each Contributor harmless for any liability
-incurred by, or claims asserted against, such Contributor by reason of your
-accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work
-
-To apply the Apache License to your work, attach the following boilerplate
-notice, with the fields enclosed by brackets "[]" replaced with your own
-identifying information. (Don't include the brackets!) The text should be
-enclosed in the appropriate comment syntax for the file format. We also
-recommend that a file or class name and description of purpose be included on
-the same "printed page" as the copyright notice for easier identification within
-third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/coreos/go-systemd/NOTICE b/vendor/github.com/coreos/go-systemd/NOTICE
deleted file mode 100644
index 23a0ada..0000000
--- a/vendor/github.com/coreos/go-systemd/NOTICE
+++ /dev/null
@@ -1,5 +0,0 @@
-CoreOS Project
-Copyright 2018 CoreOS, Inc
-
-This product includes software developed at CoreOS, Inc.
-(http://www.coreos.com/).
diff --git a/vendor/github.com/coreos/go-systemd/daemon/sdnotify.go b/vendor/github.com/coreos/go-systemd/daemon/sdnotify.go
deleted file mode 100644
index ba4ae31..0000000
--- a/vendor/github.com/coreos/go-systemd/daemon/sdnotify.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2014 Docker, Inc.
-// Copyright 2015-2018 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-// Package daemon provides a Go implementation of the sd_notify protocol.
-// It can be used to inform systemd of service start-up completion, watchdog
-// events, and other status changes.
-//
-// https://www.freedesktop.org/software/systemd/man/sd_notify.html#Description
-package daemon
-
-import (
-	"net"
-	"os"
-)
-
-const (
-	// SdNotifyReady tells the service manager that service startup is finished
-	// or the service finished loading its configuration.
-	SdNotifyReady = "READY=1"
-
-	// SdNotifyStopping tells the service manager that the service is beginning
-	// its shutdown.
-	SdNotifyStopping = "STOPPING=1"
-
-	// SdNotifyReloading tells the service manager that this service is
-	// reloading its configuration. Note that you must call SdNotifyReady when
-	// it completed reloading.
-	SdNotifyReloading = "RELOADING=1"
-
-	// SdNotifyWatchdog tells the service manager to update the watchdog
-	// timestamp for the service.
-	SdNotifyWatchdog = "WATCHDOG=1"
-)
-
-// SdNotify sends a message to the init daemon. It is common to ignore the error.
-// If `unsetEnvironment` is true, the environment variable `NOTIFY_SOCKET`
-// will be unconditionally unset.
-//
-// It returns one of the following:
-// (false, nil) - notification not supported (i.e. NOTIFY_SOCKET is unset)
-// (false, err) - notification supported, but failure happened (e.g. error connecting to NOTIFY_SOCKET or while sending data)
-// (true, nil) - notification supported, data has been sent
-func SdNotify(unsetEnvironment bool, state string) (bool, error) {
-	socketAddr := &net.UnixAddr{
-		Name: os.Getenv("NOTIFY_SOCKET"),
-		Net:  "unixgram",
-	}
-
-	// NOTIFY_SOCKET not set
-	if socketAddr.Name == "" {
-		return false, nil
-	}
-
-	if unsetEnvironment {
-		if err := os.Unsetenv("NOTIFY_SOCKET"); err != nil {
-			return false, err
-		}
-	}
-
-	conn, err := net.DialUnix(socketAddr.Net, nil, socketAddr)
-	// Error connecting to NOTIFY_SOCKET
-	if err != nil {
-		return false, err
-	}
-	defer conn.Close()
-
-	if _, err = conn.Write([]byte(state)); err != nil {
-		return false, err
-	}
-	return true, nil
-}
diff --git a/vendor/github.com/coreos/go-systemd/daemon/watchdog.go b/vendor/github.com/coreos/go-systemd/daemon/watchdog.go
deleted file mode 100644
index 7a0e0d3..0000000
--- a/vendor/github.com/coreos/go-systemd/daemon/watchdog.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2016 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package daemon
-
-import (
-	"fmt"
-	"os"
-	"strconv"
-	"time"
-)
-
-// SdWatchdogEnabled returns watchdog information for a service.
-// Processes should call daemon.SdNotify(false, daemon.SdNotifyWatchdog) every
-// time / 2.
-// If `unsetEnvironment` is true, the environment variables `WATCHDOG_USEC` and
-// `WATCHDOG_PID` will be unconditionally unset.
-//
-// It returns one of the following:
-// (0, nil) - watchdog isn't enabled or we aren't the watched PID.
-// (0, err) - an error happened (e.g. error converting time).
-// (time, nil) - watchdog is enabled and we can send ping.
-//   time is delay before inactive service will be killed.
-func SdWatchdogEnabled(unsetEnvironment bool) (time.Duration, error) {
-	wusec := os.Getenv("WATCHDOG_USEC")
-	wpid := os.Getenv("WATCHDOG_PID")
-	if unsetEnvironment {
-		wusecErr := os.Unsetenv("WATCHDOG_USEC")
-		wpidErr := os.Unsetenv("WATCHDOG_PID")
-		if wusecErr != nil {
-			return 0, wusecErr
-		}
-		if wpidErr != nil {
-			return 0, wpidErr
-		}
-	}
-
-	if wusec == "" {
-		return 0, nil
-	}
-	s, err := strconv.Atoi(wusec)
-	if err != nil {
-		return 0, fmt.Errorf("error converting WATCHDOG_USEC: %s", err)
-	}
-	if s <= 0 {
-		return 0, fmt.Errorf("error WATCHDOG_USEC must be a positive number")
-	}
-	interval := time.Duration(s) * time.Microsecond
-
-	if wpid == "" {
-		return interval, nil
-	}
-	p, err := strconv.Atoi(wpid)
-	if err != nil {
-		return 0, fmt.Errorf("error converting WATCHDOG_PID: %s", err)
-	}
-	if os.Getpid() != p {
-		return 0, nil
-	}
-
-	return interval, nil
-}
diff --git a/vendor/github.com/coreos/go-systemd/journal/journal.go b/vendor/github.com/coreos/go-systemd/journal/journal.go
deleted file mode 100644
index 603ad4c..0000000
--- a/vendor/github.com/coreos/go-systemd/journal/journal.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package journal provides write bindings to the local systemd journal.
-// It is implemented in pure Go and connects to the journal directly over its
-// unix socket.
-//
-// To read from the journal, see the "sdjournal" package, which wraps the
-// sd-journal a C API.
-//
-// http://www.freedesktop.org/software/systemd/man/systemd-journald.service.html
-package journal
-
-import (
-	"bytes"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net"
-	"os"
-	"strconv"
-	"strings"
-	"syscall"
-)
-
-// Priority of a journal message
-type Priority int
-
-const (
-	PriEmerg Priority = iota
-	PriAlert
-	PriCrit
-	PriErr
-	PriWarning
-	PriNotice
-	PriInfo
-	PriDebug
-)
-
-var conn net.Conn
-
-func init() {
-	var err error
-	conn, err = net.Dial("unixgram", "/run/systemd/journal/socket")
-	if err != nil {
-		conn = nil
-	}
-}
-
-// Enabled returns true if the local systemd journal is available for logging
-func Enabled() bool {
-	return conn != nil
-}
-
-// Send a message to the local systemd journal. vars is a map of journald
-// fields to values.  Fields must be composed of uppercase letters, numbers,
-// and underscores, but must not start with an underscore. Within these
-// restrictions, any arbitrary field name may be used.  Some names have special
-// significance: see the journalctl documentation
-// (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html)
-// for more details.  vars may be nil.
-func Send(message string, priority Priority, vars map[string]string) error {
-	if conn == nil {
-		return journalError("could not connect to journald socket")
-	}
-
-	data := new(bytes.Buffer)
-	appendVariable(data, "PRIORITY", strconv.Itoa(int(priority)))
-	appendVariable(data, "MESSAGE", message)
-	for k, v := range vars {
-		appendVariable(data, k, v)
-	}
-
-	_, err := io.Copy(conn, data)
-	if err != nil && isSocketSpaceError(err) {
-		file, err := tempFd()
-		if err != nil {
-			return journalError(err.Error())
-		}
-		defer file.Close()
-		_, err = io.Copy(file, data)
-		if err != nil {
-			return journalError(err.Error())
-		}
-
-		rights := syscall.UnixRights(int(file.Fd()))
-
-		/* this connection should always be a UnixConn, but better safe than sorry */
-		unixConn, ok := conn.(*net.UnixConn)
-		if !ok {
-			return journalError("can't send file through non-Unix connection")
-		}
-		_, _, err = unixConn.WriteMsgUnix([]byte{}, rights, nil)
-		if err != nil {
-			return journalError(err.Error())
-		}
-	} else if err != nil {
-		return journalError(err.Error())
-	}
-	return nil
-}
-
-// Print prints a message to the local systemd journal using Send().
-func Print(priority Priority, format string, a ...interface{}) error {
-	return Send(fmt.Sprintf(format, a...), priority, nil)
-}
-
-func appendVariable(w io.Writer, name, value string) {
-	if err := validVarName(name); err != nil {
-		journalError(err.Error())
-	}
-	if strings.ContainsRune(value, '\n') {
-		/* When the value contains a newline, we write:
-		 * - the variable name, followed by a newline
-		 * - the size (in 64bit little endian format)
-		 * - the data, followed by a newline
-		 */
-		fmt.Fprintln(w, name)
-		binary.Write(w, binary.LittleEndian, uint64(len(value)))
-		fmt.Fprintln(w, value)
-	} else {
-		/* just write the variable and value all on one line */
-		fmt.Fprintf(w, "%s=%s\n", name, value)
-	}
-}
-
-// validVarName validates a variable name to make sure it journald will accept it.
-// The variable name must be in uppercase and consist only of characters,
-// numbers and underscores, and may not begin with an underscore. (from the docs)
-// https://www.freedesktop.org/software/systemd/man/sd_journal_print.html
-func validVarName(name string) error {
-	if name == "" {
-		return errors.New("Empty variable name")
-	} else if name[0] == '_' {
-		return errors.New("Variable name begins with an underscore")
-	}
-
-	for _, c := range name {
-		if !(('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_') {
-			return errors.New("Variable name contains invalid characters")
-		}
-	}
-	return nil
-}
-
-func isSocketSpaceError(err error) bool {
-	opErr, ok := err.(*net.OpError)
-	if !ok {
-		return false
-	}
-
-	sysErr, ok := opErr.Err.(syscall.Errno)
-	if !ok {
-		return false
-	}
-
-	return sysErr == syscall.EMSGSIZE || sysErr == syscall.ENOBUFS
-}
-
-func tempFd() (*os.File, error) {
-	file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX")
-	if err != nil {
-		return nil, err
-	}
-	err = syscall.Unlink(file.Name())
-	if err != nil {
-		return nil, err
-	}
-	return file, nil
-}
-
-func journalError(s string) error {
-	s = "journal error: " + s
-	fmt.Fprintln(os.Stderr, s)
-	return errors.New(s)
-}
diff --git a/vendor/github.com/coreos/go-systemd/util/util.go b/vendor/github.com/coreos/go-systemd/util/util.go
deleted file mode 100644
index 7828ce6..0000000
--- a/vendor/github.com/coreos/go-systemd/util/util.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package util contains utility functions related to systemd that applications
-// can use to check things like whether systemd is running.  Note that some of
-// these functions attempt to manually load systemd libraries at runtime rather
-// than linking against them.
-package util
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"strings"
-)
-
-var (
-	ErrNoCGO = fmt.Errorf("go-systemd built with CGO disabled")
-)
-
-// GetRunningSlice attempts to retrieve the name of the systemd slice in which
-// the current process is running.
-// This function is a wrapper around the libsystemd C library; if it cannot be
-// opened, an error is returned.
-func GetRunningSlice() (string, error) {
-	return getRunningSlice()
-}
-
-// RunningFromSystemService tries to detect whether the current process has
-// been invoked from a system service. The condition for this is whether the
-// process is _not_ a user process. User processes are those running in session
-// scopes or under per-user `systemd --user` instances.
-//
-// To avoid false positives on systems without `pam_systemd` (which is
-// responsible for creating user sessions), this function also uses a heuristic
-// to detect whether it's being invoked from a session leader process. This is
-// the case if the current process is executed directly from a service file
-// (e.g. with `ExecStart=/this/cmd`). Note that this heuristic will fail if the
-// command is instead launched in a subshell or similar so that it is not
-// session leader (e.g. `ExecStart=/bin/bash -c "/this/cmd"`)
-//
-// This function is a wrapper around the libsystemd C library; if this is
-// unable to successfully open a handle to the library for any reason (e.g. it
-// cannot be found), an error will be returned.
-func RunningFromSystemService() (bool, error) {
-	return runningFromSystemService()
-}
-
-// CurrentUnitName attempts to retrieve the name of the systemd system unit
-// from which the calling process has been invoked. It wraps the systemd
-// `sd_pid_get_unit` call, with the same caveat: for processes not part of a
-// systemd system unit, this function will return an error.
-func CurrentUnitName() (string, error) {
-	return currentUnitName()
-}
-
-// IsRunningSystemd checks whether the host was booted with systemd as its init
-// system. This functions similarly to systemd's `sd_booted(3)`: internally, it
-// checks whether /run/systemd/system/ exists and is a directory.
-// http://www.freedesktop.org/software/systemd/man/sd_booted.html
-func IsRunningSystemd() bool {
-	fi, err := os.Lstat("/run/systemd/system")
-	if err != nil {
-		return false
-	}
-	return fi.IsDir()
-}
-
-// GetMachineID returns a host's 128-bit machine ID as a string. This functions
-// similarly to systemd's `sd_id128_get_machine`: internally, it simply reads
-// the contents of /etc/machine-id
-// http://www.freedesktop.org/software/systemd/man/sd_id128_get_machine.html
-func GetMachineID() (string, error) {
-	machineID, err := ioutil.ReadFile("/etc/machine-id")
-	if err != nil {
-		return "", fmt.Errorf("failed to read /etc/machine-id: %v", err)
-	}
-	return strings.TrimSpace(string(machineID)), nil
-}
diff --git a/vendor/github.com/coreos/go-systemd/util/util_cgo.go b/vendor/github.com/coreos/go-systemd/util/util_cgo.go
deleted file mode 100644
index 6269bc7..0000000
--- a/vendor/github.com/coreos/go-systemd/util/util_cgo.go
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2016 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build cgo
-
-package util
-
-// #include <stdlib.h>
-// #include <sys/types.h>
-// #include <unistd.h>
-//
-// int
-// my_sd_pid_get_owner_uid(void *f, pid_t pid, uid_t *uid)
-// {
-//   int (*sd_pid_get_owner_uid)(pid_t, uid_t *);
-//
-//   sd_pid_get_owner_uid = (int (*)(pid_t, uid_t *))f;
-//   return sd_pid_get_owner_uid(pid, uid);
-// }
-//
-// int
-// my_sd_pid_get_unit(void *f, pid_t pid, char **unit)
-// {
-//   int (*sd_pid_get_unit)(pid_t, char **);
-//
-//   sd_pid_get_unit = (int (*)(pid_t, char **))f;
-//   return sd_pid_get_unit(pid, unit);
-// }
-//
-// int
-// my_sd_pid_get_slice(void *f, pid_t pid, char **slice)
-// {
-//   int (*sd_pid_get_slice)(pid_t, char **);
-//
-//   sd_pid_get_slice = (int (*)(pid_t, char **))f;
-//   return sd_pid_get_slice(pid, slice);
-// }
-//
-// int
-// am_session_leader()
-// {
-//   return (getsid(0) == getpid());
-// }
-import "C"
-import (
-	"fmt"
-	"syscall"
-	"unsafe"
-
-	"github.com/coreos/pkg/dlopen"
-)
-
-var libsystemdNames = []string{
-	// systemd < 209
-	"libsystemd-login.so.0",
-	"libsystemd-login.so",
-
-	// systemd >= 209 merged libsystemd-login into libsystemd proper
-	"libsystemd.so.0",
-	"libsystemd.so",
-}
-
-func getRunningSlice() (slice string, err error) {
-	var h *dlopen.LibHandle
-	h, err = dlopen.GetHandle(libsystemdNames)
-	if err != nil {
-		return
-	}
-	defer func() {
-		if err1 := h.Close(); err1 != nil {
-			err = err1
-		}
-	}()
-
-	sd_pid_get_slice, err := h.GetSymbolPointer("sd_pid_get_slice")
-	if err != nil {
-		return
-	}
-
-	var s string
-	sl := C.CString(s)
-	defer C.free(unsafe.Pointer(sl))
-
-	ret := C.my_sd_pid_get_slice(sd_pid_get_slice, 0, &sl)
-	if ret < 0 {
-		err = fmt.Errorf("error calling sd_pid_get_slice: %v", syscall.Errno(-ret))
-		return
-	}
-
-	return C.GoString(sl), nil
-}
-
-func runningFromSystemService() (ret bool, err error) {
-	var h *dlopen.LibHandle
-	h, err = dlopen.GetHandle(libsystemdNames)
-	if err != nil {
-		return
-	}
-	defer func() {
-		if err1 := h.Close(); err1 != nil {
-			err = err1
-		}
-	}()
-
-	sd_pid_get_owner_uid, err := h.GetSymbolPointer("sd_pid_get_owner_uid")
-	if err != nil {
-		return
-	}
-
-	var uid C.uid_t
-	errno := C.my_sd_pid_get_owner_uid(sd_pid_get_owner_uid, 0, &uid)
-	serrno := syscall.Errno(-errno)
-	// when we're running from a unit file, sd_pid_get_owner_uid returns
-	// ENOENT (systemd <220), ENXIO (systemd 220-223), or ENODATA
-	// (systemd >=234)
-	switch {
-	case errno >= 0:
-		ret = false
-	case serrno == syscall.ENOENT, serrno == syscall.ENXIO, serrno == syscall.ENODATA:
-		// Since the implementation of sessions in systemd relies on
-		// the `pam_systemd` module, using the sd_pid_get_owner_uid
-		// heuristic alone can result in false positives if that module
-		// (or PAM itself) is not present or properly configured on the
-		// system. As such, we also check if we're the session leader,
-		// which should be the case if we're invoked from a unit file,
-		// but not if e.g. we're invoked from the command line from a
-		// user's login session
-		ret = C.am_session_leader() == 1
-	default:
-		err = fmt.Errorf("error calling sd_pid_get_owner_uid: %v", syscall.Errno(-errno))
-	}
-	return
-}
-
-func currentUnitName() (unit string, err error) {
-	var h *dlopen.LibHandle
-	h, err = dlopen.GetHandle(libsystemdNames)
-	if err != nil {
-		return
-	}
-	defer func() {
-		if err1 := h.Close(); err1 != nil {
-			err = err1
-		}
-	}()
-
-	sd_pid_get_unit, err := h.GetSymbolPointer("sd_pid_get_unit")
-	if err != nil {
-		return
-	}
-
-	var s string
-	u := C.CString(s)
-	defer C.free(unsafe.Pointer(u))
-
-	ret := C.my_sd_pid_get_unit(sd_pid_get_unit, 0, &u)
-	if ret < 0 {
-		err = fmt.Errorf("error calling sd_pid_get_unit: %v", syscall.Errno(-ret))
-		return
-	}
-
-	unit = C.GoString(u)
-	return
-}
diff --git a/vendor/github.com/coreos/go-systemd/util/util_stub.go b/vendor/github.com/coreos/go-systemd/util/util_stub.go
deleted file mode 100644
index 477589e..0000000
--- a/vendor/github.com/coreos/go-systemd/util/util_stub.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2016 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !cgo
-
-package util
-
-func getRunningSlice() (string, error) { return "", ErrNoCGO }
-
-func runningFromSystemService() (bool, error) { return false, ErrNoCGO }
-
-func currentUnitName() (string, error) { return "", ErrNoCGO }
diff --git a/vendor/github.com/coreos/pkg/LICENSE b/vendor/github.com/coreos/pkg/LICENSE
deleted file mode 100644
index e06d208..0000000
--- a/vendor/github.com/coreos/pkg/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "{}"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright {yyyy} {name of copyright owner}
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
diff --git a/vendor/github.com/coreos/pkg/NOTICE b/vendor/github.com/coreos/pkg/NOTICE
deleted file mode 100644
index b39ddfa..0000000
--- a/vendor/github.com/coreos/pkg/NOTICE
+++ /dev/null
@@ -1,5 +0,0 @@
-CoreOS Project
-Copyright 2014 CoreOS, Inc
-
-This product includes software developed at CoreOS, Inc.
-(http://www.coreos.com/).
diff --git a/vendor/github.com/coreos/pkg/capnslog/README.md b/vendor/github.com/coreos/pkg/capnslog/README.md
deleted file mode 100644
index f79dbfc..0000000
--- a/vendor/github.com/coreos/pkg/capnslog/README.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# capnslog, the CoreOS logging package
-
-There are far too many logging packages out there, with varying degrees of licenses, far too many features (colorization, all sorts of log frameworks) or are just a pain to use (lack of `Fatalln()`?).
-capnslog provides a simple but consistent logging interface suitable for all kinds of projects.
-
-### Design Principles
-
-##### `package main` is the place where logging gets turned on and routed
-
-A library should not touch log options, only generate log entries. Libraries are silent until main lets them speak.
-
-##### All log options are runtime-configurable. 
-
-Still the job of `main` to expose these configurations. `main` may delegate this to, say, a configuration webhook, but does so explicitly. 
-
-##### There is one log object per package. It is registered under its repository and package name.
-
-`main` activates logging for its repository and any dependency repositories it would also like to have output in its logstream. `main` also dictates at which level each subpackage logs.
-
-##### There is *one* output stream, and it is an `io.Writer` composed with a formatter.
-
-Splitting streams is probably not the job of your program, but rather, your log aggregation framework. If you must split output streams, again, `main` configures this and you can write a very simple two-output struct that satisfies io.Writer.
-
-Fancy colorful formatting and JSON output are beyond the scope of a basic logging framework -- they're application/log-collector dependent. These are, at best, provided as options, but more likely, provided by your application.
-
-##### Log objects are an interface
-
-An object knows best how to print itself. Log objects can collect more interesting metadata if they wish, however, because text isn't going away anytime soon, they must all be marshalable to text. The simplest log object is a string, which returns itself. If you wish to do more fancy tricks for printing your log objects, see also JSON output -- introspect and write a formatter which can handle your advanced log interface. Making strings is the only thing guaranteed.
-
-##### Log levels have specific meanings:
-
-  * Critical: Unrecoverable. Must fail.
-  * Error: Data has been lost, a request has failed for a bad reason, or a required resource has been lost
-  * Warning: (Hopefully) Temporary conditions that may cause errors, but may work fine. A replica disappearing (that may reconnect) is a warning.
-  * Notice: Normal, but important (uncommon) log information.
-  * Info: Normal, working log information, everything is fine, but helpful notices for auditing or common operations.
-  * Debug: Everything is still fine, but even common operations may be logged, and less helpful but more quantity of notices.
-  * Trace: Anything goes, from logging every function call as part of a common operation, to tracing execution of a query.
-
diff --git a/vendor/github.com/coreos/pkg/capnslog/formatters.go b/vendor/github.com/coreos/pkg/capnslog/formatters.go
deleted file mode 100644
index b305a84..0000000
--- a/vendor/github.com/coreos/pkg/capnslog/formatters.go
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package capnslog
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"log"
-	"runtime"
-	"strings"
-	"time"
-)
-
-type Formatter interface {
-	Format(pkg string, level LogLevel, depth int, entries ...interface{})
-	Flush()
-}
-
-func NewStringFormatter(w io.Writer) Formatter {
-	return &StringFormatter{
-		w: bufio.NewWriter(w),
-	}
-}
-
-type StringFormatter struct {
-	w *bufio.Writer
-}
-
-func (s *StringFormatter) Format(pkg string, l LogLevel, i int, entries ...interface{}) {
-	now := time.Now().UTC()
-	s.w.WriteString(now.Format(time.RFC3339))
-	s.w.WriteByte(' ')
-	writeEntries(s.w, pkg, l, i, entries...)
-	s.Flush()
-}
-
-func writeEntries(w *bufio.Writer, pkg string, _ LogLevel, _ int, entries ...interface{}) {
-	if pkg != "" {
-		w.WriteString(pkg + ": ")
-	}
-	str := fmt.Sprint(entries...)
-	endsInNL := strings.HasSuffix(str, "\n")
-	w.WriteString(str)
-	if !endsInNL {
-		w.WriteString("\n")
-	}
-}
-
-func (s *StringFormatter) Flush() {
-	s.w.Flush()
-}
-
-func NewPrettyFormatter(w io.Writer, debug bool) Formatter {
-	return &PrettyFormatter{
-		w:     bufio.NewWriter(w),
-		debug: debug,
-	}
-}
-
-type PrettyFormatter struct {
-	w     *bufio.Writer
-	debug bool
-}
-
-func (c *PrettyFormatter) Format(pkg string, l LogLevel, depth int, entries ...interface{}) {
-	now := time.Now()
-	ts := now.Format("2006-01-02 15:04:05")
-	c.w.WriteString(ts)
-	ms := now.Nanosecond() / 1000
-	c.w.WriteString(fmt.Sprintf(".%06d", ms))
-	if c.debug {
-		_, file, line, ok := runtime.Caller(depth) // It's always the same number of frames to the user's call.
-		if !ok {
-			file = "???"
-			line = 1
-		} else {
-			slash := strings.LastIndex(file, "/")
-			if slash >= 0 {
-				file = file[slash+1:]
-			}
-		}
-		if line < 0 {
-			line = 0 // not a real line number
-		}
-		c.w.WriteString(fmt.Sprintf(" [%s:%d]", file, line))
-	}
-	c.w.WriteString(fmt.Sprint(" ", l.Char(), " | "))
-	writeEntries(c.w, pkg, l, depth, entries...)
-	c.Flush()
-}
-
-func (c *PrettyFormatter) Flush() {
-	c.w.Flush()
-}
-
-// LogFormatter emulates the form of the traditional built-in logger.
-type LogFormatter struct {
-	logger *log.Logger
-	prefix string
-}
-
-// NewLogFormatter is a helper to produce a new LogFormatter struct. It uses the
-// golang log package to actually do the logging work so that logs look similar.
-func NewLogFormatter(w io.Writer, prefix string, flag int) Formatter {
-	return &LogFormatter{
-		logger: log.New(w, "", flag), // don't use prefix here
-		prefix: prefix,               // save it instead
-	}
-}
-
-// Format builds a log message for the LogFormatter. The LogLevel is ignored.
-func (lf *LogFormatter) Format(pkg string, _ LogLevel, _ int, entries ...interface{}) {
-	str := fmt.Sprint(entries...)
-	prefix := lf.prefix
-	if pkg != "" {
-		prefix = fmt.Sprintf("%s%s: ", prefix, pkg)
-	}
-	lf.logger.Output(5, fmt.Sprintf("%s%v", prefix, str)) // call depth is 5
-}
-
-// Flush is included so that the interface is complete, but is a no-op.
-func (lf *LogFormatter) Flush() {
-	// noop
-}
-
-// NilFormatter is a no-op log formatter that does nothing.
-type NilFormatter struct {
-}
-
-// NewNilFormatter is a helper to produce a new LogFormatter struct. It logs no
-// messages so that you can cause part of your logging to be silent.
-func NewNilFormatter() Formatter {
-	return &NilFormatter{}
-}
-
-// Format does nothing.
-func (_ *NilFormatter) Format(_ string, _ LogLevel, _ int, _ ...interface{}) {
-	// noop
-}
-
-// Flush is included so that the interface is complete, but is a no-op.
-func (_ *NilFormatter) Flush() {
-	// noop
-}
diff --git a/vendor/github.com/coreos/pkg/capnslog/glog_formatter.go b/vendor/github.com/coreos/pkg/capnslog/glog_formatter.go
deleted file mode 100644
index 426603e..0000000
--- a/vendor/github.com/coreos/pkg/capnslog/glog_formatter.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package capnslog
-
-import (
-	"bufio"
-	"bytes"
-	"io"
-	"os"
-	"runtime"
-	"strconv"
-	"strings"
-	"time"
-)
-
-var pid = os.Getpid()
-
-type GlogFormatter struct {
-	StringFormatter
-}
-
-func NewGlogFormatter(w io.Writer) *GlogFormatter {
-	g := &GlogFormatter{}
-	g.w = bufio.NewWriter(w)
-	return g
-}
-
-func (g GlogFormatter) Format(pkg string, level LogLevel, depth int, entries ...interface{}) {
-	g.w.Write(GlogHeader(level, depth+1))
-	g.StringFormatter.Format(pkg, level, depth+1, entries...)
-}
-
-func GlogHeader(level LogLevel, depth int) []byte {
-	// Lmmdd hh:mm:ss.uuuuuu threadid file:line]
-	now := time.Now().UTC()
-	_, file, line, ok := runtime.Caller(depth) // It's always the same number of frames to the user's call.
-	if !ok {
-		file = "???"
-		line = 1
-	} else {
-		slash := strings.LastIndex(file, "/")
-		if slash >= 0 {
-			file = file[slash+1:]
-		}
-	}
-	if line < 0 {
-		line = 0 // not a real line number
-	}
-	buf := &bytes.Buffer{}
-	buf.Grow(30)
-	_, month, day := now.Date()
-	hour, minute, second := now.Clock()
-	buf.WriteString(level.Char())
-	twoDigits(buf, int(month))
-	twoDigits(buf, day)
-	buf.WriteByte(' ')
-	twoDigits(buf, hour)
-	buf.WriteByte(':')
-	twoDigits(buf, minute)
-	buf.WriteByte(':')
-	twoDigits(buf, second)
-	buf.WriteByte('.')
-	buf.WriteString(strconv.Itoa(now.Nanosecond() / 1000))
-	buf.WriteByte('Z')
-	buf.WriteByte(' ')
-	buf.WriteString(strconv.Itoa(pid))
-	buf.WriteByte(' ')
-	buf.WriteString(file)
-	buf.WriteByte(':')
-	buf.WriteString(strconv.Itoa(line))
-	buf.WriteByte(']')
-	buf.WriteByte(' ')
-	return buf.Bytes()
-}
-
-const digits = "0123456789"
-
-func twoDigits(b *bytes.Buffer, d int) {
-	c2 := digits[d%10]
-	d /= 10
-	c1 := digits[d%10]
-	b.WriteByte(c1)
-	b.WriteByte(c2)
-}
diff --git a/vendor/github.com/coreos/pkg/capnslog/init.go b/vendor/github.com/coreos/pkg/capnslog/init.go
deleted file mode 100644
index 44b8cd3..0000000
--- a/vendor/github.com/coreos/pkg/capnslog/init.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// +build !windows
-
-package capnslog
-
-import (
-	"io"
-	"os"
-	"syscall"
-)
-
-// Here's where the opinionation comes in. We need some sensible defaults,
-// especially after taking over the log package. Your project (whatever it may
-// be) may see things differently. That's okay; there should be no defaults in
-// the main package that cannot be controlled or overridden programatically,
-// otherwise it's a bug. Doing so is creating your own init_log.go file much
-// like this one.
-
-func init() {
-	initHijack()
-
-	// Go `log` pacakge uses os.Stderr.
-	SetFormatter(NewDefaultFormatter(os.Stderr))
-	SetGlobalLogLevel(INFO)
-}
-
-func NewDefaultFormatter(out io.Writer) Formatter {
-	if syscall.Getppid() == 1 {
-		// We're running under init, which may be systemd.
-		f, err := NewJournaldFormatter()
-		if err == nil {
-			return f
-		}
-	}
-	return NewPrettyFormatter(out, false)
-}
diff --git a/vendor/github.com/coreos/pkg/capnslog/init_windows.go b/vendor/github.com/coreos/pkg/capnslog/init_windows.go
deleted file mode 100644
index 4553050..0000000
--- a/vendor/github.com/coreos/pkg/capnslog/init_windows.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package capnslog
-
-import "os"
-
-func init() {
-	initHijack()
-
-	// Go `log` package uses os.Stderr.
-	SetFormatter(NewPrettyFormatter(os.Stderr, false))
-	SetGlobalLogLevel(INFO)
-}
diff --git a/vendor/github.com/coreos/pkg/capnslog/journald_formatter.go b/vendor/github.com/coreos/pkg/capnslog/journald_formatter.go
deleted file mode 100644
index 72e0520..0000000
--- a/vendor/github.com/coreos/pkg/capnslog/journald_formatter.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// +build !windows
-
-package capnslog
-
-import (
-	"errors"
-	"fmt"
-	"os"
-	"path/filepath"
-
-	"github.com/coreos/go-systemd/journal"
-)
-
-func NewJournaldFormatter() (Formatter, error) {
-	if !journal.Enabled() {
-		return nil, errors.New("No systemd detected")
-	}
-	return &journaldFormatter{}, nil
-}
-
-type journaldFormatter struct{}
-
-func (j *journaldFormatter) Format(pkg string, l LogLevel, _ int, entries ...interface{}) {
-	var pri journal.Priority
-	switch l {
-	case CRITICAL:
-		pri = journal.PriCrit
-	case ERROR:
-		pri = journal.PriErr
-	case WARNING:
-		pri = journal.PriWarning
-	case NOTICE:
-		pri = journal.PriNotice
-	case INFO:
-		pri = journal.PriInfo
-	case DEBUG:
-		pri = journal.PriDebug
-	case TRACE:
-		pri = journal.PriDebug
-	default:
-		panic("Unhandled loglevel")
-	}
-	msg := fmt.Sprint(entries...)
-	tags := map[string]string{
-		"PACKAGE":           pkg,
-		"SYSLOG_IDENTIFIER": filepath.Base(os.Args[0]),
-	}
-	err := journal.Send(msg, pri, tags)
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-	}
-}
-
-func (j *journaldFormatter) Flush() {}
diff --git a/vendor/github.com/coreos/pkg/capnslog/log_hijack.go b/vendor/github.com/coreos/pkg/capnslog/log_hijack.go
deleted file mode 100644
index 970086b..0000000
--- a/vendor/github.com/coreos/pkg/capnslog/log_hijack.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package capnslog
-
-import (
-	"log"
-)
-
-func initHijack() {
-	pkg := NewPackageLogger("log", "")
-	w := packageWriter{pkg}
-	log.SetFlags(0)
-	log.SetPrefix("")
-	log.SetOutput(w)
-}
-
-type packageWriter struct {
-	pl *PackageLogger
-}
-
-func (p packageWriter) Write(b []byte) (int, error) {
-	if p.pl.level < INFO {
-		return 0, nil
-	}
-	p.pl.internalLog(calldepth+2, INFO, string(b))
-	return len(b), nil
-}
diff --git a/vendor/github.com/coreos/pkg/capnslog/logmap.go b/vendor/github.com/coreos/pkg/capnslog/logmap.go
deleted file mode 100644
index 226b60c..0000000
--- a/vendor/github.com/coreos/pkg/capnslog/logmap.go
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package capnslog
-
-import (
-	"errors"
-	"strings"
-	"sync"
-)
-
-// LogLevel is the set of all log levels.
-type LogLevel int8
-
-const (
-	// CRITICAL is the lowest log level; only errors which will end the program will be propagated.
-	CRITICAL LogLevel = iota - 1
-	// ERROR is for errors that are not fatal but lead to troubling behavior.
-	ERROR
-	// WARNING is for errors which are not fatal and not errors, but are unusual. Often sourced from misconfigurations.
-	WARNING
-	// NOTICE is for normal but significant conditions.
-	NOTICE
-	// INFO is a log level for common, everyday log updates.
-	INFO
-	// DEBUG is the default hidden level for more verbose updates about internal processes.
-	DEBUG
-	// TRACE is for (potentially) call by call tracing of programs.
-	TRACE
-)
-
-// Char returns a single-character representation of the log level.
-func (l LogLevel) Char() string {
-	switch l {
-	case CRITICAL:
-		return "C"
-	case ERROR:
-		return "E"
-	case WARNING:
-		return "W"
-	case NOTICE:
-		return "N"
-	case INFO:
-		return "I"
-	case DEBUG:
-		return "D"
-	case TRACE:
-		return "T"
-	default:
-		panic("Unhandled loglevel")
-	}
-}
-
-// String returns a multi-character representation of the log level.
-func (l LogLevel) String() string {
-	switch l {
-	case CRITICAL:
-		return "CRITICAL"
-	case ERROR:
-		return "ERROR"
-	case WARNING:
-		return "WARNING"
-	case NOTICE:
-		return "NOTICE"
-	case INFO:
-		return "INFO"
-	case DEBUG:
-		return "DEBUG"
-	case TRACE:
-		return "TRACE"
-	default:
-		panic("Unhandled loglevel")
-	}
-}
-
-// Update using the given string value. Fulfills the flag.Value interface.
-func (l *LogLevel) Set(s string) error {
-	value, err := ParseLevel(s)
-	if err != nil {
-		return err
-	}
-
-	*l = value
-	return nil
-}
-
-// Returns an empty string, only here to fulfill the pflag.Value interface.
-func (l *LogLevel) Type() string {
-	return ""
-}
-
-// ParseLevel translates some potential loglevel strings into their corresponding levels.
-func ParseLevel(s string) (LogLevel, error) {
-	switch s {
-	case "CRITICAL", "C":
-		return CRITICAL, nil
-	case "ERROR", "0", "E":
-		return ERROR, nil
-	case "WARNING", "1", "W":
-		return WARNING, nil
-	case "NOTICE", "2", "N":
-		return NOTICE, nil
-	case "INFO", "3", "I":
-		return INFO, nil
-	case "DEBUG", "4", "D":
-		return DEBUG, nil
-	case "TRACE", "5", "T":
-		return TRACE, nil
-	}
-	return CRITICAL, errors.New("couldn't parse log level " + s)
-}
-
-type RepoLogger map[string]*PackageLogger
-
-type loggerStruct struct {
-	sync.Mutex
-	repoMap   map[string]RepoLogger
-	formatter Formatter
-}
-
-// logger is the global logger
-var logger = new(loggerStruct)
-
-// SetGlobalLogLevel sets the log level for all packages in all repositories
-// registered with capnslog.
-func SetGlobalLogLevel(l LogLevel) {
-	logger.Lock()
-	defer logger.Unlock()
-	for _, r := range logger.repoMap {
-		r.setRepoLogLevelInternal(l)
-	}
-}
-
-// GetRepoLogger may return the handle to the repository's set of packages' loggers.
-func GetRepoLogger(repo string) (RepoLogger, error) {
-	logger.Lock()
-	defer logger.Unlock()
-	r, ok := logger.repoMap[repo]
-	if !ok {
-		return nil, errors.New("no packages registered for repo " + repo)
-	}
-	return r, nil
-}
-
-// MustRepoLogger returns the handle to the repository's packages' loggers.
-func MustRepoLogger(repo string) RepoLogger {
-	r, err := GetRepoLogger(repo)
-	if err != nil {
-		panic(err)
-	}
-	return r
-}
-
-// SetRepoLogLevel sets the log level for all packages in the repository.
-func (r RepoLogger) SetRepoLogLevel(l LogLevel) {
-	logger.Lock()
-	defer logger.Unlock()
-	r.setRepoLogLevelInternal(l)
-}
-
-func (r RepoLogger) setRepoLogLevelInternal(l LogLevel) {
-	for _, v := range r {
-		v.level = l
-	}
-}
-
-// ParseLogLevelConfig parses a comma-separated string of "package=loglevel", in
-// order, and returns a map of the results, for use in SetLogLevel.
-func (r RepoLogger) ParseLogLevelConfig(conf string) (map[string]LogLevel, error) {
-	setlist := strings.Split(conf, ",")
-	out := make(map[string]LogLevel)
-	for _, setstring := range setlist {
-		setting := strings.Split(setstring, "=")
-		if len(setting) != 2 {
-			return nil, errors.New("oddly structured `pkg=level` option: " + setstring)
-		}
-		l, err := ParseLevel(setting[1])
-		if err != nil {
-			return nil, err
-		}
-		out[setting[0]] = l
-	}
-	return out, nil
-}
-
-// SetLogLevel takes a map of package names within a repository to their desired
-// loglevel, and sets the levels appropriately. Unknown packages are ignored.
-// "*" is a special package name that corresponds to all packages, and will be
-// processed first.
-func (r RepoLogger) SetLogLevel(m map[string]LogLevel) {
-	logger.Lock()
-	defer logger.Unlock()
-	if l, ok := m["*"]; ok {
-		r.setRepoLogLevelInternal(l)
-	}
-	for k, v := range m {
-		l, ok := r[k]
-		if !ok {
-			continue
-		}
-		l.level = v
-	}
-}
-
-// SetFormatter sets the formatting function for all logs.
-func SetFormatter(f Formatter) {
-	logger.Lock()
-	defer logger.Unlock()
-	logger.formatter = f
-}
-
-// NewPackageLogger creates a package logger object.
-// This should be defined as a global var in your package, referencing your repo.
-func NewPackageLogger(repo string, pkg string) (p *PackageLogger) {
-	logger.Lock()
-	defer logger.Unlock()
-	if logger.repoMap == nil {
-		logger.repoMap = make(map[string]RepoLogger)
-	}
-	r, rok := logger.repoMap[repo]
-	if !rok {
-		logger.repoMap[repo] = make(RepoLogger)
-		r = logger.repoMap[repo]
-	}
-	p, pok := r[pkg]
-	if !pok {
-		r[pkg] = &PackageLogger{
-			pkg:   pkg,
-			level: INFO,
-		}
-		p = r[pkg]
-	}
-	return
-}
diff --git a/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go b/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go
deleted file mode 100644
index 00ff371..0000000
--- a/vendor/github.com/coreos/pkg/capnslog/pkg_logger.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package capnslog
-
-import (
-	"fmt"
-	"os"
-)
-
-type PackageLogger struct {
-	pkg   string
-	level LogLevel
-}
-
-const calldepth = 2
-
-func (p *PackageLogger) internalLog(depth int, inLevel LogLevel, entries ...interface{}) {
-	logger.Lock()
-	defer logger.Unlock()
-	if inLevel != CRITICAL && p.level < inLevel {
-		return
-	}
-	if logger.formatter != nil {
-		logger.formatter.Format(p.pkg, inLevel, depth+1, entries...)
-	}
-}
-
-// SetLevel allows users to change the current logging level.
-func (p *PackageLogger) SetLevel(l LogLevel) {
-	logger.Lock()
-	defer logger.Unlock()
-	p.level = l
-}
-
-// LevelAt checks if the given log level will be outputted under current setting.
-func (p *PackageLogger) LevelAt(l LogLevel) bool {
-	logger.Lock()
-	defer logger.Unlock()
-	return p.level >= l
-}
-
-// Log a formatted string at any level between ERROR and TRACE
-func (p *PackageLogger) Logf(l LogLevel, format string, args ...interface{}) {
-	p.internalLog(calldepth, l, fmt.Sprintf(format, args...))
-}
-
-// Log a message at any level between ERROR and TRACE
-func (p *PackageLogger) Log(l LogLevel, args ...interface{}) {
-	p.internalLog(calldepth, l, fmt.Sprint(args...))
-}
-
-// log stdlib compatibility
-
-func (p *PackageLogger) Println(args ...interface{}) {
-	p.internalLog(calldepth, INFO, fmt.Sprintln(args...))
-}
-
-func (p *PackageLogger) Printf(format string, args ...interface{}) {
-	p.Logf(INFO, format, args...)
-}
-
-func (p *PackageLogger) Print(args ...interface{}) {
-	p.internalLog(calldepth, INFO, fmt.Sprint(args...))
-}
-
-// Panic and fatal
-
-func (p *PackageLogger) Panicf(format string, args ...interface{}) {
-	s := fmt.Sprintf(format, args...)
-	p.internalLog(calldepth, CRITICAL, s)
-	panic(s)
-}
-
-func (p *PackageLogger) Panic(args ...interface{}) {
-	s := fmt.Sprint(args...)
-	p.internalLog(calldepth, CRITICAL, s)
-	panic(s)
-}
-
-func (p *PackageLogger) Panicln(args ...interface{}) {
-	s := fmt.Sprintln(args...)
-	p.internalLog(calldepth, CRITICAL, s)
-	panic(s)
-}
-
-func (p *PackageLogger) Fatalf(format string, args ...interface{}) {
-	p.Logf(CRITICAL, format, args...)
-	os.Exit(1)
-}
-
-func (p *PackageLogger) Fatal(args ...interface{}) {
-	s := fmt.Sprint(args...)
-	p.internalLog(calldepth, CRITICAL, s)
-	os.Exit(1)
-}
-
-func (p *PackageLogger) Fatalln(args ...interface{}) {
-	s := fmt.Sprintln(args...)
-	p.internalLog(calldepth, CRITICAL, s)
-	os.Exit(1)
-}
-
-// Error Functions
-
-func (p *PackageLogger) Errorf(format string, args ...interface{}) {
-	p.Logf(ERROR, format, args...)
-}
-
-func (p *PackageLogger) Error(entries ...interface{}) {
-	p.internalLog(calldepth, ERROR, entries...)
-}
-
-// Warning Functions
-
-func (p *PackageLogger) Warningf(format string, args ...interface{}) {
-	p.Logf(WARNING, format, args...)
-}
-
-func (p *PackageLogger) Warning(entries ...interface{}) {
-	p.internalLog(calldepth, WARNING, entries...)
-}
-
-// Notice Functions
-
-func (p *PackageLogger) Noticef(format string, args ...interface{}) {
-	p.Logf(NOTICE, format, args...)
-}
-
-func (p *PackageLogger) Notice(entries ...interface{}) {
-	p.internalLog(calldepth, NOTICE, entries...)
-}
-
-// Info Functions
-
-func (p *PackageLogger) Infof(format string, args ...interface{}) {
-	p.Logf(INFO, format, args...)
-}
-
-func (p *PackageLogger) Info(entries ...interface{}) {
-	p.internalLog(calldepth, INFO, entries...)
-}
-
-// Debug Functions
-
-func (p *PackageLogger) Debugf(format string, args ...interface{}) {
-	if p.level < DEBUG {
-		return
-	}
-	p.Logf(DEBUG, format, args...)
-}
-
-func (p *PackageLogger) Debug(entries ...interface{}) {
-	if p.level < DEBUG {
-		return
-	}
-	p.internalLog(calldepth, DEBUG, entries...)
-}
-
-// Trace Functions
-
-func (p *PackageLogger) Tracef(format string, args ...interface{}) {
-	if p.level < TRACE {
-		return
-	}
-	p.Logf(TRACE, format, args...)
-}
-
-func (p *PackageLogger) Trace(entries ...interface{}) {
-	if p.level < TRACE {
-		return
-	}
-	p.internalLog(calldepth, TRACE, entries...)
-}
-
-func (p *PackageLogger) Flush() {
-	logger.Lock()
-	defer logger.Unlock()
-	logger.formatter.Flush()
-}
diff --git a/vendor/github.com/coreos/pkg/capnslog/syslog_formatter.go b/vendor/github.com/coreos/pkg/capnslog/syslog_formatter.go
deleted file mode 100644
index 4be5a1f..0000000
--- a/vendor/github.com/coreos/pkg/capnslog/syslog_formatter.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// +build !windows
-
-package capnslog
-
-import (
-	"fmt"
-	"log/syslog"
-)
-
-func NewSyslogFormatter(w *syslog.Writer) Formatter {
-	return &syslogFormatter{w}
-}
-
-func NewDefaultSyslogFormatter(tag string) (Formatter, error) {
-	w, err := syslog.New(syslog.LOG_DEBUG, tag)
-	if err != nil {
-		return nil, err
-	}
-	return NewSyslogFormatter(w), nil
-}
-
-type syslogFormatter struct {
-	w *syslog.Writer
-}
-
-func (s *syslogFormatter) Format(pkg string, l LogLevel, _ int, entries ...interface{}) {
-	for _, entry := range entries {
-		str := fmt.Sprint(entry)
-		switch l {
-		case CRITICAL:
-			s.w.Crit(str)
-		case ERROR:
-			s.w.Err(str)
-		case WARNING:
-			s.w.Warning(str)
-		case NOTICE:
-			s.w.Notice(str)
-		case INFO:
-			s.w.Info(str)
-		case DEBUG:
-			s.w.Debug(str)
-		case TRACE:
-			s.w.Debug(str)
-		default:
-			panic("Unhandled loglevel")
-		}
-	}
-}
-
-func (s *syslogFormatter) Flush() {
-}
diff --git a/vendor/github.com/coreos/pkg/dlopen/dlopen.go b/vendor/github.com/coreos/pkg/dlopen/dlopen.go
deleted file mode 100644
index 23774f6..0000000
--- a/vendor/github.com/coreos/pkg/dlopen/dlopen.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2016 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package dlopen provides some convenience functions to dlopen a library and
-// get its symbols.
-package dlopen
-
-// #cgo LDFLAGS: -ldl
-// #include <stdlib.h>
-// #include <dlfcn.h>
-import "C"
-import (
-	"errors"
-	"fmt"
-	"unsafe"
-)
-
-var ErrSoNotFound = errors.New("unable to open a handle to the library")
-
-// LibHandle represents an open handle to a library (.so)
-type LibHandle struct {
-	Handle  unsafe.Pointer
-	Libname string
-}
-
-// GetHandle tries to get a handle to a library (.so), attempting to access it
-// by the names specified in libs and returning the first that is successfully
-// opened. Callers are responsible for closing the handler. If no library can
-// be successfully opened, an error is returned.
-func GetHandle(libs []string) (*LibHandle, error) {
-	for _, name := range libs {
-		libname := C.CString(name)
-		defer C.free(unsafe.Pointer(libname))
-		handle := C.dlopen(libname, C.RTLD_LAZY)
-		if handle != nil {
-			h := &LibHandle{
-				Handle:  handle,
-				Libname: name,
-			}
-			return h, nil
-		}
-	}
-	return nil, ErrSoNotFound
-}
-
-// GetSymbolPointer takes a symbol name and returns a pointer to the symbol.
-func (l *LibHandle) GetSymbolPointer(symbol string) (unsafe.Pointer, error) {
-	sym := C.CString(symbol)
-	defer C.free(unsafe.Pointer(sym))
-
-	C.dlerror()
-	p := C.dlsym(l.Handle, sym)
-	e := C.dlerror()
-	if e != nil {
-		return nil, fmt.Errorf("error resolving symbol %q: %v", symbol, errors.New(C.GoString(e)))
-	}
-
-	return p, nil
-}
-
-// Close closes a LibHandle.
-func (l *LibHandle) Close() error {
-	C.dlerror()
-	C.dlclose(l.Handle)
-	e := C.dlerror()
-	if e != nil {
-		return fmt.Errorf("error closing %v: %v", l.Libname, errors.New(C.GoString(e)))
-	}
-
-	return nil
-}
diff --git a/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go b/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go
deleted file mode 100644
index 48a6601..0000000
--- a/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 CoreOS, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// +build linux
-
-package dlopen
-
-// #include <string.h>
-// #include <stdlib.h>
-//
-// int
-// my_strlen(void *f, const char *s)
-// {
-//   size_t (*strlen)(const char *);
-//
-//   strlen = (size_t (*)(const char *))f;
-//   return strlen(s);
-// }
-import "C"
-
-import (
-	"fmt"
-	"unsafe"
-)
-
-func strlen(libs []string, s string) (int, error) {
-	h, err := GetHandle(libs)
-	if err != nil {
-		return -1, fmt.Errorf(`couldn't get a handle to the library: %v`, err)
-	}
-	defer h.Close()
-
-	f := "strlen"
-	cs := C.CString(s)
-	defer C.free(unsafe.Pointer(cs))
-
-	strlen, err := h.GetSymbolPointer(f)
-	if err != nil {
-		return -1, fmt.Errorf(`couldn't get symbol %q: %v`, f, err)
-	}
-
-	len := C.my_strlen(strlen, cs)
-
-	return int(len), nil
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/.gitignore b/vendor/github.com/dgrijalva/jwt-go/.gitignore
deleted file mode 100644
index 80bed65..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.DS_Store
-bin
-
-
diff --git a/vendor/github.com/dgrijalva/jwt-go/.travis.yml b/vendor/github.com/dgrijalva/jwt-go/.travis.yml
deleted file mode 100644
index 1027f56..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/.travis.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-language: go
-
-script:
-    - go vet ./...
-    - go test -v ./...
-
-go:
-  - 1.3
-  - 1.4
-  - 1.5
-  - 1.6
-  - 1.7
-  - tip
diff --git a/vendor/github.com/dgrijalva/jwt-go/LICENSE b/vendor/github.com/dgrijalva/jwt-go/LICENSE
deleted file mode 100644
index df83a9c..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/LICENSE
+++ /dev/null
@@ -1,8 +0,0 @@
-Copyright (c) 2012 Dave Grijalva
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md b/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md
deleted file mode 100644
index 7fc1f79..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md
+++ /dev/null
@@ -1,97 +0,0 @@
-## Migration Guide from v2 -> v3
-
-Version 3 adds several new, frequently requested features.  To do so, it introduces a few breaking changes.  We've worked to keep these as minimal as possible.  This guide explains the breaking changes and how you can quickly update your code.
-
-### `Token.Claims` is now an interface type
-
-The most requested feature from the 2.0 verison of this library was the ability to provide a custom type to the JSON parser for claims. This was implemented by introducing a new interface, `Claims`, to replace `map[string]interface{}`.  We also included two concrete implementations of `Claims`: `MapClaims` and `StandardClaims`.
-
-`MapClaims` is an alias for `map[string]interface{}` with built in validation behavior.  It is the default claims type when using `Parse`.  The usage is unchanged except you must type cast the claims property.
-
-The old example for parsing a token looked like this..
-
-```go
-	if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil {
-		fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"])
-	}
-```
-
-is now directly mapped to...
-
-```go
-	if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil {
-		claims := token.Claims.(jwt.MapClaims)
-		fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"])
-	}
-```
-
-`StandardClaims` is designed to be embedded in your custom type.  You can supply a custom claims type with the new `ParseWithClaims` function.  Here's an example of using a custom claims type.
-
-```go
-	type MyCustomClaims struct {
-		User string
-		*StandardClaims
-	}
-	
-	if token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, keyLookupFunc); err == nil {
-		claims := token.Claims.(*MyCustomClaims)
-		fmt.Printf("Token for user %v expires %v", claims.User, claims.StandardClaims.ExpiresAt)
-	}
-```
-
-### `ParseFromRequest` has been moved
-
-To keep this library focused on the tokens without becoming overburdened with complex request processing logic, `ParseFromRequest` and its new companion `ParseFromRequestWithClaims` have been moved to a subpackage, `request`.  The method signatues have also been augmented to receive a new argument: `Extractor`.
-
-`Extractors` do the work of picking the token string out of a request.  The interface is simple and composable.
-
-This simple parsing example:
-
-```go
-	if token, err := jwt.ParseFromRequest(tokenString, req, keyLookupFunc); err == nil {
-		fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"])
-	}
-```
-
-is directly mapped to:
-
-```go
-	if token, err := request.ParseFromRequest(req, request.OAuth2Extractor, keyLookupFunc); err == nil {
-		claims := token.Claims.(jwt.MapClaims)
-		fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"])
-	}
-```
-
-There are several concrete `Extractor` types provided for your convenience:
-
-* `HeaderExtractor` will search a list of headers until one contains content.
-* `ArgumentExtractor` will search a list of keys in request query and form arguments until one contains content.
-* `MultiExtractor` will try a list of `Extractors` in order until one returns content.
-* `AuthorizationHeaderExtractor` will look in the `Authorization` header for a `Bearer` token.
-* `OAuth2Extractor` searches the places an OAuth2 token would be specified (per the spec): `Authorization` header and `access_token` argument
-* `PostExtractionFilter` wraps an `Extractor`, allowing you to process the content before it's parsed.  A simple example is stripping the `Bearer ` text from a header
-
-
-### RSA signing methods no longer accept `[]byte` keys
-
-Due to a [critical vulnerability](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/), we've decided the convenience of accepting `[]byte` instead of `rsa.PublicKey` or `rsa.PrivateKey` isn't worth the risk of misuse.
-
-To replace this behavior, we've added two helper methods: `ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error)` and `ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error)`.  These are just simple helpers for unpacking PEM encoded PKCS1 and PKCS8 keys. If your keys are encoded any other way, all you need to do is convert them to the `crypto/rsa` package's types.
-
-```go 
-	func keyLookupFunc(*Token) (interface{}, error) {
-		// Don't forget to validate the alg is what you expect:
-		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
-			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
-		}
-		
-		// Look up key 
-		key, err := lookupPublicKey(token.Header["kid"])
-		if err != nil {
-			return nil, err
-		}
-		
-		// Unpack key from PEM encoded PKCS8
-		return jwt.ParseRSAPublicKeyFromPEM(key)
-	}
-```
diff --git a/vendor/github.com/dgrijalva/jwt-go/README.md b/vendor/github.com/dgrijalva/jwt-go/README.md
deleted file mode 100644
index d358d88..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/README.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# jwt-go
-
-[![Build Status](https://travis-ci.org/dgrijalva/jwt-go.svg?branch=master)](https://travis-ci.org/dgrijalva/jwt-go)
-[![GoDoc](https://godoc.org/github.com/dgrijalva/jwt-go?status.svg)](https://godoc.org/github.com/dgrijalva/jwt-go)
-
-A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html)
-
-**NEW VERSION COMING:** There have been a lot of improvements suggested since the version 3.0.0 released in 2016. I'm working now on cutting two different releases: 3.2.0 will contain any non-breaking changes or enhancements. 4.0.0 will follow shortly which will include breaking changes. See the 4.0.0 milestone to get an idea of what's coming. If you have other ideas, or would like to participate in 4.0.0, now's the time. If you depend on this library and don't want to be interrupted, I recommend you use your dependency mangement tool to pin to version 3. 
-
-**SECURITY NOTICE:** Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least 1.8.3. See issue #216 for more detail.
-
-**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage.  See the examples provided.
-
-## What the heck is a JWT?
-
-JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web Tokens.
-
-In short, it's a signed JSON object that does something useful (for example, authentication).  It's commonly used for `Bearer` tokens in Oauth 2.  A token is made of three parts, separated by `.`'s.  The first two parts are JSON objects, that have been [base64url](http://tools.ietf.org/html/rfc4648) encoded.  The last part is the signature, encoded the same way.
-
-The first part is called the header.  It contains the necessary information for verifying the last part, the signature.  For example, which encryption method was used for signing and what key was used.
-
-The part in the middle is the interesting bit.  It's called the Claims and contains the actual stuff you care about.  Refer to [the RFC](http://self-issued.info/docs/draft-jones-json-web-token.html) for information about reserved keys and the proper way to add your own.
-
-## What's in the box?
-
-This library supports the parsing and verification as well as the generation and signing of JWTs.  Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own.
-
-## Examples
-
-See [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) for examples of usage:
-
-* [Simple example of parsing and validating a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac)
-* [Simple example of building and signing a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac)
-* [Directory of Examples](https://godoc.org/github.com/dgrijalva/jwt-go#pkg-examples)
-
-## Extensions
-
-This library publishes all the necessary components for adding your own signing methods.  Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`.  
-
-Here's an example of an extension that integrates with the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go
-
-## Compliance
-
-This library was last reviewed to comply with [RTF 7519](http://www.rfc-editor.org/info/rfc7519) dated May 2015 with a few notable differences:
-
-* In order to protect against accidental use of [Unsecured JWTs](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#UnsecuredJWT), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key.
-
-## Project Status & Versioning
-
-This library is considered production ready.  Feedback and feature requests are appreciated.  The API should be considered stable.  There should be very few backwards-incompatible changes outside of major version updates (and only with good reason).
-
-This project uses [Semantic Versioning 2.0.0](http://semver.org).  Accepted pull requests will land on `master`.  Periodically, versions will be tagged from `master`.  You can find all the releases on [the project releases page](https://github.com/dgrijalva/jwt-go/releases).
-
-While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users.  You may want to use this alternative package include: `gopkg.in/dgrijalva/jwt-go.v3`.  It will do the right thing WRT semantic versioning.
-
-**BREAKING CHANGES:*** 
-* Version 3.0.0 includes _a lot_ of changes from the 2.x line, including a few that break the API.  We've tried to break as few things as possible, so there should just be a few type signature changes.  A full list of breaking changes is available in `VERSION_HISTORY.md`.  See `MIGRATION_GUIDE.md` for more information on updating your code.
-
-## Usage Tips
-
-### Signing vs Encryption
-
-A token is simply a JSON object that is signed by its author. this tells you exactly two things about the data:
-
-* The author of the token was in the possession of the signing secret
-* The data has not been modified since it was signed
-
-It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. JWE is currently outside the scope of this library.
-
-### Choosing a Signing Method
-
-There are several signing methods available, and you should probably take the time to learn about the various options before choosing one.  The principal design decision is most likely going to be symmetric vs asymmetric.
-
-Symmetric signing methods, such as HSA, use only a single secret. This is probably the simplest signing method to use since any `[]byte` can be used as a valid secret. They are also slightly computationally faster to use, though this rarely is enough to matter. Symmetric signing methods work the best when both producers and consumers of tokens are trusted, or even the same system. Since the same secret is used to both sign and validate tokens, you can't easily distribute the key for validation.
-
-Asymmetric signing methods, such as RSA, use different keys for signing and verifying tokens. This makes it possible to produce tokens with a private key, and allow any consumer to access the public key for verification.
-
-### Signing Methods and Key Types
-
-Each signing method expects a different object type for its signing keys. See the package documentation for details. Here are the most common ones:
-
-* The [HMAC signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation
-* The [RSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation
-* The [ECDSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation
-
-### JWT and OAuth
-
-It's worth mentioning that OAuth and JWT are not the same thing. A JWT token is simply a signed JSON object. It can be used anywhere such a thing is useful. There is some confusion, though, as JWT is the most common type of bearer token used in OAuth2 authentication.
-
-Without going too far down the rabbit hole, here's a description of the interaction of these technologies:
-
-* OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth.
-* OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token.
-* Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL.
-
-## More
-
-Documentation can be found [on godoc.org](http://godoc.org/github.com/dgrijalva/jwt-go).
-
-The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in the documentation.
diff --git a/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md b/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md
deleted file mode 100644
index 6370298..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md
+++ /dev/null
@@ -1,118 +0,0 @@
-## `jwt-go` Version History
-
-#### 3.2.0
-
-* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation
-* HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate
-* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before.
-* Deprecated `ParseFromRequestWithClaims` to simplify API in the future.
-
-#### 3.1.0
-
-* Improvements to `jwt` command line tool
-* Added `SkipClaimsValidation` option to `Parser`
-* Documentation updates
-
-#### 3.0.0
-
-* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code
-	* Dropped support for `[]byte` keys when using RSA signing methods.  This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods.
-	* `ParseFromRequest` has been moved to `request` subpackage and usage has changed
-	* The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`.  The default value is type `MapClaims`, which is an alias to `map[string]interface{}`.  This makes it possible to use a custom type when decoding claims.
-* Other Additions and Changes
-	* Added `Claims` interface type to allow users to decode the claims into a custom type
-	* Added `ParseWithClaims`, which takes a third argument of type `Claims`.  Use this function instead of `Parse` if you have a custom type you'd like to decode into.
-	* Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage
-	* Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims`
-	* Added new interface type `Extractor`, which is used for extracting JWT strings from http requests.  Used with `ParseFromRequest` and `ParseFromRequestWithClaims`.
-	* Added several new, more specific, validation errors to error type bitmask
-	* Moved examples from README to executable example files
-	* Signing method registry is now thread safe
-	* Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser)
-
-#### 2.7.0
-
-This will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes.
-
-* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying
-* Error text for expired tokens includes how long it's been expired
-* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM`
-* Documentation updates
-
-#### 2.6.0
-
-* Exposed inner error within ValidationError
-* Fixed validation errors when using UseJSONNumber flag
-* Added several unit tests
-
-#### 2.5.0
-
-* Added support for signing method none.  You shouldn't use this.  The API tries to make this clear.
-* Updated/fixed some documentation
-* Added more helpful error message when trying to parse tokens that begin with `BEARER `
-
-#### 2.4.0
-
-* Added new type, Parser, to allow for configuration of various parsing parameters
-	* You can now specify a list of valid signing methods.  Anything outside this set will be rejected.
-	* You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON
-* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go)
-* Fixed some bugs with ECDSA parsing
-
-#### 2.3.0
-
-* Added support for ECDSA signing methods
-* Added support for RSA PSS signing methods (requires go v1.4)
-
-#### 2.2.0
-
-* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`.  Result will now be the parsed token and an error, instead of a panic.
-
-#### 2.1.0
-
-Backwards compatible API change that was missed in 2.0.0.
-
-* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte`
-
-#### 2.0.0
-
-There were two major reasons for breaking backwards compatibility with this update.  The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations.  There will likely be no required code changes to support this change.
-
-The second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods.  Not all keys used for all signing methods have a single standard on-disk representation.  Requiring `[]byte` as the type for all keys proved too limiting.  Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys.  Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`.
-
-It is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`.
-
-* **Compatibility Breaking Changes**
-	* `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct`
-	* `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct`
-	* `KeyFunc` now returns `interface{}` instead of `[]byte`
-	* `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key
-	* `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key
-* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`.  Specific sizes are now just instances of this type.
-    * Added public package global `SigningMethodHS256`
-    * Added public package global `SigningMethodHS384`
-    * Added public package global `SigningMethodHS512`
-* Renamed type `SigningMethodRS256` to `SigningMethodRSA`.  Specific sizes are now just instances of this type.
-    * Added public package global `SigningMethodRS256`
-    * Added public package global `SigningMethodRS384`
-    * Added public package global `SigningMethodRS512`
-* Moved sample private key for HMAC tests from an inline value to a file on disk.  Value is unchanged.
-* Refactored the RSA implementation to be easier to read
-* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM`
-
-#### 1.0.2
-
-* Fixed bug in parsing public keys from certificates
-* Added more tests around the parsing of keys for RS256
-* Code refactoring in RS256 implementation.  No functional changes
-
-#### 1.0.1
-
-* Fixed panic if RS256 signing method was passed an invalid key
-
-#### 1.0.0
-
-* First versioned release
-* API stabilized
-* Supports creating, signing, parsing, and validating JWT tokens
-* Supports RS256 and HS256 signing methods
\ No newline at end of file
diff --git a/vendor/github.com/dgrijalva/jwt-go/claims.go b/vendor/github.com/dgrijalva/jwt-go/claims.go
deleted file mode 100644
index f0228f0..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/claims.go
+++ /dev/null
@@ -1,134 +0,0 @@
-package jwt
-
-import (
-	"crypto/subtle"
-	"fmt"
-	"time"
-)
-
-// For a type to be a Claims object, it must just have a Valid method that determines
-// if the token is invalid for any supported reason
-type Claims interface {
-	Valid() error
-}
-
-// Structured version of Claims Section, as referenced at
-// https://tools.ietf.org/html/rfc7519#section-4.1
-// See examples for how to use this with your own claim types
-type StandardClaims struct {
-	Audience  string `json:"aud,omitempty"`
-	ExpiresAt int64  `json:"exp,omitempty"`
-	Id        string `json:"jti,omitempty"`
-	IssuedAt  int64  `json:"iat,omitempty"`
-	Issuer    string `json:"iss,omitempty"`
-	NotBefore int64  `json:"nbf,omitempty"`
-	Subject   string `json:"sub,omitempty"`
-}
-
-// Validates time based claims "exp, iat, nbf".
-// There is no accounting for clock skew.
-// As well, if any of the above claims are not in the token, it will still
-// be considered a valid claim.
-func (c StandardClaims) Valid() error {
-	vErr := new(ValidationError)
-	now := TimeFunc().Unix()
-
-	// The claims below are optional, by default, so if they are set to the
-	// default value in Go, let's not fail the verification for them.
-	if c.VerifyExpiresAt(now, false) == false {
-		delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0))
-		vErr.Inner = fmt.Errorf("token is expired by %v", delta)
-		vErr.Errors |= ValidationErrorExpired
-	}
-
-	if c.VerifyIssuedAt(now, false) == false {
-		vErr.Inner = fmt.Errorf("Token used before issued")
-		vErr.Errors |= ValidationErrorIssuedAt
-	}
-
-	if c.VerifyNotBefore(now, false) == false {
-		vErr.Inner = fmt.Errorf("token is not valid yet")
-		vErr.Errors |= ValidationErrorNotValidYet
-	}
-
-	if vErr.valid() {
-		return nil
-	}
-
-	return vErr
-}
-
-// Compares the aud claim against cmp.
-// If required is false, this method will return true if the value matches or is unset
-func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool {
-	return verifyAud(c.Audience, cmp, req)
-}
-
-// Compares the exp claim against cmp.
-// If required is false, this method will return true if the value matches or is unset
-func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool {
-	return verifyExp(c.ExpiresAt, cmp, req)
-}
-
-// Compares the iat claim against cmp.
-// If required is false, this method will return true if the value matches or is unset
-func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool {
-	return verifyIat(c.IssuedAt, cmp, req)
-}
-
-// Compares the iss claim against cmp.
-// If required is false, this method will return true if the value matches or is unset
-func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool {
-	return verifyIss(c.Issuer, cmp, req)
-}
-
-// Compares the nbf claim against cmp.
-// If required is false, this method will return true if the value matches or is unset
-func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
-	return verifyNbf(c.NotBefore, cmp, req)
-}
-
-// ----- helpers
-
-func verifyAud(aud string, cmp string, required bool) bool {
-	if aud == "" {
-		return !required
-	}
-	if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 {
-		return true
-	} else {
-		return false
-	}
-}
-
-func verifyExp(exp int64, now int64, required bool) bool {
-	if exp == 0 {
-		return !required
-	}
-	return now <= exp
-}
-
-func verifyIat(iat int64, now int64, required bool) bool {
-	if iat == 0 {
-		return !required
-	}
-	return now >= iat
-}
-
-func verifyIss(iss string, cmp string, required bool) bool {
-	if iss == "" {
-		return !required
-	}
-	if subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0 {
-		return true
-	} else {
-		return false
-	}
-}
-
-func verifyNbf(nbf int64, now int64, required bool) bool {
-	if nbf == 0 {
-		return !required
-	}
-	return now >= nbf
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/doc.go b/vendor/github.com/dgrijalva/jwt-go/doc.go
deleted file mode 100644
index a86dc1a..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/doc.go
+++ /dev/null
@@ -1,4 +0,0 @@
-// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html
-//
-// See README.md for more info.
-package jwt
diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go
deleted file mode 100644
index f977381..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go
+++ /dev/null
@@ -1,148 +0,0 @@
-package jwt
-
-import (
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/rand"
-	"errors"
-	"math/big"
-)
-
-var (
-	// Sadly this is missing from crypto/ecdsa compared to crypto/rsa
-	ErrECDSAVerification = errors.New("crypto/ecdsa: verification error")
-)
-
-// Implements the ECDSA family of signing methods signing methods
-// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification
-type SigningMethodECDSA struct {
-	Name      string
-	Hash      crypto.Hash
-	KeySize   int
-	CurveBits int
-}
-
-// Specific instances for EC256 and company
-var (
-	SigningMethodES256 *SigningMethodECDSA
-	SigningMethodES384 *SigningMethodECDSA
-	SigningMethodES512 *SigningMethodECDSA
-)
-
-func init() {
-	// ES256
-	SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256}
-	RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod {
-		return SigningMethodES256
-	})
-
-	// ES384
-	SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384}
-	RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod {
-		return SigningMethodES384
-	})
-
-	// ES512
-	SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521}
-	RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod {
-		return SigningMethodES512
-	})
-}
-
-func (m *SigningMethodECDSA) Alg() string {
-	return m.Name
-}
-
-// Implements the Verify method from SigningMethod
-// For this verify method, key must be an ecdsa.PublicKey struct
-func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error {
-	var err error
-
-	// Decode the signature
-	var sig []byte
-	if sig, err = DecodeSegment(signature); err != nil {
-		return err
-	}
-
-	// Get the key
-	var ecdsaKey *ecdsa.PublicKey
-	switch k := key.(type) {
-	case *ecdsa.PublicKey:
-		ecdsaKey = k
-	default:
-		return ErrInvalidKeyType
-	}
-
-	if len(sig) != 2*m.KeySize {
-		return ErrECDSAVerification
-	}
-
-	r := big.NewInt(0).SetBytes(sig[:m.KeySize])
-	s := big.NewInt(0).SetBytes(sig[m.KeySize:])
-
-	// Create hasher
-	if !m.Hash.Available() {
-		return ErrHashUnavailable
-	}
-	hasher := m.Hash.New()
-	hasher.Write([]byte(signingString))
-
-	// Verify the signature
-	if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true {
-		return nil
-	} else {
-		return ErrECDSAVerification
-	}
-}
-
-// Implements the Sign method from SigningMethod
-// For this signing method, key must be an ecdsa.PrivateKey struct
-func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) {
-	// Get the key
-	var ecdsaKey *ecdsa.PrivateKey
-	switch k := key.(type) {
-	case *ecdsa.PrivateKey:
-		ecdsaKey = k
-	default:
-		return "", ErrInvalidKeyType
-	}
-
-	// Create the hasher
-	if !m.Hash.Available() {
-		return "", ErrHashUnavailable
-	}
-
-	hasher := m.Hash.New()
-	hasher.Write([]byte(signingString))
-
-	// Sign the string and return r, s
-	if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil {
-		curveBits := ecdsaKey.Curve.Params().BitSize
-
-		if m.CurveBits != curveBits {
-			return "", ErrInvalidKey
-		}
-
-		keyBytes := curveBits / 8
-		if curveBits%8 > 0 {
-			keyBytes += 1
-		}
-
-		// We serialize the outpus (r and s) into big-endian byte arrays and pad
-		// them with zeros on the left to make sure the sizes work out. Both arrays
-		// must be keyBytes long, and the output must be 2*keyBytes long.
-		rBytes := r.Bytes()
-		rBytesPadded := make([]byte, keyBytes)
-		copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
-
-		sBytes := s.Bytes()
-		sBytesPadded := make([]byte, keyBytes)
-		copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
-
-		out := append(rBytesPadded, sBytesPadded...)
-
-		return EncodeSegment(out), nil
-	} else {
-		return "", err
-	}
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go
deleted file mode 100644
index d19624b..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package jwt
-
-import (
-	"crypto/ecdsa"
-	"crypto/x509"
-	"encoding/pem"
-	"errors"
-)
-
-var (
-	ErrNotECPublicKey  = errors.New("Key is not a valid ECDSA public key")
-	ErrNotECPrivateKey = errors.New("Key is not a valid ECDSA private key")
-)
-
-// Parse PEM encoded Elliptic Curve Private Key Structure
-func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
-	var err error
-
-	// Parse PEM block
-	var block *pem.Block
-	if block, _ = pem.Decode(key); block == nil {
-		return nil, ErrKeyMustBePEMEncoded
-	}
-
-	// Parse the key
-	var parsedKey interface{}
-	if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
-		return nil, err
-	}
-
-	var pkey *ecdsa.PrivateKey
-	var ok bool
-	if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok {
-		return nil, ErrNotECPrivateKey
-	}
-
-	return pkey, nil
-}
-
-// Parse PEM encoded PKCS1 or PKCS8 public key
-func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
-	var err error
-
-	// Parse PEM block
-	var block *pem.Block
-	if block, _ = pem.Decode(key); block == nil {
-		return nil, ErrKeyMustBePEMEncoded
-	}
-
-	// Parse the key
-	var parsedKey interface{}
-	if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
-		if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
-			parsedKey = cert.PublicKey
-		} else {
-			return nil, err
-		}
-	}
-
-	var pkey *ecdsa.PublicKey
-	var ok bool
-	if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok {
-		return nil, ErrNotECPublicKey
-	}
-
-	return pkey, nil
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/errors.go b/vendor/github.com/dgrijalva/jwt-go/errors.go
deleted file mode 100644
index 1c93024..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/errors.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package jwt
-
-import (
-	"errors"
-)
-
-// Error constants
-var (
-	ErrInvalidKey      = errors.New("key is invalid")
-	ErrInvalidKeyType  = errors.New("key is of invalid type")
-	ErrHashUnavailable = errors.New("the requested hash function is unavailable")
-)
-
-// The errors that might occur when parsing and validating a token
-const (
-	ValidationErrorMalformed        uint32 = 1 << iota // Token is malformed
-	ValidationErrorUnverifiable                        // Token could not be verified because of signing problems
-	ValidationErrorSignatureInvalid                    // Signature validation failed
-
-	// Standard Claim validation errors
-	ValidationErrorAudience      // AUD validation failed
-	ValidationErrorExpired       // EXP validation failed
-	ValidationErrorIssuedAt      // IAT validation failed
-	ValidationErrorIssuer        // ISS validation failed
-	ValidationErrorNotValidYet   // NBF validation failed
-	ValidationErrorId            // JTI validation failed
-	ValidationErrorClaimsInvalid // Generic claims validation error
-)
-
-// Helper for constructing a ValidationError with a string error message
-func NewValidationError(errorText string, errorFlags uint32) *ValidationError {
-	return &ValidationError{
-		text:   errorText,
-		Errors: errorFlags,
-	}
-}
-
-// The error from Parse if token is not valid
-type ValidationError struct {
-	Inner  error  // stores the error returned by external dependencies, i.e.: KeyFunc
-	Errors uint32 // bitfield.  see ValidationError... constants
-	text   string // errors that do not have a valid error just have text
-}
-
-// Validation error is an error type
-func (e ValidationError) Error() string {
-	if e.Inner != nil {
-		return e.Inner.Error()
-	} else if e.text != "" {
-		return e.text
-	} else {
-		return "token is invalid"
-	}
-}
-
-// No errors
-func (e *ValidationError) valid() bool {
-	return e.Errors == 0
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/hmac.go b/vendor/github.com/dgrijalva/jwt-go/hmac.go
deleted file mode 100644
index addbe5d..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/hmac.go
+++ /dev/null
@@ -1,95 +0,0 @@
-package jwt
-
-import (
-	"crypto"
-	"crypto/hmac"
-	"errors"
-)
-
-// Implements the HMAC-SHA family of signing methods signing methods
-// Expects key type of []byte for both signing and validation
-type SigningMethodHMAC struct {
-	Name string
-	Hash crypto.Hash
-}
-
-// Specific instances for HS256 and company
-var (
-	SigningMethodHS256  *SigningMethodHMAC
-	SigningMethodHS384  *SigningMethodHMAC
-	SigningMethodHS512  *SigningMethodHMAC
-	ErrSignatureInvalid = errors.New("signature is invalid")
-)
-
-func init() {
-	// HS256
-	SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256}
-	RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod {
-		return SigningMethodHS256
-	})
-
-	// HS384
-	SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384}
-	RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod {
-		return SigningMethodHS384
-	})
-
-	// HS512
-	SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512}
-	RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod {
-		return SigningMethodHS512
-	})
-}
-
-func (m *SigningMethodHMAC) Alg() string {
-	return m.Name
-}
-
-// Verify the signature of HSXXX tokens.  Returns nil if the signature is valid.
-func (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error {
-	// Verify the key is the right type
-	keyBytes, ok := key.([]byte)
-	if !ok {
-		return ErrInvalidKeyType
-	}
-
-	// Decode signature, for comparison
-	sig, err := DecodeSegment(signature)
-	if err != nil {
-		return err
-	}
-
-	// Can we use the specified hashing method?
-	if !m.Hash.Available() {
-		return ErrHashUnavailable
-	}
-
-	// This signing method is symmetric, so we validate the signature
-	// by reproducing the signature from the signing string and key, then
-	// comparing that against the provided signature.
-	hasher := hmac.New(m.Hash.New, keyBytes)
-	hasher.Write([]byte(signingString))
-	if !hmac.Equal(sig, hasher.Sum(nil)) {
-		return ErrSignatureInvalid
-	}
-
-	// No validation errors.  Signature is good.
-	return nil
-}
-
-// Implements the Sign method from SigningMethod for this signing method.
-// Key must be []byte
-func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) {
-	if keyBytes, ok := key.([]byte); ok {
-		if !m.Hash.Available() {
-			return "", ErrHashUnavailable
-		}
-
-		hasher := hmac.New(m.Hash.New, keyBytes)
-		hasher.Write([]byte(signingString))
-
-		return EncodeSegment(hasher.Sum(nil)), nil
-	}
-
-	return "", ErrInvalidKeyType
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/map_claims.go b/vendor/github.com/dgrijalva/jwt-go/map_claims.go
deleted file mode 100644
index 291213c..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/map_claims.go
+++ /dev/null
@@ -1,94 +0,0 @@
-package jwt
-
-import (
-	"encoding/json"
-	"errors"
-	// "fmt"
-)
-
-// Claims type that uses the map[string]interface{} for JSON decoding
-// This is the default claims type if you don't supply one
-type MapClaims map[string]interface{}
-
-// Compares the aud claim against cmp.
-// If required is false, this method will return true if the value matches or is unset
-func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
-	aud, _ := m["aud"].(string)
-	return verifyAud(aud, cmp, req)
-}
-
-// Compares the exp claim against cmp.
-// If required is false, this method will return true if the value matches or is unset
-func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool {
-	switch exp := m["exp"].(type) {
-	case float64:
-		return verifyExp(int64(exp), cmp, req)
-	case json.Number:
-		v, _ := exp.Int64()
-		return verifyExp(v, cmp, req)
-	}
-	return req == false
-}
-
-// Compares the iat claim against cmp.
-// If required is false, this method will return true if the value matches or is unset
-func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool {
-	switch iat := m["iat"].(type) {
-	case float64:
-		return verifyIat(int64(iat), cmp, req)
-	case json.Number:
-		v, _ := iat.Int64()
-		return verifyIat(v, cmp, req)
-	}
-	return req == false
-}
-
-// Compares the iss claim against cmp.
-// If required is false, this method will return true if the value matches or is unset
-func (m MapClaims) VerifyIssuer(cmp string, req bool) bool {
-	iss, _ := m["iss"].(string)
-	return verifyIss(iss, cmp, req)
-}
-
-// Compares the nbf claim against cmp.
-// If required is false, this method will return true if the value matches or is unset
-func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool {
-	switch nbf := m["nbf"].(type) {
-	case float64:
-		return verifyNbf(int64(nbf), cmp, req)
-	case json.Number:
-		v, _ := nbf.Int64()
-		return verifyNbf(v, cmp, req)
-	}
-	return req == false
-}
-
-// Validates time based claims "exp, iat, nbf".
-// There is no accounting for clock skew.
-// As well, if any of the above claims are not in the token, it will still
-// be considered a valid claim.
-func (m MapClaims) Valid() error {
-	vErr := new(ValidationError)
-	now := TimeFunc().Unix()
-
-	if m.VerifyExpiresAt(now, false) == false {
-		vErr.Inner = errors.New("Token is expired")
-		vErr.Errors |= ValidationErrorExpired
-	}
-
-	if m.VerifyIssuedAt(now, false) == false {
-		vErr.Inner = errors.New("Token used before issued")
-		vErr.Errors |= ValidationErrorIssuedAt
-	}
-
-	if m.VerifyNotBefore(now, false) == false {
-		vErr.Inner = errors.New("Token is not valid yet")
-		vErr.Errors |= ValidationErrorNotValidYet
-	}
-
-	if vErr.valid() {
-		return nil
-	}
-
-	return vErr
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/none.go b/vendor/github.com/dgrijalva/jwt-go/none.go
deleted file mode 100644
index f04d189..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/none.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package jwt
-
-// Implements the none signing method.  This is required by the spec
-// but you probably should never use it.
-var SigningMethodNone *signingMethodNone
-
-const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed"
-
-var NoneSignatureTypeDisallowedError error
-
-type signingMethodNone struct{}
-type unsafeNoneMagicConstant string
-
-func init() {
-	SigningMethodNone = &signingMethodNone{}
-	NoneSignatureTypeDisallowedError = NewValidationError("'none' signature type is not allowed", ValidationErrorSignatureInvalid)
-
-	RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod {
-		return SigningMethodNone
-	})
-}
-
-func (m *signingMethodNone) Alg() string {
-	return "none"
-}
-
-// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key
-func (m *signingMethodNone) Verify(signingString, signature string, key interface{}) (err error) {
-	// Key must be UnsafeAllowNoneSignatureType to prevent accidentally
-	// accepting 'none' signing method
-	if _, ok := key.(unsafeNoneMagicConstant); !ok {
-		return NoneSignatureTypeDisallowedError
-	}
-	// If signing method is none, signature must be an empty string
-	if signature != "" {
-		return NewValidationError(
-			"'none' signing method with non-empty signature",
-			ValidationErrorSignatureInvalid,
-		)
-	}
-
-	// Accept 'none' signing method.
-	return nil
-}
-
-// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key
-func (m *signingMethodNone) Sign(signingString string, key interface{}) (string, error) {
-	if _, ok := key.(unsafeNoneMagicConstant); ok {
-		return "", nil
-	}
-	return "", NoneSignatureTypeDisallowedError
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/parser.go b/vendor/github.com/dgrijalva/jwt-go/parser.go
deleted file mode 100644
index d6901d9..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/parser.go
+++ /dev/null
@@ -1,148 +0,0 @@
-package jwt
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"strings"
-)
-
-type Parser struct {
-	ValidMethods         []string // If populated, only these methods will be considered valid
-	UseJSONNumber        bool     // Use JSON Number format in JSON decoder
-	SkipClaimsValidation bool     // Skip claims validation during token parsing
-}
-
-// Parse, validate, and return a token.
-// keyFunc will receive the parsed token and should return the key for validating.
-// If everything is kosher, err will be nil
-func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
-	return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc)
-}
-
-func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
-	token, parts, err := p.ParseUnverified(tokenString, claims)
-	if err != nil {
-		return token, err
-	}
-
-	// Verify signing method is in the required set
-	if p.ValidMethods != nil {
-		var signingMethodValid = false
-		var alg = token.Method.Alg()
-		for _, m := range p.ValidMethods {
-			if m == alg {
-				signingMethodValid = true
-				break
-			}
-		}
-		if !signingMethodValid {
-			// signing method is not in the listed set
-			return token, NewValidationError(fmt.Sprintf("signing method %v is invalid", alg), ValidationErrorSignatureInvalid)
-		}
-	}
-
-	// Lookup key
-	var key interface{}
-	if keyFunc == nil {
-		// keyFunc was not provided.  short circuiting validation
-		return token, NewValidationError("no Keyfunc was provided.", ValidationErrorUnverifiable)
-	}
-	if key, err = keyFunc(token); err != nil {
-		// keyFunc returned an error
-		if ve, ok := err.(*ValidationError); ok {
-			return token, ve
-		}
-		return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable}
-	}
-
-	vErr := &ValidationError{}
-
-	// Validate Claims
-	if !p.SkipClaimsValidation {
-		if err := token.Claims.Valid(); err != nil {
-
-			// If the Claims Valid returned an error, check if it is a validation error,
-			// If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set
-			if e, ok := err.(*ValidationError); !ok {
-				vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid}
-			} else {
-				vErr = e
-			}
-		}
-	}
-
-	// Perform validation
-	token.Signature = parts[2]
-	if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil {
-		vErr.Inner = err
-		vErr.Errors |= ValidationErrorSignatureInvalid
-	}
-
-	if vErr.valid() {
-		token.Valid = true
-		return token, nil
-	}
-
-	return token, vErr
-}
-
-// WARNING: Don't use this method unless you know what you're doing
-//
-// This method parses the token but doesn't validate the signature. It's only
-// ever useful in cases where you know the signature is valid (because it has
-// been checked previously in the stack) and you want to extract values from
-// it.
-func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) {
-	parts = strings.Split(tokenString, ".")
-	if len(parts) != 3 {
-		return nil, parts, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed)
-	}
-
-	token = &Token{Raw: tokenString}
-
-	// parse Header
-	var headerBytes []byte
-	if headerBytes, err = DecodeSegment(parts[0]); err != nil {
-		if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") {
-			return token, parts, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed)
-		}
-		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
-	}
-	if err = json.Unmarshal(headerBytes, &token.Header); err != nil {
-		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
-	}
-
-	// parse Claims
-	var claimBytes []byte
-	token.Claims = claims
-
-	if claimBytes, err = DecodeSegment(parts[1]); err != nil {
-		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
-	}
-	dec := json.NewDecoder(bytes.NewBuffer(claimBytes))
-	if p.UseJSONNumber {
-		dec.UseNumber()
-	}
-	// JSON Decode.  Special case for map type to avoid weird pointer behavior
-	if c, ok := token.Claims.(MapClaims); ok {
-		err = dec.Decode(&c)
-	} else {
-		err = dec.Decode(&claims)
-	}
-	// Handle decode error
-	if err != nil {
-		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
-	}
-
-	// Lookup signature method
-	if method, ok := token.Header["alg"].(string); ok {
-		if token.Method = GetSigningMethod(method); token.Method == nil {
-			return token, parts, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable)
-		}
-	} else {
-		return token, parts, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable)
-	}
-
-	return token, parts, nil
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa.go b/vendor/github.com/dgrijalva/jwt-go/rsa.go
deleted file mode 100644
index e4caf1c..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/rsa.go
+++ /dev/null
@@ -1,101 +0,0 @@
-package jwt
-
-import (
-	"crypto"
-	"crypto/rand"
-	"crypto/rsa"
-)
-
-// Implements the RSA family of signing methods signing methods
-// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation
-type SigningMethodRSA struct {
-	Name string
-	Hash crypto.Hash
-}
-
-// Specific instances for RS256 and company
-var (
-	SigningMethodRS256 *SigningMethodRSA
-	SigningMethodRS384 *SigningMethodRSA
-	SigningMethodRS512 *SigningMethodRSA
-)
-
-func init() {
-	// RS256
-	SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256}
-	RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod {
-		return SigningMethodRS256
-	})
-
-	// RS384
-	SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384}
-	RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod {
-		return SigningMethodRS384
-	})
-
-	// RS512
-	SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512}
-	RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod {
-		return SigningMethodRS512
-	})
-}
-
-func (m *SigningMethodRSA) Alg() string {
-	return m.Name
-}
-
-// Implements the Verify method from SigningMethod
-// For this signing method, must be an *rsa.PublicKey structure.
-func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error {
-	var err error
-
-	// Decode the signature
-	var sig []byte
-	if sig, err = DecodeSegment(signature); err != nil {
-		return err
-	}
-
-	var rsaKey *rsa.PublicKey
-	var ok bool
-
-	if rsaKey, ok = key.(*rsa.PublicKey); !ok {
-		return ErrInvalidKeyType
-	}
-
-	// Create hasher
-	if !m.Hash.Available() {
-		return ErrHashUnavailable
-	}
-	hasher := m.Hash.New()
-	hasher.Write([]byte(signingString))
-
-	// Verify the signature
-	return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig)
-}
-
-// Implements the Sign method from SigningMethod
-// For this signing method, must be an *rsa.PrivateKey structure.
-func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) {
-	var rsaKey *rsa.PrivateKey
-	var ok bool
-
-	// Validate type of key
-	if rsaKey, ok = key.(*rsa.PrivateKey); !ok {
-		return "", ErrInvalidKey
-	}
-
-	// Create the hasher
-	if !m.Hash.Available() {
-		return "", ErrHashUnavailable
-	}
-
-	hasher := m.Hash.New()
-	hasher.Write([]byte(signingString))
-
-	// Sign the string and return the encoded bytes
-	if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil {
-		return EncodeSegment(sigBytes), nil
-	} else {
-		return "", err
-	}
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go b/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go
deleted file mode 100644
index 10ee9db..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// +build go1.4
-
-package jwt
-
-import (
-	"crypto"
-	"crypto/rand"
-	"crypto/rsa"
-)
-
-// Implements the RSAPSS family of signing methods signing methods
-type SigningMethodRSAPSS struct {
-	*SigningMethodRSA
-	Options *rsa.PSSOptions
-}
-
-// Specific instances for RS/PS and company
-var (
-	SigningMethodPS256 *SigningMethodRSAPSS
-	SigningMethodPS384 *SigningMethodRSAPSS
-	SigningMethodPS512 *SigningMethodRSAPSS
-)
-
-func init() {
-	// PS256
-	SigningMethodPS256 = &SigningMethodRSAPSS{
-		&SigningMethodRSA{
-			Name: "PS256",
-			Hash: crypto.SHA256,
-		},
-		&rsa.PSSOptions{
-			SaltLength: rsa.PSSSaltLengthAuto,
-			Hash:       crypto.SHA256,
-		},
-	}
-	RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod {
-		return SigningMethodPS256
-	})
-
-	// PS384
-	SigningMethodPS384 = &SigningMethodRSAPSS{
-		&SigningMethodRSA{
-			Name: "PS384",
-			Hash: crypto.SHA384,
-		},
-		&rsa.PSSOptions{
-			SaltLength: rsa.PSSSaltLengthAuto,
-			Hash:       crypto.SHA384,
-		},
-	}
-	RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod {
-		return SigningMethodPS384
-	})
-
-	// PS512
-	SigningMethodPS512 = &SigningMethodRSAPSS{
-		&SigningMethodRSA{
-			Name: "PS512",
-			Hash: crypto.SHA512,
-		},
-		&rsa.PSSOptions{
-			SaltLength: rsa.PSSSaltLengthAuto,
-			Hash:       crypto.SHA512,
-		},
-	}
-	RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod {
-		return SigningMethodPS512
-	})
-}
-
-// Implements the Verify method from SigningMethod
-// For this verify method, key must be an rsa.PublicKey struct
-func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interface{}) error {
-	var err error
-
-	// Decode the signature
-	var sig []byte
-	if sig, err = DecodeSegment(signature); err != nil {
-		return err
-	}
-
-	var rsaKey *rsa.PublicKey
-	switch k := key.(type) {
-	case *rsa.PublicKey:
-		rsaKey = k
-	default:
-		return ErrInvalidKey
-	}
-
-	// Create hasher
-	if !m.Hash.Available() {
-		return ErrHashUnavailable
-	}
-	hasher := m.Hash.New()
-	hasher.Write([]byte(signingString))
-
-	return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, m.Options)
-}
-
-// Implements the Sign method from SigningMethod
-// For this signing method, key must be an rsa.PrivateKey struct
-func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (string, error) {
-	var rsaKey *rsa.PrivateKey
-
-	switch k := key.(type) {
-	case *rsa.PrivateKey:
-		rsaKey = k
-	default:
-		return "", ErrInvalidKeyType
-	}
-
-	// Create the hasher
-	if !m.Hash.Available() {
-		return "", ErrHashUnavailable
-	}
-
-	hasher := m.Hash.New()
-	hasher.Write([]byte(signingString))
-
-	// Sign the string and return the encoded bytes
-	if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil {
-		return EncodeSegment(sigBytes), nil
-	} else {
-		return "", err
-	}
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go
deleted file mode 100644
index a5ababf..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go
+++ /dev/null
@@ -1,101 +0,0 @@
-package jwt
-
-import (
-	"crypto/rsa"
-	"crypto/x509"
-	"encoding/pem"
-	"errors"
-)
-
-var (
-	ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
-	ErrNotRSAPrivateKey    = errors.New("Key is not a valid RSA private key")
-	ErrNotRSAPublicKey     = errors.New("Key is not a valid RSA public key")
-)
-
-// Parse PEM encoded PKCS1 or PKCS8 private key
-func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
-	var err error
-
-	// Parse PEM block
-	var block *pem.Block
-	if block, _ = pem.Decode(key); block == nil {
-		return nil, ErrKeyMustBePEMEncoded
-	}
-
-	var parsedKey interface{}
-	if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
-		if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
-			return nil, err
-		}
-	}
-
-	var pkey *rsa.PrivateKey
-	var ok bool
-	if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
-		return nil, ErrNotRSAPrivateKey
-	}
-
-	return pkey, nil
-}
-
-// Parse PEM encoded PKCS1 or PKCS8 private key protected with password
-func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) {
-	var err error
-
-	// Parse PEM block
-	var block *pem.Block
-	if block, _ = pem.Decode(key); block == nil {
-		return nil, ErrKeyMustBePEMEncoded
-	}
-
-	var parsedKey interface{}
-
-	var blockDecrypted []byte
-	if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil {
-		return nil, err
-	}
-
-	if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil {
-		if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil {
-			return nil, err
-		}
-	}
-
-	var pkey *rsa.PrivateKey
-	var ok bool
-	if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
-		return nil, ErrNotRSAPrivateKey
-	}
-
-	return pkey, nil
-}
-
-// Parse PEM encoded PKCS1 or PKCS8 public key
-func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
-	var err error
-
-	// Parse PEM block
-	var block *pem.Block
-	if block, _ = pem.Decode(key); block == nil {
-		return nil, ErrKeyMustBePEMEncoded
-	}
-
-	// Parse the key
-	var parsedKey interface{}
-	if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
-		if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
-			parsedKey = cert.PublicKey
-		} else {
-			return nil, err
-		}
-	}
-
-	var pkey *rsa.PublicKey
-	var ok bool
-	if pkey, ok = parsedKey.(*rsa.PublicKey); !ok {
-		return nil, ErrNotRSAPublicKey
-	}
-
-	return pkey, nil
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/signing_method.go b/vendor/github.com/dgrijalva/jwt-go/signing_method.go
deleted file mode 100644
index ed1f212..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/signing_method.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package jwt
-
-import (
-	"sync"
-)
-
-var signingMethods = map[string]func() SigningMethod{}
-var signingMethodLock = new(sync.RWMutex)
-
-// Implement SigningMethod to add new methods for signing or verifying tokens.
-type SigningMethod interface {
-	Verify(signingString, signature string, key interface{}) error // Returns nil if signature is valid
-	Sign(signingString string, key interface{}) (string, error)    // Returns encoded signature or error
-	Alg() string                                                   // returns the alg identifier for this method (example: 'HS256')
-}
-
-// Register the "alg" name and a factory function for signing method.
-// This is typically done during init() in the method's implementation
-func RegisterSigningMethod(alg string, f func() SigningMethod) {
-	signingMethodLock.Lock()
-	defer signingMethodLock.Unlock()
-
-	signingMethods[alg] = f
-}
-
-// Get a signing method from an "alg" string
-func GetSigningMethod(alg string) (method SigningMethod) {
-	signingMethodLock.RLock()
-	defer signingMethodLock.RUnlock()
-
-	if methodF, ok := signingMethods[alg]; ok {
-		method = methodF()
-	}
-	return
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/token.go b/vendor/github.com/dgrijalva/jwt-go/token.go
deleted file mode 100644
index d637e08..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/token.go
+++ /dev/null
@@ -1,108 +0,0 @@
-package jwt
-
-import (
-	"encoding/base64"
-	"encoding/json"
-	"strings"
-	"time"
-)
-
-// TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time).
-// You can override it to use another time value.  This is useful for testing or if your
-// server uses a different time zone than your tokens.
-var TimeFunc = time.Now
-
-// Parse methods use this callback function to supply
-// the key for verification.  The function receives the parsed,
-// but unverified Token.  This allows you to use properties in the
-// Header of the token (such as `kid`) to identify which key to use.
-type Keyfunc func(*Token) (interface{}, error)
-
-// A JWT Token.  Different fields will be used depending on whether you're
-// creating or parsing/verifying a token.
-type Token struct {
-	Raw       string                 // The raw token.  Populated when you Parse a token
-	Method    SigningMethod          // The signing method used or to be used
-	Header    map[string]interface{} // The first segment of the token
-	Claims    Claims                 // The second segment of the token
-	Signature string                 // The third segment of the token.  Populated when you Parse a token
-	Valid     bool                   // Is the token valid?  Populated when you Parse/Verify a token
-}
-
-// Create a new Token.  Takes a signing method
-func New(method SigningMethod) *Token {
-	return NewWithClaims(method, MapClaims{})
-}
-
-func NewWithClaims(method SigningMethod, claims Claims) *Token {
-	return &Token{
-		Header: map[string]interface{}{
-			"typ": "JWT",
-			"alg": method.Alg(),
-		},
-		Claims: claims,
-		Method: method,
-	}
-}
-
-// Get the complete, signed token
-func (t *Token) SignedString(key interface{}) (string, error) {
-	var sig, sstr string
-	var err error
-	if sstr, err = t.SigningString(); err != nil {
-		return "", err
-	}
-	if sig, err = t.Method.Sign(sstr, key); err != nil {
-		return "", err
-	}
-	return strings.Join([]string{sstr, sig}, "."), nil
-}
-
-// Generate the signing string.  This is the
-// most expensive part of the whole deal.  Unless you
-// need this for something special, just go straight for
-// the SignedString.
-func (t *Token) SigningString() (string, error) {
-	var err error
-	parts := make([]string, 2)
-	for i, _ := range parts {
-		var jsonValue []byte
-		if i == 0 {
-			if jsonValue, err = json.Marshal(t.Header); err != nil {
-				return "", err
-			}
-		} else {
-			if jsonValue, err = json.Marshal(t.Claims); err != nil {
-				return "", err
-			}
-		}
-
-		parts[i] = EncodeSegment(jsonValue)
-	}
-	return strings.Join(parts, "."), nil
-}
-
-// Parse, validate, and return a token.
-// keyFunc will receive the parsed token and should return the key for validating.
-// If everything is kosher, err will be nil
-func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
-	return new(Parser).Parse(tokenString, keyFunc)
-}
-
-func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
-	return new(Parser).ParseWithClaims(tokenString, claims, keyFunc)
-}
-
-// Encode JWT specific base64url encoding with padding stripped
-func EncodeSegment(seg []byte) string {
-	return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=")
-}
-
-// Decode JWT specific base64url encoding with padding stripped
-func DecodeSegment(seg string) ([]byte, error) {
-	if l := len(seg) % 4; l > 0 {
-		seg += strings.Repeat("=", 4-l)
-	}
-
-	return base64.URLEncoding.DecodeString(seg)
-}
diff --git a/vendor/github.com/ghodss/yaml/.gitignore b/vendor/github.com/ghodss/yaml/.gitignore
deleted file mode 100644
index e256a31..0000000
--- a/vendor/github.com/ghodss/yaml/.gitignore
+++ /dev/null
@@ -1,20 +0,0 @@
-# OSX leaves these everywhere on SMB shares
-._*
-
-# Eclipse files
-.classpath
-.project
-.settings/**
-
-# Emacs save files
-*~
-
-# Vim-related files
-[._]*.s[a-w][a-z]
-[._]s[a-w][a-z]
-*.un~
-Session.vim
-.netrwhist
-
-# Go test binaries
-*.test
diff --git a/vendor/github.com/ghodss/yaml/.travis.yml b/vendor/github.com/ghodss/yaml/.travis.yml
deleted file mode 100644
index 0e9d6ed..0000000
--- a/vendor/github.com/ghodss/yaml/.travis.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-language: go
-go:
-  - 1.3
-  - 1.4
-script:
-  - go test
-  - go build
diff --git a/vendor/github.com/ghodss/yaml/LICENSE b/vendor/github.com/ghodss/yaml/LICENSE
deleted file mode 100644
index 7805d36..0000000
--- a/vendor/github.com/ghodss/yaml/LICENSE
+++ /dev/null
@@ -1,50 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 Sam Ghods
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-
-Copyright (c) 2012 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/ghodss/yaml/README.md b/vendor/github.com/ghodss/yaml/README.md
deleted file mode 100644
index 0200f75..0000000
--- a/vendor/github.com/ghodss/yaml/README.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# YAML marshaling and unmarshaling support for Go
-
-[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml)
-
-## Introduction
-
-A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs.
-
-In short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/).
-
-## Compatibility
-
-This package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility).
-
-## Caveats
-
-**Caveat #1:** When using `yaml.Marshal` and `yaml.Unmarshal`, binary data should NOT be preceded with the `!!binary` YAML tag. If you do, go-yaml will convert the binary data from base64 to native binary data, which is not compatible with JSON. You can still use binary in your YAML files though - just store them without the `!!binary` tag and decode the base64 in your code (e.g. in the custom JSON methods `MarshalJSON` and `UnmarshalJSON`). This also has the benefit that your YAML and your JSON binary data will be decoded exactly the same way. As an example:
-
-```
-BAD:
-	exampleKey: !!binary gIGC
-
-GOOD:
-	exampleKey: gIGC
-... and decode the base64 data in your code.
-```
-
-**Caveat #2:** When using `YAMLToJSON` directly, maps with keys that are maps will result in an error since this is not supported by JSON. This error will occur in `Unmarshal` as well since you can't unmarshal map keys anyways since struct fields can't be keys.
-
-## Installation and usage
-
-To install, run:
-
-```
-$ go get github.com/ghodss/yaml
-```
-
-And import using:
-
-```
-import "github.com/ghodss/yaml"
-```
-
-Usage is very similar to the JSON library:
-
-```go
-package main
-
-import (
-	"fmt"
-
-	"github.com/ghodss/yaml"
-)
-
-type Person struct {
-	Name string `json:"name"` // Affects YAML field names too.
-	Age  int    `json:"age"`
-}
-
-func main() {
-	// Marshal a Person struct to YAML.
-	p := Person{"John", 30}
-	y, err := yaml.Marshal(p)
-	if err != nil {
-		fmt.Printf("err: %v\n", err)
-		return
-	}
-	fmt.Println(string(y))
-	/* Output:
-	age: 30
-	name: John
-	*/
-
-	// Unmarshal the YAML back into a Person struct.
-	var p2 Person
-	err = yaml.Unmarshal(y, &p2)
-	if err != nil {
-		fmt.Printf("err: %v\n", err)
-		return
-	}
-	fmt.Println(p2)
-	/* Output:
-	{John 30}
-	*/
-}
-```
-
-`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available:
-
-```go
-package main
-
-import (
-	"fmt"
-
-	"github.com/ghodss/yaml"
-)
-
-func main() {
-	j := []byte(`{"name": "John", "age": 30}`)
-	y, err := yaml.JSONToYAML(j)
-	if err != nil {
-		fmt.Printf("err: %v\n", err)
-		return
-	}
-	fmt.Println(string(y))
-	/* Output:
-	name: John
-	age: 30
-	*/
-	j2, err := yaml.YAMLToJSON(y)
-	if err != nil {
-		fmt.Printf("err: %v\n", err)
-		return
-	}
-	fmt.Println(string(j2))
-	/* Output:
-	{"age":30,"name":"John"}
-	*/
-}
-```
diff --git a/vendor/github.com/ghodss/yaml/fields.go b/vendor/github.com/ghodss/yaml/fields.go
deleted file mode 100644
index 5860074..0000000
--- a/vendor/github.com/ghodss/yaml/fields.go
+++ /dev/null
@@ -1,501 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-package yaml
-
-import (
-	"bytes"
-	"encoding"
-	"encoding/json"
-	"reflect"
-	"sort"
-	"strings"
-	"sync"
-	"unicode"
-	"unicode/utf8"
-)
-
-// indirect walks down v allocating pointers as needed,
-// until it gets to a non-pointer.
-// if it encounters an Unmarshaler, indirect stops and returns that.
-// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.
-func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
-	// If v is a named type and is addressable,
-	// start with its address, so that if the type has pointer methods,
-	// we find them.
-	if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
-		v = v.Addr()
-	}
-	for {
-		// Load value from interface, but only if the result will be
-		// usefully addressable.
-		if v.Kind() == reflect.Interface && !v.IsNil() {
-			e := v.Elem()
-			if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
-				v = e
-				continue
-			}
-		}
-
-		if v.Kind() != reflect.Ptr {
-			break
-		}
-
-		if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {
-			break
-		}
-		if v.IsNil() {
-			if v.CanSet() {
-				v.Set(reflect.New(v.Type().Elem()))
-			} else {
-				v = reflect.New(v.Type().Elem())
-			}
-		}
-		if v.Type().NumMethod() > 0 {
-			if u, ok := v.Interface().(json.Unmarshaler); ok {
-				return u, nil, reflect.Value{}
-			}
-			if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
-				return nil, u, reflect.Value{}
-			}
-		}
-		v = v.Elem()
-	}
-	return nil, nil, v
-}
-
-// A field represents a single field found in a struct.
-type field struct {
-	name      string
-	nameBytes []byte                 // []byte(name)
-	equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent
-
-	tag       bool
-	index     []int
-	typ       reflect.Type
-	omitEmpty bool
-	quoted    bool
-}
-
-func fillField(f field) field {
-	f.nameBytes = []byte(f.name)
-	f.equalFold = foldFunc(f.nameBytes)
-	return f
-}
-
-// byName sorts field by name, breaking ties with depth,
-// then breaking ties with "name came from json tag", then
-// breaking ties with index sequence.
-type byName []field
-
-func (x byName) Len() int { return len(x) }
-
-func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-func (x byName) Less(i, j int) bool {
-	if x[i].name != x[j].name {
-		return x[i].name < x[j].name
-	}
-	if len(x[i].index) != len(x[j].index) {
-		return len(x[i].index) < len(x[j].index)
-	}
-	if x[i].tag != x[j].tag {
-		return x[i].tag
-	}
-	return byIndex(x).Less(i, j)
-}
-
-// byIndex sorts field by index sequence.
-type byIndex []field
-
-func (x byIndex) Len() int { return len(x) }
-
-func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-func (x byIndex) Less(i, j int) bool {
-	for k, xik := range x[i].index {
-		if k >= len(x[j].index) {
-			return false
-		}
-		if xik != x[j].index[k] {
-			return xik < x[j].index[k]
-		}
-	}
-	return len(x[i].index) < len(x[j].index)
-}
-
-// typeFields returns a list of fields that JSON should recognize for the given type.
-// The algorithm is breadth-first search over the set of structs to include - the top struct
-// and then any reachable anonymous structs.
-func typeFields(t reflect.Type) []field {
-	// Anonymous fields to explore at the current level and the next.
-	current := []field{}
-	next := []field{{typ: t}}
-
-	// Count of queued names for current level and the next.
-	count := map[reflect.Type]int{}
-	nextCount := map[reflect.Type]int{}
-
-	// Types already visited at an earlier level.
-	visited := map[reflect.Type]bool{}
-
-	// Fields found.
-	var fields []field
-
-	for len(next) > 0 {
-		current, next = next, current[:0]
-		count, nextCount = nextCount, map[reflect.Type]int{}
-
-		for _, f := range current {
-			if visited[f.typ] {
-				continue
-			}
-			visited[f.typ] = true
-
-			// Scan f.typ for fields to include.
-			for i := 0; i < f.typ.NumField(); i++ {
-				sf := f.typ.Field(i)
-				if sf.PkgPath != "" { // unexported
-					continue
-				}
-				tag := sf.Tag.Get("json")
-				if tag == "-" {
-					continue
-				}
-				name, opts := parseTag(tag)
-				if !isValidTag(name) {
-					name = ""
-				}
-				index := make([]int, len(f.index)+1)
-				copy(index, f.index)
-				index[len(f.index)] = i
-
-				ft := sf.Type
-				if ft.Name() == "" && ft.Kind() == reflect.Ptr {
-					// Follow pointer.
-					ft = ft.Elem()
-				}
-
-				// Record found field and index sequence.
-				if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
-					tagged := name != ""
-					if name == "" {
-						name = sf.Name
-					}
-					fields = append(fields, fillField(field{
-						name:      name,
-						tag:       tagged,
-						index:     index,
-						typ:       ft,
-						omitEmpty: opts.Contains("omitempty"),
-						quoted:    opts.Contains("string"),
-					}))
-					if count[f.typ] > 1 {
-						// If there were multiple instances, add a second,
-						// so that the annihilation code will see a duplicate.
-						// It only cares about the distinction between 1 or 2,
-						// so don't bother generating any more copies.
-						fields = append(fields, fields[len(fields)-1])
-					}
-					continue
-				}
-
-				// Record new anonymous struct to explore in next round.
-				nextCount[ft]++
-				if nextCount[ft] == 1 {
-					next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))
-				}
-			}
-		}
-	}
-
-	sort.Sort(byName(fields))
-
-	// Delete all fields that are hidden by the Go rules for embedded fields,
-	// except that fields with JSON tags are promoted.
-
-	// The fields are sorted in primary order of name, secondary order
-	// of field index length. Loop over names; for each name, delete
-	// hidden fields by choosing the one dominant field that survives.
-	out := fields[:0]
-	for advance, i := 0, 0; i < len(fields); i += advance {
-		// One iteration per name.
-		// Find the sequence of fields with the name of this first field.
-		fi := fields[i]
-		name := fi.name
-		for advance = 1; i+advance < len(fields); advance++ {
-			fj := fields[i+advance]
-			if fj.name != name {
-				break
-			}
-		}
-		if advance == 1 { // Only one field with this name
-			out = append(out, fi)
-			continue
-		}
-		dominant, ok := dominantField(fields[i : i+advance])
-		if ok {
-			out = append(out, dominant)
-		}
-	}
-
-	fields = out
-	sort.Sort(byIndex(fields))
-
-	return fields
-}
-
-// dominantField looks through the fields, all of which are known to
-// have the same name, to find the single field that dominates the
-// others using Go's embedding rules, modified by the presence of
-// JSON tags. If there are multiple top-level fields, the boolean
-// will be false: This condition is an error in Go and we skip all
-// the fields.
-func dominantField(fields []field) (field, bool) {
-	// The fields are sorted in increasing index-length order. The winner
-	// must therefore be one with the shortest index length. Drop all
-	// longer entries, which is easy: just truncate the slice.
-	length := len(fields[0].index)
-	tagged := -1 // Index of first tagged field.
-	for i, f := range fields {
-		if len(f.index) > length {
-			fields = fields[:i]
-			break
-		}
-		if f.tag {
-			if tagged >= 0 {
-				// Multiple tagged fields at the same level: conflict.
-				// Return no field.
-				return field{}, false
-			}
-			tagged = i
-		}
-	}
-	if tagged >= 0 {
-		return fields[tagged], true
-	}
-	// All remaining fields have the same length. If there's more than one,
-	// we have a conflict (two fields named "X" at the same level) and we
-	// return no field.
-	if len(fields) > 1 {
-		return field{}, false
-	}
-	return fields[0], true
-}
-
-var fieldCache struct {
-	sync.RWMutex
-	m map[reflect.Type][]field
-}
-
-// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
-func cachedTypeFields(t reflect.Type) []field {
-	fieldCache.RLock()
-	f := fieldCache.m[t]
-	fieldCache.RUnlock()
-	if f != nil {
-		return f
-	}
-
-	// Compute fields without lock.
-	// Might duplicate effort but won't hold other computations back.
-	f = typeFields(t)
-	if f == nil {
-		f = []field{}
-	}
-
-	fieldCache.Lock()
-	if fieldCache.m == nil {
-		fieldCache.m = map[reflect.Type][]field{}
-	}
-	fieldCache.m[t] = f
-	fieldCache.Unlock()
-	return f
-}
-
-func isValidTag(s string) bool {
-	if s == "" {
-		return false
-	}
-	for _, c := range s {
-		switch {
-		case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
-			// Backslash and quote chars are reserved, but
-			// otherwise any punctuation chars are allowed
-			// in a tag name.
-		default:
-			if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
-				return false
-			}
-		}
-	}
-	return true
-}
-
-const (
-	caseMask     = ^byte(0x20) // Mask to ignore case in ASCII.
-	kelvin       = '\u212a'
-	smallLongEss = '\u017f'
-)
-
-// foldFunc returns one of four different case folding equivalence
-// functions, from most general (and slow) to fastest:
-//
-// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8
-// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')
-// 3) asciiEqualFold, no special, but includes non-letters (including _)
-// 4) simpleLetterEqualFold, no specials, no non-letters.
-//
-// The letters S and K are special because they map to 3 runes, not just 2:
-//  * S maps to s and to U+017F 'ſ' Latin small letter long s
-//  * k maps to K and to U+212A 'K' Kelvin sign
-// See http://play.golang.org/p/tTxjOc0OGo
-//
-// The returned function is specialized for matching against s and
-// should only be given s. It's not curried for performance reasons.
-func foldFunc(s []byte) func(s, t []byte) bool {
-	nonLetter := false
-	special := false // special letter
-	for _, b := range s {
-		if b >= utf8.RuneSelf {
-			return bytes.EqualFold
-		}
-		upper := b & caseMask
-		if upper < 'A' || upper > 'Z' {
-			nonLetter = true
-		} else if upper == 'K' || upper == 'S' {
-			// See above for why these letters are special.
-			special = true
-		}
-	}
-	if special {
-		return equalFoldRight
-	}
-	if nonLetter {
-		return asciiEqualFold
-	}
-	return simpleLetterEqualFold
-}
-
-// equalFoldRight is a specialization of bytes.EqualFold when s is
-// known to be all ASCII (including punctuation), but contains an 's',
-// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
-// See comments on foldFunc.
-func equalFoldRight(s, t []byte) bool {
-	for _, sb := range s {
-		if len(t) == 0 {
-			return false
-		}
-		tb := t[0]
-		if tb < utf8.RuneSelf {
-			if sb != tb {
-				sbUpper := sb & caseMask
-				if 'A' <= sbUpper && sbUpper <= 'Z' {
-					if sbUpper != tb&caseMask {
-						return false
-					}
-				} else {
-					return false
-				}
-			}
-			t = t[1:]
-			continue
-		}
-		// sb is ASCII and t is not. t must be either kelvin
-		// sign or long s; sb must be s, S, k, or K.
-		tr, size := utf8.DecodeRune(t)
-		switch sb {
-		case 's', 'S':
-			if tr != smallLongEss {
-				return false
-			}
-		case 'k', 'K':
-			if tr != kelvin {
-				return false
-			}
-		default:
-			return false
-		}
-		t = t[size:]
-
-	}
-	if len(t) > 0 {
-		return false
-	}
-	return true
-}
-
-// asciiEqualFold is a specialization of bytes.EqualFold for use when
-// s is all ASCII (but may contain non-letters) and contains no
-// special-folding letters.
-// See comments on foldFunc.
-func asciiEqualFold(s, t []byte) bool {
-	if len(s) != len(t) {
-		return false
-	}
-	for i, sb := range s {
-		tb := t[i]
-		if sb == tb {
-			continue
-		}
-		if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
-			if sb&caseMask != tb&caseMask {
-				return false
-			}
-		} else {
-			return false
-		}
-	}
-	return true
-}
-
-// simpleLetterEqualFold is a specialization of bytes.EqualFold for
-// use when s is all ASCII letters (no underscores, etc) and also
-// doesn't contain 'k', 'K', 's', or 'S'.
-// See comments on foldFunc.
-func simpleLetterEqualFold(s, t []byte) bool {
-	if len(s) != len(t) {
-		return false
-	}
-	for i, b := range s {
-		if b&caseMask != t[i]&caseMask {
-			return false
-		}
-	}
-	return true
-}
-
-// tagOptions is the string following a comma in a struct field's "json"
-// tag, or the empty string. It does not include the leading comma.
-type tagOptions string
-
-// parseTag splits a struct field's json tag into its name and
-// comma-separated options.
-func parseTag(tag string) (string, tagOptions) {
-	if idx := strings.Index(tag, ","); idx != -1 {
-		return tag[:idx], tagOptions(tag[idx+1:])
-	}
-	return tag, tagOptions("")
-}
-
-// Contains reports whether a comma-separated list of options
-// contains a particular substr flag. substr must be surrounded by a
-// string boundary or commas.
-func (o tagOptions) Contains(optionName string) bool {
-	if len(o) == 0 {
-		return false
-	}
-	s := string(o)
-	for s != "" {
-		var next string
-		i := strings.Index(s, ",")
-		if i >= 0 {
-			s, next = s[:i], s[i+1:]
-		}
-		if s == optionName {
-			return true
-		}
-		s = next
-	}
-	return false
-}
diff --git a/vendor/github.com/ghodss/yaml/yaml.go b/vendor/github.com/ghodss/yaml/yaml.go
deleted file mode 100644
index 4fb4054..0000000
--- a/vendor/github.com/ghodss/yaml/yaml.go
+++ /dev/null
@@ -1,277 +0,0 @@
-package yaml
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"reflect"
-	"strconv"
-
-	"gopkg.in/yaml.v2"
-)
-
-// Marshals the object into JSON then converts JSON to YAML and returns the
-// YAML.
-func Marshal(o interface{}) ([]byte, error) {
-	j, err := json.Marshal(o)
-	if err != nil {
-		return nil, fmt.Errorf("error marshaling into JSON: %v", err)
-	}
-
-	y, err := JSONToYAML(j)
-	if err != nil {
-		return nil, fmt.Errorf("error converting JSON to YAML: %v", err)
-	}
-
-	return y, nil
-}
-
-// Converts YAML to JSON then uses JSON to unmarshal into an object.
-func Unmarshal(y []byte, o interface{}) error {
-	vo := reflect.ValueOf(o)
-	j, err := yamlToJSON(y, &vo)
-	if err != nil {
-		return fmt.Errorf("error converting YAML to JSON: %v", err)
-	}
-
-	err = json.Unmarshal(j, o)
-	if err != nil {
-		return fmt.Errorf("error unmarshaling JSON: %v", err)
-	}
-
-	return nil
-}
-
-// Convert JSON to YAML.
-func JSONToYAML(j []byte) ([]byte, error) {
-	// Convert the JSON to an object.
-	var jsonObj interface{}
-	// We are using yaml.Unmarshal here (instead of json.Unmarshal) because the
-	// Go JSON library doesn't try to pick the right number type (int, float,
-	// etc.) when unmarshalling to interface{}, it just picks float64
-	// universally. go-yaml does go through the effort of picking the right
-	// number type, so we can preserve number type throughout this process.
-	err := yaml.Unmarshal(j, &jsonObj)
-	if err != nil {
-		return nil, err
-	}
-
-	// Marshal this object into YAML.
-	return yaml.Marshal(jsonObj)
-}
-
-// Convert YAML to JSON. Since JSON is a subset of YAML, passing JSON through
-// this method should be a no-op.
-//
-// Things YAML can do that are not supported by JSON:
-// * In YAML you can have binary and null keys in your maps. These are invalid
-//   in JSON. (int and float keys are converted to strings.)
-// * Binary data in YAML with the !!binary tag is not supported. If you want to
-//   use binary data with this library, encode the data as base64 as usual but do
-//   not use the !!binary tag in your YAML. This will ensure the original base64
-//   encoded data makes it all the way through to the JSON.
-func YAMLToJSON(y []byte) ([]byte, error) {
-	return yamlToJSON(y, nil)
-}
-
-func yamlToJSON(y []byte, jsonTarget *reflect.Value) ([]byte, error) {
-	// Convert the YAML to an object.
-	var yamlObj interface{}
-	err := yaml.Unmarshal(y, &yamlObj)
-	if err != nil {
-		return nil, err
-	}
-
-	// YAML objects are not completely compatible with JSON objects (e.g. you
-	// can have non-string keys in YAML). So, convert the YAML-compatible object
-	// to a JSON-compatible object, failing with an error if irrecoverable
-	// incompatibilties happen along the way.
-	jsonObj, err := convertToJSONableObject(yamlObj, jsonTarget)
-	if err != nil {
-		return nil, err
-	}
-
-	// Convert this object to JSON and return the data.
-	return json.Marshal(jsonObj)
-}
-
-func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) {
-	var err error
-
-	// Resolve jsonTarget to a concrete value (i.e. not a pointer or an
-	// interface). We pass decodingNull as false because we're not actually
-	// decoding into the value, we're just checking if the ultimate target is a
-	// string.
-	if jsonTarget != nil {
-		ju, tu, pv := indirect(*jsonTarget, false)
-		// We have a JSON or Text Umarshaler at this level, so we can't be trying
-		// to decode into a string.
-		if ju != nil || tu != nil {
-			jsonTarget = nil
-		} else {
-			jsonTarget = &pv
-		}
-	}
-
-	// If yamlObj is a number or a boolean, check if jsonTarget is a string -
-	// if so, coerce.  Else return normal.
-	// If yamlObj is a map or array, find the field that each key is
-	// unmarshaling to, and when you recurse pass the reflect.Value for that
-	// field back into this function.
-	switch typedYAMLObj := yamlObj.(type) {
-	case map[interface{}]interface{}:
-		// JSON does not support arbitrary keys in a map, so we must convert
-		// these keys to strings.
-		//
-		// From my reading of go-yaml v2 (specifically the resolve function),
-		// keys can only have the types string, int, int64, float64, binary
-		// (unsupported), or null (unsupported).
-		strMap := make(map[string]interface{})
-		for k, v := range typedYAMLObj {
-			// Resolve the key to a string first.
-			var keyString string
-			switch typedKey := k.(type) {
-			case string:
-				keyString = typedKey
-			case int:
-				keyString = strconv.Itoa(typedKey)
-			case int64:
-				// go-yaml will only return an int64 as a key if the system
-				// architecture is 32-bit and the key's value is between 32-bit
-				// and 64-bit. Otherwise the key type will simply be int.
-				keyString = strconv.FormatInt(typedKey, 10)
-			case float64:
-				// Stolen from go-yaml to use the same conversion to string as
-				// the go-yaml library uses to convert float to string when
-				// Marshaling.
-				s := strconv.FormatFloat(typedKey, 'g', -1, 32)
-				switch s {
-				case "+Inf":
-					s = ".inf"
-				case "-Inf":
-					s = "-.inf"
-				case "NaN":
-					s = ".nan"
-				}
-				keyString = s
-			case bool:
-				if typedKey {
-					keyString = "true"
-				} else {
-					keyString = "false"
-				}
-			default:
-				return nil, fmt.Errorf("Unsupported map key of type: %s, key: %+#v, value: %+#v",
-					reflect.TypeOf(k), k, v)
-			}
-
-			// jsonTarget should be a struct or a map. If it's a struct, find
-			// the field it's going to map to and pass its reflect.Value. If
-			// it's a map, find the element type of the map and pass the
-			// reflect.Value created from that type. If it's neither, just pass
-			// nil - JSON conversion will error for us if it's a real issue.
-			if jsonTarget != nil {
-				t := *jsonTarget
-				if t.Kind() == reflect.Struct {
-					keyBytes := []byte(keyString)
-					// Find the field that the JSON library would use.
-					var f *field
-					fields := cachedTypeFields(t.Type())
-					for i := range fields {
-						ff := &fields[i]
-						if bytes.Equal(ff.nameBytes, keyBytes) {
-							f = ff
-							break
-						}
-						// Do case-insensitive comparison.
-						if f == nil && ff.equalFold(ff.nameBytes, keyBytes) {
-							f = ff
-						}
-					}
-					if f != nil {
-						// Find the reflect.Value of the most preferential
-						// struct field.
-						jtf := t.Field(f.index[0])
-						strMap[keyString], err = convertToJSONableObject(v, &jtf)
-						if err != nil {
-							return nil, err
-						}
-						continue
-					}
-				} else if t.Kind() == reflect.Map {
-					// Create a zero value of the map's element type to use as
-					// the JSON target.
-					jtv := reflect.Zero(t.Type().Elem())
-					strMap[keyString], err = convertToJSONableObject(v, &jtv)
-					if err != nil {
-						return nil, err
-					}
-					continue
-				}
-			}
-			strMap[keyString], err = convertToJSONableObject(v, nil)
-			if err != nil {
-				return nil, err
-			}
-		}
-		return strMap, nil
-	case []interface{}:
-		// We need to recurse into arrays in case there are any
-		// map[interface{}]interface{}'s inside and to convert any
-		// numbers to strings.
-
-		// If jsonTarget is a slice (which it really should be), find the
-		// thing it's going to map to. If it's not a slice, just pass nil
-		// - JSON conversion will error for us if it's a real issue.
-		var jsonSliceElemValue *reflect.Value
-		if jsonTarget != nil {
-			t := *jsonTarget
-			if t.Kind() == reflect.Slice {
-				// By default slices point to nil, but we need a reflect.Value
-				// pointing to a value of the slice type, so we create one here.
-				ev := reflect.Indirect(reflect.New(t.Type().Elem()))
-				jsonSliceElemValue = &ev
-			}
-		}
-
-		// Make and use a new array.
-		arr := make([]interface{}, len(typedYAMLObj))
-		for i, v := range typedYAMLObj {
-			arr[i], err = convertToJSONableObject(v, jsonSliceElemValue)
-			if err != nil {
-				return nil, err
-			}
-		}
-		return arr, nil
-	default:
-		// If the target type is a string and the YAML type is a number,
-		// convert the YAML type to a string.
-		if jsonTarget != nil && (*jsonTarget).Kind() == reflect.String {
-			// Based on my reading of go-yaml, it may return int, int64,
-			// float64, or uint64.
-			var s string
-			switch typedVal := typedYAMLObj.(type) {
-			case int:
-				s = strconv.FormatInt(int64(typedVal), 10)
-			case int64:
-				s = strconv.FormatInt(typedVal, 10)
-			case float64:
-				s = strconv.FormatFloat(typedVal, 'g', -1, 32)
-			case uint64:
-				s = strconv.FormatUint(typedVal, 10)
-			case bool:
-				if typedVal {
-					s = "true"
-				} else {
-					s = "false"
-				}
-			}
-			if len(s) > 0 {
-				yamlObj = interface{}(s)
-			}
-		}
-		return yamlObj, nil
-	}
-
-	return nil, nil
-}
diff --git a/vendor/github.com/golang/groupcache/LICENSE b/vendor/github.com/golang/groupcache/LICENSE
deleted file mode 100644
index 37ec93a..0000000
--- a/vendor/github.com/golang/groupcache/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-Apache License
-Version 2.0, January 2004
-http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-"License" shall mean the terms and conditions for use, reproduction, and
-distribution as defined by Sections 1 through 9 of this document.
-
-"Licensor" shall mean the copyright owner or entity authorized by the copyright
-owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities
-that control, are controlled by, or are under common control with that entity.
-For the purposes of this definition, "control" means (i) the power, direct or
-indirect, to cause the direction or management of such entity, whether by
-contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
-outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising
-permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including
-but not limited to software source code, documentation source, and configuration
-files.
-
-"Object" form shall mean any form resulting from mechanical transformation or
-translation of a Source form, including but not limited to compiled object code,
-generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made
-available under the License, as indicated by a copyright notice that is included
-in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that
-is based on (or derived from) the Work and for which the editorial revisions,
-annotations, elaborations, or other modifications represent, as a whole, an
-original work of authorship. For the purposes of this License, Derivative Works
-shall not include works that remain separable from, or merely link (or bind by
-name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version
-of the Work and any modifications or additions to that Work or Derivative Works
-thereof, that is intentionally submitted to Licensor for inclusion in the Work
-by the copyright owner or by an individual or Legal Entity authorized to submit
-on behalf of the copyright owner. For the purposes of this definition,
-"submitted" means any form of electronic, verbal, or written communication sent
-to the Licensor or its representatives, including but not limited to
-communication on electronic mailing lists, source code control systems, and
-issue tracking systems that are managed by, or on behalf of, the Licensor for
-the purpose of discussing and improving the Work, but excluding communication
-that is conspicuously marked or otherwise designated in writing by the copyright
-owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
-of whom a Contribution has been received by Licensor and subsequently
-incorporated within the Work.
-
-2. Grant of Copyright License.
-
-Subject to the terms and conditions of this License, each Contributor hereby
-grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
-irrevocable copyright license to reproduce, prepare Derivative Works of,
-publicly display, publicly perform, sublicense, and distribute the Work and such
-Derivative Works in Source or Object form.
-
-3. Grant of Patent License.
-
-Subject to the terms and conditions of this License, each Contributor hereby
-grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
-irrevocable (except as stated in this section) patent license to make, have
-made, use, offer to sell, sell, import, and otherwise transfer the Work, where
-such license applies only to those patent claims licensable by such Contributor
-that are necessarily infringed by their Contribution(s) alone or by combination
-of their Contribution(s) with the Work to which such Contribution(s) was
-submitted. If You institute patent litigation against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that the Work or a
-Contribution incorporated within the Work constitutes direct or contributory
-patent infringement, then any patent licenses granted to You under this License
-for that Work shall terminate as of the date such litigation is filed.
-
-4. Redistribution.
-
-You may reproduce and distribute copies of the Work or Derivative Works thereof
-in any medium, with or without modifications, and in Source or Object form,
-provided that You meet the following conditions:
-
-You must give any other recipients of the Work or Derivative Works a copy of
-this License; and
-You must cause any modified files to carry prominent notices stating that You
-changed the files; and
-You must retain, in the Source form of any Derivative Works that You distribute,
-all copyright, patent, trademark, and attribution notices from the Source form
-of the Work, excluding those notices that do not pertain to any part of the
-Derivative Works; and
-If the Work includes a "NOTICE" text file as part of its distribution, then any
-Derivative Works that You distribute must include a readable copy of the
-attribution notices contained within such NOTICE file, excluding those notices
-that do not pertain to any part of the Derivative Works, in at least one of the
-following places: within a NOTICE text file distributed as part of the
-Derivative Works; within the Source form or documentation, if provided along
-with the Derivative Works; or, within a display generated by the Derivative
-Works, if and wherever such third-party notices normally appear. The contents of
-the NOTICE file are for informational purposes only and do not modify the
-License. You may add Your own attribution notices within Derivative Works that
-You distribute, alongside or as an addendum to the NOTICE text from the Work,
-provided that such additional attribution notices cannot be construed as
-modifying the License.
-You may add Your own copyright statement to Your modifications and may provide
-additional or different license terms and conditions for use, reproduction, or
-distribution of Your modifications, or for any such Derivative Works as a whole,
-provided Your use, reproduction, and distribution of the Work otherwise complies
-with the conditions stated in this License.
-
-5. Submission of Contributions.
-
-Unless You explicitly state otherwise, any Contribution intentionally submitted
-for inclusion in the Work by You to the Licensor shall be under the terms and
-conditions of this License, without any additional terms or conditions.
-Notwithstanding the above, nothing herein shall supersede or modify the terms of
-any separate license agreement you may have executed with Licensor regarding
-such Contributions.
-
-6. Trademarks.
-
-This License does not grant permission to use the trade names, trademarks,
-service marks, or product names of the Licensor, except as required for
-reasonable and customary use in describing the origin of the Work and
-reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty.
-
-Unless required by applicable law or agreed to in writing, Licensor provides the
-Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
-including, without limitation, any warranties or conditions of TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
-solely responsible for determining the appropriateness of using or
-redistributing the Work and assume any risks associated with Your exercise of
-permissions under this License.
-
-8. Limitation of Liability.
-
-In no event and under no legal theory, whether in tort (including negligence),
-contract, or otherwise, unless required by applicable law (such as deliberate
-and grossly negligent acts) or agreed to in writing, shall any Contributor be
-liable to You for damages, including any direct, indirect, special, incidental,
-or consequential damages of any character arising as a result of this License or
-out of the use or inability to use the Work (including but not limited to
-damages for loss of goodwill, work stoppage, computer failure or malfunction, or
-any and all other commercial damages or losses), even if such Contributor has
-been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability.
-
-While redistributing the Work or Derivative Works thereof, You may choose to
-offer, and charge a fee for, acceptance of support, warranty, indemnity, or
-other liability obligations and/or rights consistent with this License. However,
-in accepting such obligations, You may act only on Your own behalf and on Your
-sole responsibility, not on behalf of any other Contributor, and only if You
-agree to indemnify, defend, and hold each Contributor harmless for any liability
-incurred by, or claims asserted against, such Contributor by reason of your
-accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work
-
-To apply the Apache License to your work, attach the following boilerplate
-notice, with the fields enclosed by brackets "[]" replaced with your own
-identifying information. (Don't include the brackets!) The text should be
-enclosed in the appropriate comment syntax for the file format. We also
-recommend that a file or class name and description of purpose be included on
-the same "printed page" as the copyright notice for easier identification within
-third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/golang/groupcache/lru/lru.go b/vendor/github.com/golang/groupcache/lru/lru.go
deleted file mode 100644
index 532cc45..0000000
--- a/vendor/github.com/golang/groupcache/lru/lru.go
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Copyright 2013 Google Inc.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Package lru implements an LRU cache.
-package lru
-
-import "container/list"
-
-// Cache is an LRU cache. It is not safe for concurrent access.
-type Cache struct {
-	// MaxEntries is the maximum number of cache entries before
-	// an item is evicted. Zero means no limit.
-	MaxEntries int
-
-	// OnEvicted optionally specificies a callback function to be
-	// executed when an entry is purged from the cache.
-	OnEvicted func(key Key, value interface{})
-
-	ll    *list.List
-	cache map[interface{}]*list.Element
-}
-
-// A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators
-type Key interface{}
-
-type entry struct {
-	key   Key
-	value interface{}
-}
-
-// New creates a new Cache.
-// If maxEntries is zero, the cache has no limit and it's assumed
-// that eviction is done by the caller.
-func New(maxEntries int) *Cache {
-	return &Cache{
-		MaxEntries: maxEntries,
-		ll:         list.New(),
-		cache:      make(map[interface{}]*list.Element),
-	}
-}
-
-// Add adds a value to the cache.
-func (c *Cache) Add(key Key, value interface{}) {
-	if c.cache == nil {
-		c.cache = make(map[interface{}]*list.Element)
-		c.ll = list.New()
-	}
-	if ee, ok := c.cache[key]; ok {
-		c.ll.MoveToFront(ee)
-		ee.Value.(*entry).value = value
-		return
-	}
-	ele := c.ll.PushFront(&entry{key, value})
-	c.cache[key] = ele
-	if c.MaxEntries != 0 && c.ll.Len() > c.MaxEntries {
-		c.RemoveOldest()
-	}
-}
-
-// Get looks up a key's value from the cache.
-func (c *Cache) Get(key Key) (value interface{}, ok bool) {
-	if c.cache == nil {
-		return
-	}
-	if ele, hit := c.cache[key]; hit {
-		c.ll.MoveToFront(ele)
-		return ele.Value.(*entry).value, true
-	}
-	return
-}
-
-// Remove removes the provided key from the cache.
-func (c *Cache) Remove(key Key) {
-	if c.cache == nil {
-		return
-	}
-	if ele, hit := c.cache[key]; hit {
-		c.removeElement(ele)
-	}
-}
-
-// RemoveOldest removes the oldest item from the cache.
-func (c *Cache) RemoveOldest() {
-	if c.cache == nil {
-		return
-	}
-	ele := c.ll.Back()
-	if ele != nil {
-		c.removeElement(ele)
-	}
-}
-
-func (c *Cache) removeElement(e *list.Element) {
-	c.ll.Remove(e)
-	kv := e.Value.(*entry)
-	delete(c.cache, kv.key)
-	if c.OnEvicted != nil {
-		c.OnEvicted(kv.key, kv.value)
-	}
-}
-
-// Len returns the number of items in the cache.
-func (c *Cache) Len() int {
-	if c.cache == nil {
-		return 0
-	}
-	return c.ll.Len()
-}
-
-// Clear purges all stored items from the cache.
-func (c *Cache) Clear() {
-	if c.OnEvicted != nil {
-		for _, e := range c.cache {
-			kv := e.Value.(*entry)
-			c.OnEvicted(kv.key, kv.value)
-		}
-	}
-	c.ll = nil
-	c.cache = nil
-}
diff --git a/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
deleted file mode 100644
index ada2b78..0000000
--- a/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
+++ /dev/null
@@ -1,1271 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2015 The Go Authors.  All rights reserved.
-// https://github.com/golang/protobuf
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/*
-Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON.
-It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json.
-
-This package produces a different output than the standard "encoding/json" package,
-which does not operate correctly on protocol buffers.
-*/
-package jsonpb
-
-import (
-	"bytes"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io"
-	"math"
-	"reflect"
-	"sort"
-	"strconv"
-	"strings"
-	"time"
-
-	"github.com/golang/protobuf/proto"
-
-	stpb "github.com/golang/protobuf/ptypes/struct"
-)
-
-const secondInNanos = int64(time.Second / time.Nanosecond)
-
-// Marshaler is a configurable object for converting between
-// protocol buffer objects and a JSON representation for them.
-type Marshaler struct {
-	// Whether to render enum values as integers, as opposed to string values.
-	EnumsAsInts bool
-
-	// Whether to render fields with zero values.
-	EmitDefaults bool
-
-	// A string to indent each level by. The presence of this field will
-	// also cause a space to appear between the field separator and
-	// value, and for newlines to be appear between fields and array
-	// elements.
-	Indent string
-
-	// Whether to use the original (.proto) name for fields.
-	OrigName bool
-
-	// A custom URL resolver to use when marshaling Any messages to JSON.
-	// If unset, the default resolution strategy is to extract the
-	// fully-qualified type name from the type URL and pass that to
-	// proto.MessageType(string).
-	AnyResolver AnyResolver
-}
-
-// AnyResolver takes a type URL, present in an Any message, and resolves it into
-// an instance of the associated message.
-type AnyResolver interface {
-	Resolve(typeUrl string) (proto.Message, error)
-}
-
-func defaultResolveAny(typeUrl string) (proto.Message, error) {
-	// Only the part of typeUrl after the last slash is relevant.
-	mname := typeUrl
-	if slash := strings.LastIndex(mname, "/"); slash >= 0 {
-		mname = mname[slash+1:]
-	}
-	mt := proto.MessageType(mname)
-	if mt == nil {
-		return nil, fmt.Errorf("unknown message type %q", mname)
-	}
-	return reflect.New(mt.Elem()).Interface().(proto.Message), nil
-}
-
-// JSONPBMarshaler is implemented by protobuf messages that customize the
-// way they are marshaled to JSON. Messages that implement this should
-// also implement JSONPBUnmarshaler so that the custom format can be
-// parsed.
-//
-// The JSON marshaling must follow the proto to JSON specification:
-//	https://developers.google.com/protocol-buffers/docs/proto3#json
-type JSONPBMarshaler interface {
-	MarshalJSONPB(*Marshaler) ([]byte, error)
-}
-
-// JSONPBUnmarshaler is implemented by protobuf messages that customize
-// the way they are unmarshaled from JSON. Messages that implement this
-// should also implement JSONPBMarshaler so that the custom format can be
-// produced.
-//
-// The JSON unmarshaling must follow the JSON to proto specification:
-//	https://developers.google.com/protocol-buffers/docs/proto3#json
-type JSONPBUnmarshaler interface {
-	UnmarshalJSONPB(*Unmarshaler, []byte) error
-}
-
-// Marshal marshals a protocol buffer into JSON.
-func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error {
-	v := reflect.ValueOf(pb)
-	if pb == nil || (v.Kind() == reflect.Ptr && v.IsNil()) {
-		return errors.New("Marshal called with nil")
-	}
-	// Check for unset required fields first.
-	if err := checkRequiredFields(pb); err != nil {
-		return err
-	}
-	writer := &errWriter{writer: out}
-	return m.marshalObject(writer, pb, "", "")
-}
-
-// MarshalToString converts a protocol buffer object to JSON string.
-func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) {
-	var buf bytes.Buffer
-	if err := m.Marshal(&buf, pb); err != nil {
-		return "", err
-	}
-	return buf.String(), nil
-}
-
-type int32Slice []int32
-
-var nonFinite = map[string]float64{
-	`"NaN"`:       math.NaN(),
-	`"Infinity"`:  math.Inf(1),
-	`"-Infinity"`: math.Inf(-1),
-}
-
-// For sorting extensions ids to ensure stable output.
-func (s int32Slice) Len() int           { return len(s) }
-func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
-func (s int32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-
-type wkt interface {
-	XXX_WellKnownType() string
-}
-
-// marshalObject writes a struct to the Writer.
-func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeURL string) error {
-	if jsm, ok := v.(JSONPBMarshaler); ok {
-		b, err := jsm.MarshalJSONPB(m)
-		if err != nil {
-			return err
-		}
-		if typeURL != "" {
-			// we are marshaling this object to an Any type
-			var js map[string]*json.RawMessage
-			if err = json.Unmarshal(b, &js); err != nil {
-				return fmt.Errorf("type %T produced invalid JSON: %v", v, err)
-			}
-			turl, err := json.Marshal(typeURL)
-			if err != nil {
-				return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err)
-			}
-			js["@type"] = (*json.RawMessage)(&turl)
-			if b, err = json.Marshal(js); err != nil {
-				return err
-			}
-		}
-
-		out.write(string(b))
-		return out.err
-	}
-
-	s := reflect.ValueOf(v).Elem()
-
-	// Handle well-known types.
-	if wkt, ok := v.(wkt); ok {
-		switch wkt.XXX_WellKnownType() {
-		case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
-			"Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
-			// "Wrappers use the same representation in JSON
-			//  as the wrapped primitive type, ..."
-			sprop := proto.GetProperties(s.Type())
-			return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent)
-		case "Any":
-			// Any is a bit more involved.
-			return m.marshalAny(out, v, indent)
-		case "Duration":
-			// "Generated output always contains 0, 3, 6, or 9 fractional digits,
-			//  depending on required precision."
-			s, ns := s.Field(0).Int(), s.Field(1).Int()
-			if ns <= -secondInNanos || ns >= secondInNanos {
-				return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos)
-			}
-			if (s > 0 && ns < 0) || (s < 0 && ns > 0) {
-				return errors.New("signs of seconds and nanos do not match")
-			}
-			if s < 0 {
-				ns = -ns
-			}
-			x := fmt.Sprintf("%d.%09d", s, ns)
-			x = strings.TrimSuffix(x, "000")
-			x = strings.TrimSuffix(x, "000")
-			x = strings.TrimSuffix(x, ".000")
-			out.write(`"`)
-			out.write(x)
-			out.write(`s"`)
-			return out.err
-		case "Struct", "ListValue":
-			// Let marshalValue handle the `Struct.fields` map or the `ListValue.values` slice.
-			// TODO: pass the correct Properties if needed.
-			return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent)
-		case "Timestamp":
-			// "RFC 3339, where generated output will always be Z-normalized
-			//  and uses 0, 3, 6 or 9 fractional digits."
-			s, ns := s.Field(0).Int(), s.Field(1).Int()
-			if ns < 0 || ns >= secondInNanos {
-				return fmt.Errorf("ns out of range [0, %v)", secondInNanos)
-			}
-			t := time.Unix(s, ns).UTC()
-			// time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits).
-			x := t.Format("2006-01-02T15:04:05.000000000")
-			x = strings.TrimSuffix(x, "000")
-			x = strings.TrimSuffix(x, "000")
-			x = strings.TrimSuffix(x, ".000")
-			out.write(`"`)
-			out.write(x)
-			out.write(`Z"`)
-			return out.err
-		case "Value":
-			// Value has a single oneof.
-			kind := s.Field(0)
-			if kind.IsNil() {
-				// "absence of any variant indicates an error"
-				return errors.New("nil Value")
-			}
-			// oneof -> *T -> T -> T.F
-			x := kind.Elem().Elem().Field(0)
-			// TODO: pass the correct Properties if needed.
-			return m.marshalValue(out, &proto.Properties{}, x, indent)
-		}
-	}
-
-	out.write("{")
-	if m.Indent != "" {
-		out.write("\n")
-	}
-
-	firstField := true
-
-	if typeURL != "" {
-		if err := m.marshalTypeURL(out, indent, typeURL); err != nil {
-			return err
-		}
-		firstField = false
-	}
-
-	for i := 0; i < s.NumField(); i++ {
-		value := s.Field(i)
-		valueField := s.Type().Field(i)
-		if strings.HasPrefix(valueField.Name, "XXX_") {
-			continue
-		}
-
-		// IsNil will panic on most value kinds.
-		switch value.Kind() {
-		case reflect.Chan, reflect.Func, reflect.Interface:
-			if value.IsNil() {
-				continue
-			}
-		}
-
-		if !m.EmitDefaults {
-			switch value.Kind() {
-			case reflect.Bool:
-				if !value.Bool() {
-					continue
-				}
-			case reflect.Int32, reflect.Int64:
-				if value.Int() == 0 {
-					continue
-				}
-			case reflect.Uint32, reflect.Uint64:
-				if value.Uint() == 0 {
-					continue
-				}
-			case reflect.Float32, reflect.Float64:
-				if value.Float() == 0 {
-					continue
-				}
-			case reflect.String:
-				if value.Len() == 0 {
-					continue
-				}
-			case reflect.Map, reflect.Ptr, reflect.Slice:
-				if value.IsNil() {
-					continue
-				}
-			}
-		}
-
-		// Oneof fields need special handling.
-		if valueField.Tag.Get("protobuf_oneof") != "" {
-			// value is an interface containing &T{real_value}.
-			sv := value.Elem().Elem() // interface -> *T -> T
-			value = sv.Field(0)
-			valueField = sv.Type().Field(0)
-		}
-		prop := jsonProperties(valueField, m.OrigName)
-		if !firstField {
-			m.writeSep(out)
-		}
-		if err := m.marshalField(out, prop, value, indent); err != nil {
-			return err
-		}
-		firstField = false
-	}
-
-	// Handle proto2 extensions.
-	if ep, ok := v.(proto.Message); ok {
-		extensions := proto.RegisteredExtensions(v)
-		// Sort extensions for stable output.
-		ids := make([]int32, 0, len(extensions))
-		for id, desc := range extensions {
-			if !proto.HasExtension(ep, desc) {
-				continue
-			}
-			ids = append(ids, id)
-		}
-		sort.Sort(int32Slice(ids))
-		for _, id := range ids {
-			desc := extensions[id]
-			if desc == nil {
-				// unknown extension
-				continue
-			}
-			ext, extErr := proto.GetExtension(ep, desc)
-			if extErr != nil {
-				return extErr
-			}
-			value := reflect.ValueOf(ext)
-			var prop proto.Properties
-			prop.Parse(desc.Tag)
-			prop.JSONName = fmt.Sprintf("[%s]", desc.Name)
-			if !firstField {
-				m.writeSep(out)
-			}
-			if err := m.marshalField(out, &prop, value, indent); err != nil {
-				return err
-			}
-			firstField = false
-		}
-
-	}
-
-	if m.Indent != "" {
-		out.write("\n")
-		out.write(indent)
-	}
-	out.write("}")
-	return out.err
-}
-
-func (m *Marshaler) writeSep(out *errWriter) {
-	if m.Indent != "" {
-		out.write(",\n")
-	} else {
-		out.write(",")
-	}
-}
-
-func (m *Marshaler) marshalAny(out *errWriter, any proto.Message, indent string) error {
-	// "If the Any contains a value that has a special JSON mapping,
-	//  it will be converted as follows: {"@type": xxx, "value": yyy}.
-	//  Otherwise, the value will be converted into a JSON object,
-	//  and the "@type" field will be inserted to indicate the actual data type."
-	v := reflect.ValueOf(any).Elem()
-	turl := v.Field(0).String()
-	val := v.Field(1).Bytes()
-
-	var msg proto.Message
-	var err error
-	if m.AnyResolver != nil {
-		msg, err = m.AnyResolver.Resolve(turl)
-	} else {
-		msg, err = defaultResolveAny(turl)
-	}
-	if err != nil {
-		return err
-	}
-
-	if err := proto.Unmarshal(val, msg); err != nil {
-		return err
-	}
-
-	if _, ok := msg.(wkt); ok {
-		out.write("{")
-		if m.Indent != "" {
-			out.write("\n")
-		}
-		if err := m.marshalTypeURL(out, indent, turl); err != nil {
-			return err
-		}
-		m.writeSep(out)
-		if m.Indent != "" {
-			out.write(indent)
-			out.write(m.Indent)
-			out.write(`"value": `)
-		} else {
-			out.write(`"value":`)
-		}
-		if err := m.marshalObject(out, msg, indent+m.Indent, ""); err != nil {
-			return err
-		}
-		if m.Indent != "" {
-			out.write("\n")
-			out.write(indent)
-		}
-		out.write("}")
-		return out.err
-	}
-
-	return m.marshalObject(out, msg, indent, turl)
-}
-
-func (m *Marshaler) marshalTypeURL(out *errWriter, indent, typeURL string) error {
-	if m.Indent != "" {
-		out.write(indent)
-		out.write(m.Indent)
-	}
-	out.write(`"@type":`)
-	if m.Indent != "" {
-		out.write(" ")
-	}
-	b, err := json.Marshal(typeURL)
-	if err != nil {
-		return err
-	}
-	out.write(string(b))
-	return out.err
-}
-
-// marshalField writes field description and value to the Writer.
-func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
-	if m.Indent != "" {
-		out.write(indent)
-		out.write(m.Indent)
-	}
-	out.write(`"`)
-	out.write(prop.JSONName)
-	out.write(`":`)
-	if m.Indent != "" {
-		out.write(" ")
-	}
-	if err := m.marshalValue(out, prop, v, indent); err != nil {
-		return err
-	}
-	return nil
-}
-
-// marshalValue writes the value to the Writer.
-func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
-	var err error
-	v = reflect.Indirect(v)
-
-	// Handle nil pointer
-	if v.Kind() == reflect.Invalid {
-		out.write("null")
-		return out.err
-	}
-
-	// Handle repeated elements.
-	if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 {
-		out.write("[")
-		comma := ""
-		for i := 0; i < v.Len(); i++ {
-			sliceVal := v.Index(i)
-			out.write(comma)
-			if m.Indent != "" {
-				out.write("\n")
-				out.write(indent)
-				out.write(m.Indent)
-				out.write(m.Indent)
-			}
-			if err := m.marshalValue(out, prop, sliceVal, indent+m.Indent); err != nil {
-				return err
-			}
-			comma = ","
-		}
-		if m.Indent != "" {
-			out.write("\n")
-			out.write(indent)
-			out.write(m.Indent)
-		}
-		out.write("]")
-		return out.err
-	}
-
-	// Handle well-known types.
-	// Most are handled up in marshalObject (because 99% are messages).
-	if wkt, ok := v.Interface().(wkt); ok {
-		switch wkt.XXX_WellKnownType() {
-		case "NullValue":
-			out.write("null")
-			return out.err
-		}
-	}
-
-	// Handle enumerations.
-	if !m.EnumsAsInts && prop.Enum != "" {
-		// Unknown enum values will are stringified by the proto library as their
-		// value. Such values should _not_ be quoted or they will be interpreted
-		// as an enum string instead of their value.
-		enumStr := v.Interface().(fmt.Stringer).String()
-		var valStr string
-		if v.Kind() == reflect.Ptr {
-			valStr = strconv.Itoa(int(v.Elem().Int()))
-		} else {
-			valStr = strconv.Itoa(int(v.Int()))
-		}
-		isKnownEnum := enumStr != valStr
-		if isKnownEnum {
-			out.write(`"`)
-		}
-		out.write(enumStr)
-		if isKnownEnum {
-			out.write(`"`)
-		}
-		return out.err
-	}
-
-	// Handle nested messages.
-	if v.Kind() == reflect.Struct {
-		return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent, "")
-	}
-
-	// Handle maps.
-	// Since Go randomizes map iteration, we sort keys for stable output.
-	if v.Kind() == reflect.Map {
-		out.write(`{`)
-		keys := v.MapKeys()
-		sort.Sort(mapKeys(keys))
-		for i, k := range keys {
-			if i > 0 {
-				out.write(`,`)
-			}
-			if m.Indent != "" {
-				out.write("\n")
-				out.write(indent)
-				out.write(m.Indent)
-				out.write(m.Indent)
-			}
-
-			// TODO handle map key prop properly
-			b, err := json.Marshal(k.Interface())
-			if err != nil {
-				return err
-			}
-			s := string(b)
-
-			// If the JSON is not a string value, encode it again to make it one.
-			if !strings.HasPrefix(s, `"`) {
-				b, err := json.Marshal(s)
-				if err != nil {
-					return err
-				}
-				s = string(b)
-			}
-
-			out.write(s)
-			out.write(`:`)
-			if m.Indent != "" {
-				out.write(` `)
-			}
-
-			vprop := prop
-			if prop != nil && prop.MapValProp != nil {
-				vprop = prop.MapValProp
-			}
-			if err := m.marshalValue(out, vprop, v.MapIndex(k), indent+m.Indent); err != nil {
-				return err
-			}
-		}
-		if m.Indent != "" {
-			out.write("\n")
-			out.write(indent)
-			out.write(m.Indent)
-		}
-		out.write(`}`)
-		return out.err
-	}
-
-	// Handle non-finite floats, e.g. NaN, Infinity and -Infinity.
-	if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
-		f := v.Float()
-		var sval string
-		switch {
-		case math.IsInf(f, 1):
-			sval = `"Infinity"`
-		case math.IsInf(f, -1):
-			sval = `"-Infinity"`
-		case math.IsNaN(f):
-			sval = `"NaN"`
-		}
-		if sval != "" {
-			out.write(sval)
-			return out.err
-		}
-	}
-
-	// Default handling defers to the encoding/json library.
-	b, err := json.Marshal(v.Interface())
-	if err != nil {
-		return err
-	}
-	needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64)
-	if needToQuote {
-		out.write(`"`)
-	}
-	out.write(string(b))
-	if needToQuote {
-		out.write(`"`)
-	}
-	return out.err
-}
-
-// Unmarshaler is a configurable object for converting from a JSON
-// representation to a protocol buffer object.
-type Unmarshaler struct {
-	// Whether to allow messages to contain unknown fields, as opposed to
-	// failing to unmarshal.
-	AllowUnknownFields bool
-
-	// A custom URL resolver to use when unmarshaling Any messages from JSON.
-	// If unset, the default resolution strategy is to extract the
-	// fully-qualified type name from the type URL and pass that to
-	// proto.MessageType(string).
-	AnyResolver AnyResolver
-}
-
-// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
-// This function is lenient and will decode any options permutations of the
-// related Marshaler.
-func (u *Unmarshaler) UnmarshalNext(dec *json.Decoder, pb proto.Message) error {
-	inputValue := json.RawMessage{}
-	if err := dec.Decode(&inputValue); err != nil {
-		return err
-	}
-	if err := u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil); err != nil {
-		return err
-	}
-	return checkRequiredFields(pb)
-}
-
-// Unmarshal unmarshals a JSON object stream into a protocol
-// buffer. This function is lenient and will decode any options
-// permutations of the related Marshaler.
-func (u *Unmarshaler) Unmarshal(r io.Reader, pb proto.Message) error {
-	dec := json.NewDecoder(r)
-	return u.UnmarshalNext(dec, pb)
-}
-
-// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
-// This function is lenient and will decode any options permutations of the
-// related Marshaler.
-func UnmarshalNext(dec *json.Decoder, pb proto.Message) error {
-	return new(Unmarshaler).UnmarshalNext(dec, pb)
-}
-
-// Unmarshal unmarshals a JSON object stream into a protocol
-// buffer. This function is lenient and will decode any options
-// permutations of the related Marshaler.
-func Unmarshal(r io.Reader, pb proto.Message) error {
-	return new(Unmarshaler).Unmarshal(r, pb)
-}
-
-// UnmarshalString will populate the fields of a protocol buffer based
-// on a JSON string. This function is lenient and will decode any options
-// permutations of the related Marshaler.
-func UnmarshalString(str string, pb proto.Message) error {
-	return new(Unmarshaler).Unmarshal(strings.NewReader(str), pb)
-}
-
-// unmarshalValue converts/copies a value into the target.
-// prop may be nil.
-func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error {
-	targetType := target.Type()
-
-	// Allocate memory for pointer fields.
-	if targetType.Kind() == reflect.Ptr {
-		// If input value is "null" and target is a pointer type, then the field should be treated as not set
-		// UNLESS the target is structpb.Value, in which case it should be set to structpb.NullValue.
-		_, isJSONPBUnmarshaler := target.Interface().(JSONPBUnmarshaler)
-		if string(inputValue) == "null" && targetType != reflect.TypeOf(&stpb.Value{}) && !isJSONPBUnmarshaler {
-			return nil
-		}
-		target.Set(reflect.New(targetType.Elem()))
-
-		return u.unmarshalValue(target.Elem(), inputValue, prop)
-	}
-
-	if jsu, ok := target.Addr().Interface().(JSONPBUnmarshaler); ok {
-		return jsu.UnmarshalJSONPB(u, []byte(inputValue))
-	}
-
-	// Handle well-known types that are not pointers.
-	if w, ok := target.Addr().Interface().(wkt); ok {
-		switch w.XXX_WellKnownType() {
-		case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
-			"Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
-			return u.unmarshalValue(target.Field(0), inputValue, prop)
-		case "Any":
-			// Use json.RawMessage pointer type instead of value to support pre-1.8 version.
-			// 1.8 changed RawMessage.MarshalJSON from pointer type to value type, see
-			// https://github.com/golang/go/issues/14493
-			var jsonFields map[string]*json.RawMessage
-			if err := json.Unmarshal(inputValue, &jsonFields); err != nil {
-				return err
-			}
-
-			val, ok := jsonFields["@type"]
-			if !ok || val == nil {
-				return errors.New("Any JSON doesn't have '@type'")
-			}
-
-			var turl string
-			if err := json.Unmarshal([]byte(*val), &turl); err != nil {
-				return fmt.Errorf("can't unmarshal Any's '@type': %q", *val)
-			}
-			target.Field(0).SetString(turl)
-
-			var m proto.Message
-			var err error
-			if u.AnyResolver != nil {
-				m, err = u.AnyResolver.Resolve(turl)
-			} else {
-				m, err = defaultResolveAny(turl)
-			}
-			if err != nil {
-				return err
-			}
-
-			if _, ok := m.(wkt); ok {
-				val, ok := jsonFields["value"]
-				if !ok {
-					return errors.New("Any JSON doesn't have 'value'")
-				}
-
-				if err := u.unmarshalValue(reflect.ValueOf(m).Elem(), *val, nil); err != nil {
-					return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err)
-				}
-			} else {
-				delete(jsonFields, "@type")
-				nestedProto, err := json.Marshal(jsonFields)
-				if err != nil {
-					return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err)
-				}
-
-				if err = u.unmarshalValue(reflect.ValueOf(m).Elem(), nestedProto, nil); err != nil {
-					return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err)
-				}
-			}
-
-			b, err := proto.Marshal(m)
-			if err != nil {
-				return fmt.Errorf("can't marshal proto %T into Any.Value: %v", m, err)
-			}
-			target.Field(1).SetBytes(b)
-
-			return nil
-		case "Duration":
-			unq, err := unquote(string(inputValue))
-			if err != nil {
-				return err
-			}
-
-			d, err := time.ParseDuration(unq)
-			if err != nil {
-				return fmt.Errorf("bad Duration: %v", err)
-			}
-
-			ns := d.Nanoseconds()
-			s := ns / 1e9
-			ns %= 1e9
-			target.Field(0).SetInt(s)
-			target.Field(1).SetInt(ns)
-			return nil
-		case "Timestamp":
-			unq, err := unquote(string(inputValue))
-			if err != nil {
-				return err
-			}
-
-			t, err := time.Parse(time.RFC3339Nano, unq)
-			if err != nil {
-				return fmt.Errorf("bad Timestamp: %v", err)
-			}
-
-			target.Field(0).SetInt(t.Unix())
-			target.Field(1).SetInt(int64(t.Nanosecond()))
-			return nil
-		case "Struct":
-			var m map[string]json.RawMessage
-			if err := json.Unmarshal(inputValue, &m); err != nil {
-				return fmt.Errorf("bad StructValue: %v", err)
-			}
-
-			target.Field(0).Set(reflect.ValueOf(map[string]*stpb.Value{}))
-			for k, jv := range m {
-				pv := &stpb.Value{}
-				if err := u.unmarshalValue(reflect.ValueOf(pv).Elem(), jv, prop); err != nil {
-					return fmt.Errorf("bad value in StructValue for key %q: %v", k, err)
-				}
-				target.Field(0).SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(pv))
-			}
-			return nil
-		case "ListValue":
-			var s []json.RawMessage
-			if err := json.Unmarshal(inputValue, &s); err != nil {
-				return fmt.Errorf("bad ListValue: %v", err)
-			}
-
-			target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s))))
-			for i, sv := range s {
-				if err := u.unmarshalValue(target.Field(0).Index(i), sv, prop); err != nil {
-					return err
-				}
-			}
-			return nil
-		case "Value":
-			ivStr := string(inputValue)
-			if ivStr == "null" {
-				target.Field(0).Set(reflect.ValueOf(&stpb.Value_NullValue{}))
-			} else if v, err := strconv.ParseFloat(ivStr, 0); err == nil {
-				target.Field(0).Set(reflect.ValueOf(&stpb.Value_NumberValue{v}))
-			} else if v, err := unquote(ivStr); err == nil {
-				target.Field(0).Set(reflect.ValueOf(&stpb.Value_StringValue{v}))
-			} else if v, err := strconv.ParseBool(ivStr); err == nil {
-				target.Field(0).Set(reflect.ValueOf(&stpb.Value_BoolValue{v}))
-			} else if err := json.Unmarshal(inputValue, &[]json.RawMessage{}); err == nil {
-				lv := &stpb.ListValue{}
-				target.Field(0).Set(reflect.ValueOf(&stpb.Value_ListValue{lv}))
-				return u.unmarshalValue(reflect.ValueOf(lv).Elem(), inputValue, prop)
-			} else if err := json.Unmarshal(inputValue, &map[string]json.RawMessage{}); err == nil {
-				sv := &stpb.Struct{}
-				target.Field(0).Set(reflect.ValueOf(&stpb.Value_StructValue{sv}))
-				return u.unmarshalValue(reflect.ValueOf(sv).Elem(), inputValue, prop)
-			} else {
-				return fmt.Errorf("unrecognized type for Value %q", ivStr)
-			}
-			return nil
-		}
-	}
-
-	// Handle enums, which have an underlying type of int32,
-	// and may appear as strings.
-	// The case of an enum appearing as a number is handled
-	// at the bottom of this function.
-	if inputValue[0] == '"' && prop != nil && prop.Enum != "" {
-		vmap := proto.EnumValueMap(prop.Enum)
-		// Don't need to do unquoting; valid enum names
-		// are from a limited character set.
-		s := inputValue[1 : len(inputValue)-1]
-		n, ok := vmap[string(s)]
-		if !ok {
-			return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum)
-		}
-		if target.Kind() == reflect.Ptr { // proto2
-			target.Set(reflect.New(targetType.Elem()))
-			target = target.Elem()
-		}
-		if targetType.Kind() != reflect.Int32 {
-			return fmt.Errorf("invalid target %q for enum %s", targetType.Kind(), prop.Enum)
-		}
-		target.SetInt(int64(n))
-		return nil
-	}
-
-	// Handle nested messages.
-	if targetType.Kind() == reflect.Struct {
-		var jsonFields map[string]json.RawMessage
-		if err := json.Unmarshal(inputValue, &jsonFields); err != nil {
-			return err
-		}
-
-		consumeField := func(prop *proto.Properties) (json.RawMessage, bool) {
-			// Be liberal in what names we accept; both orig_name and camelName are okay.
-			fieldNames := acceptedJSONFieldNames(prop)
-
-			vOrig, okOrig := jsonFields[fieldNames.orig]
-			vCamel, okCamel := jsonFields[fieldNames.camel]
-			if !okOrig && !okCamel {
-				return nil, false
-			}
-			// If, for some reason, both are present in the data, favour the camelName.
-			var raw json.RawMessage
-			if okOrig {
-				raw = vOrig
-				delete(jsonFields, fieldNames.orig)
-			}
-			if okCamel {
-				raw = vCamel
-				delete(jsonFields, fieldNames.camel)
-			}
-			return raw, true
-		}
-
-		sprops := proto.GetProperties(targetType)
-		for i := 0; i < target.NumField(); i++ {
-			ft := target.Type().Field(i)
-			if strings.HasPrefix(ft.Name, "XXX_") {
-				continue
-			}
-
-			valueForField, ok := consumeField(sprops.Prop[i])
-			if !ok {
-				continue
-			}
-
-			if err := u.unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil {
-				return err
-			}
-		}
-		// Check for any oneof fields.
-		if len(jsonFields) > 0 {
-			for _, oop := range sprops.OneofTypes {
-				raw, ok := consumeField(oop.Prop)
-				if !ok {
-					continue
-				}
-				nv := reflect.New(oop.Type.Elem())
-				target.Field(oop.Field).Set(nv)
-				if err := u.unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil {
-					return err
-				}
-			}
-		}
-		// Handle proto2 extensions.
-		if len(jsonFields) > 0 {
-			if ep, ok := target.Addr().Interface().(proto.Message); ok {
-				for _, ext := range proto.RegisteredExtensions(ep) {
-					name := fmt.Sprintf("[%s]", ext.Name)
-					raw, ok := jsonFields[name]
-					if !ok {
-						continue
-					}
-					delete(jsonFields, name)
-					nv := reflect.New(reflect.TypeOf(ext.ExtensionType).Elem())
-					if err := u.unmarshalValue(nv.Elem(), raw, nil); err != nil {
-						return err
-					}
-					if err := proto.SetExtension(ep, ext, nv.Interface()); err != nil {
-						return err
-					}
-				}
-			}
-		}
-		if !u.AllowUnknownFields && len(jsonFields) > 0 {
-			// Pick any field to be the scapegoat.
-			var f string
-			for fname := range jsonFields {
-				f = fname
-				break
-			}
-			return fmt.Errorf("unknown field %q in %v", f, targetType)
-		}
-		return nil
-	}
-
-	// Handle arrays (which aren't encoded bytes)
-	if targetType.Kind() == reflect.Slice && targetType.Elem().Kind() != reflect.Uint8 {
-		var slc []json.RawMessage
-		if err := json.Unmarshal(inputValue, &slc); err != nil {
-			return err
-		}
-		if slc != nil {
-			l := len(slc)
-			target.Set(reflect.MakeSlice(targetType, l, l))
-			for i := 0; i < l; i++ {
-				if err := u.unmarshalValue(target.Index(i), slc[i], prop); err != nil {
-					return err
-				}
-			}
-		}
-		return nil
-	}
-
-	// Handle maps (whose keys are always strings)
-	if targetType.Kind() == reflect.Map {
-		var mp map[string]json.RawMessage
-		if err := json.Unmarshal(inputValue, &mp); err != nil {
-			return err
-		}
-		if mp != nil {
-			target.Set(reflect.MakeMap(targetType))
-			for ks, raw := range mp {
-				// Unmarshal map key. The core json library already decoded the key into a
-				// string, so we handle that specially. Other types were quoted post-serialization.
-				var k reflect.Value
-				if targetType.Key().Kind() == reflect.String {
-					k = reflect.ValueOf(ks)
-				} else {
-					k = reflect.New(targetType.Key()).Elem()
-					var kprop *proto.Properties
-					if prop != nil && prop.MapKeyProp != nil {
-						kprop = prop.MapKeyProp
-					}
-					if err := u.unmarshalValue(k, json.RawMessage(ks), kprop); err != nil {
-						return err
-					}
-				}
-
-				// Unmarshal map value.
-				v := reflect.New(targetType.Elem()).Elem()
-				var vprop *proto.Properties
-				if prop != nil && prop.MapValProp != nil {
-					vprop = prop.MapValProp
-				}
-				if err := u.unmarshalValue(v, raw, vprop); err != nil {
-					return err
-				}
-				target.SetMapIndex(k, v)
-			}
-		}
-		return nil
-	}
-
-	// Non-finite numbers can be encoded as strings.
-	isFloat := targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64
-	if isFloat {
-		if num, ok := nonFinite[string(inputValue)]; ok {
-			target.SetFloat(num)
-			return nil
-		}
-	}
-
-	// integers & floats can be encoded as strings. In this case we drop
-	// the quotes and proceed as normal.
-	isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64 ||
-		targetType.Kind() == reflect.Int32 || targetType.Kind() == reflect.Uint32 ||
-		targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64
-	if isNum && strings.HasPrefix(string(inputValue), `"`) {
-		inputValue = inputValue[1 : len(inputValue)-1]
-	}
-
-	// Use the encoding/json for parsing other value types.
-	return json.Unmarshal(inputValue, target.Addr().Interface())
-}
-
-func unquote(s string) (string, error) {
-	var ret string
-	err := json.Unmarshal([]byte(s), &ret)
-	return ret, err
-}
-
-// jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute.
-func jsonProperties(f reflect.StructField, origName bool) *proto.Properties {
-	var prop proto.Properties
-	prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f)
-	if origName || prop.JSONName == "" {
-		prop.JSONName = prop.OrigName
-	}
-	return &prop
-}
-
-type fieldNames struct {
-	orig, camel string
-}
-
-func acceptedJSONFieldNames(prop *proto.Properties) fieldNames {
-	opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName}
-	if prop.JSONName != "" {
-		opts.camel = prop.JSONName
-	}
-	return opts
-}
-
-// Writer wrapper inspired by https://blog.golang.org/errors-are-values
-type errWriter struct {
-	writer io.Writer
-	err    error
-}
-
-func (w *errWriter) write(str string) {
-	if w.err != nil {
-		return
-	}
-	_, w.err = w.writer.Write([]byte(str))
-}
-
-// Map fields may have key types of non-float scalars, strings and enums.
-// The easiest way to sort them in some deterministic order is to use fmt.
-// If this turns out to be inefficient we can always consider other options,
-// such as doing a Schwartzian transform.
-//
-// Numeric keys are sorted in numeric order per
-// https://developers.google.com/protocol-buffers/docs/proto#maps.
-type mapKeys []reflect.Value
-
-func (s mapKeys) Len() int      { return len(s) }
-func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-func (s mapKeys) Less(i, j int) bool {
-	if k := s[i].Kind(); k == s[j].Kind() {
-		switch k {
-		case reflect.String:
-			return s[i].String() < s[j].String()
-		case reflect.Int32, reflect.Int64:
-			return s[i].Int() < s[j].Int()
-		case reflect.Uint32, reflect.Uint64:
-			return s[i].Uint() < s[j].Uint()
-		}
-	}
-	return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
-}
-
-// checkRequiredFields returns an error if any required field in the given proto message is not set.
-// This function is used by both Marshal and Unmarshal.  While required fields only exist in a
-// proto2 message, a proto3 message can contain proto2 message(s).
-func checkRequiredFields(pb proto.Message) error {
-	// Most well-known type messages do not contain required fields.  The "Any" type may contain
-	// a message that has required fields.
-	//
-	// When an Any message is being marshaled, the code will invoked proto.Unmarshal on Any.Value
-	// field in order to transform that into JSON, and that should have returned an error if a
-	// required field is not set in the embedded message.
-	//
-	// When an Any message is being unmarshaled, the code will have invoked proto.Marshal on the
-	// embedded message to store the serialized message in Any.Value field, and that should have
-	// returned an error if a required field is not set.
-	if _, ok := pb.(wkt); ok {
-		return nil
-	}
-
-	v := reflect.ValueOf(pb)
-	// Skip message if it is not a struct pointer.
-	if v.Kind() != reflect.Ptr {
-		return nil
-	}
-	v = v.Elem()
-	if v.Kind() != reflect.Struct {
-		return nil
-	}
-
-	for i := 0; i < v.NumField(); i++ {
-		field := v.Field(i)
-		sfield := v.Type().Field(i)
-
-		if sfield.PkgPath != "" {
-			// blank PkgPath means the field is exported; skip if not exported
-			continue
-		}
-
-		if strings.HasPrefix(sfield.Name, "XXX_") {
-			continue
-		}
-
-		// Oneof field is an interface implemented by wrapper structs containing the actual oneof
-		// field, i.e. an interface containing &T{real_value}.
-		if sfield.Tag.Get("protobuf_oneof") != "" {
-			if field.Kind() != reflect.Interface {
-				continue
-			}
-			v := field.Elem()
-			if v.Kind() != reflect.Ptr || v.IsNil() {
-				continue
-			}
-			v = v.Elem()
-			if v.Kind() != reflect.Struct || v.NumField() < 1 {
-				continue
-			}
-			field = v.Field(0)
-			sfield = v.Type().Field(0)
-		}
-
-		protoTag := sfield.Tag.Get("protobuf")
-		if protoTag == "" {
-			continue
-		}
-		var prop proto.Properties
-		prop.Init(sfield.Type, sfield.Name, protoTag, &sfield)
-
-		switch field.Kind() {
-		case reflect.Map:
-			if field.IsNil() {
-				continue
-			}
-			// Check each map value.
-			keys := field.MapKeys()
-			for _, k := range keys {
-				v := field.MapIndex(k)
-				if err := checkRequiredFieldsInValue(v); err != nil {
-					return err
-				}
-			}
-		case reflect.Slice:
-			// Handle non-repeated type, e.g. bytes.
-			if !prop.Repeated {
-				if prop.Required && field.IsNil() {
-					return fmt.Errorf("required field %q is not set", prop.Name)
-				}
-				continue
-			}
-
-			// Handle repeated type.
-			if field.IsNil() {
-				continue
-			}
-			// Check each slice item.
-			for i := 0; i < field.Len(); i++ {
-				v := field.Index(i)
-				if err := checkRequiredFieldsInValue(v); err != nil {
-					return err
-				}
-			}
-		case reflect.Ptr:
-			if field.IsNil() {
-				if prop.Required {
-					return fmt.Errorf("required field %q is not set", prop.Name)
-				}
-				continue
-			}
-			if err := checkRequiredFieldsInValue(field); err != nil {
-				return err
-			}
-		}
-	}
-
-	// Handle proto2 extensions.
-	for _, ext := range proto.RegisteredExtensions(pb) {
-		if !proto.HasExtension(pb, ext) {
-			continue
-		}
-		ep, err := proto.GetExtension(pb, ext)
-		if err != nil {
-			return err
-		}
-		err = checkRequiredFieldsInValue(reflect.ValueOf(ep))
-		if err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func checkRequiredFieldsInValue(v reflect.Value) error {
-	if pm, ok := v.Interface().(proto.Message); ok {
-		return checkRequiredFields(pm)
-	}
-	return nil
-}
diff --git a/vendor/github.com/golang/protobuf/ptypes/struct/struct.proto b/vendor/github.com/golang/protobuf/ptypes/struct/struct.proto
deleted file mode 100644
index 7d7808e..0000000
--- a/vendor/github.com/golang/protobuf/ptypes/struct/struct.proto
+++ /dev/null
@@ -1,96 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option cc_enable_arenas = true;
-option go_package = "github.com/golang/protobuf/ptypes/struct;structpb";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "StructProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-
-// `Struct` represents a structured data value, consisting of fields
-// which map to dynamically typed values. In some languages, `Struct`
-// might be supported by a native representation. For example, in
-// scripting languages like JS a struct is represented as an
-// object. The details of that representation are described together
-// with the proto support for the language.
-//
-// The JSON representation for `Struct` is JSON object.
-message Struct {
-  // Unordered map of dynamically typed values.
-  map<string, Value> fields = 1;
-}
-
-// `Value` represents a dynamically typed value which can be either
-// null, a number, a string, a boolean, a recursive struct value, or a
-// list of values. A producer of value is expected to set one of that
-// variants, absence of any variant indicates an error.
-//
-// The JSON representation for `Value` is JSON value.
-message Value {
-  // The kind of value.
-  oneof kind {
-    // Represents a null value.
-    NullValue null_value = 1;
-    // Represents a double value.
-    double number_value = 2;
-    // Represents a string value.
-    string string_value = 3;
-    // Represents a boolean value.
-    bool bool_value = 4;
-    // Represents a structured value.
-    Struct struct_value = 5;
-    // Represents a repeated `Value`.
-    ListValue list_value = 6;
-  }
-}
-
-// `NullValue` is a singleton enumeration to represent the null value for the
-// `Value` type union.
-//
-//  The JSON representation for `NullValue` is JSON `null`.
-enum NullValue {
-  // Null value.
-  NULL_VALUE = 0;
-}
-
-// `ListValue` is a wrapper around a repeated field of values.
-//
-// The JSON representation for `ListValue` is JSON array.
-message ListValue {
-  // Repeated field of dynamically typed values.
-  repeated Value values = 1;
-}
diff --git a/vendor/github.com/gorilla/websocket/.gitignore b/vendor/github.com/gorilla/websocket/.gitignore
deleted file mode 100644
index cd3fcd1..0000000
--- a/vendor/github.com/gorilla/websocket/.gitignore
+++ /dev/null
@@ -1,25 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-
-.idea/
-*.iml
diff --git a/vendor/github.com/gorilla/websocket/.travis.yml b/vendor/github.com/gorilla/websocket/.travis.yml
deleted file mode 100644
index a49db51..0000000
--- a/vendor/github.com/gorilla/websocket/.travis.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-language: go
-sudo: false
-
-matrix:
-  include:
-    - go: 1.7.x
-    - go: 1.8.x
-    - go: 1.9.x
-    - go: 1.10.x
-    - go: 1.11.x
-    - go: tip
-  allow_failures:
-    - go: tip
-
-script:
-  - go get -t -v ./...
-  - diff -u <(echo -n) <(gofmt -d .)
-  - go vet $(go list ./... | grep -v /vendor/)
-  - go test -v -race ./...
diff --git a/vendor/github.com/gorilla/websocket/AUTHORS b/vendor/github.com/gorilla/websocket/AUTHORS
deleted file mode 100644
index 1931f40..0000000
--- a/vendor/github.com/gorilla/websocket/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# This is the official list of Gorilla WebSocket authors for copyright
-# purposes.
-#
-# Please keep the list sorted.
-
-Gary Burd <gary@beagledreams.com>
-Google LLC (https://opensource.google.com/)
-Joachim Bauch <mail@joachim-bauch.de>
-
diff --git a/vendor/github.com/gorilla/websocket/LICENSE b/vendor/github.com/gorilla/websocket/LICENSE
deleted file mode 100644
index 9171c97..0000000
--- a/vendor/github.com/gorilla/websocket/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-  Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-  Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md
deleted file mode 100644
index 20e391f..0000000
--- a/vendor/github.com/gorilla/websocket/README.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# Gorilla WebSocket
-
-Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
-[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
-
-[![Build Status](https://travis-ci.org/gorilla/websocket.svg?branch=master)](https://travis-ci.org/gorilla/websocket)
-[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)
-
-### Documentation
-
-* [API Reference](http://godoc.org/github.com/gorilla/websocket)
-* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)
-* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)
-* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)
-* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)
-
-### Status
-
-The Gorilla WebSocket package provides a complete and tested implementation of
-the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The
-package API is stable.
-
-### Installation
-
-    go get github.com/gorilla/websocket
-
-### Protocol Compliance
-
-The Gorilla WebSocket package passes the server tests in the [Autobahn Test
-Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn
-subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
-
-### Gorilla WebSocket compared with other packages
-
-<table>
-<tr>
-<th></th>
-<th><a href="http://godoc.org/github.com/gorilla/websocket">github.com/gorilla</a></th>
-<th><a href="http://godoc.org/golang.org/x/net/websocket">golang.org/x/net</a></th>
-</tr>
-<tr>
-<tr><td colspan="3"><a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> Features</td></tr>
-<tr><td>Passes <a href="http://autobahn.ws/testsuite/">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr>
-<tr><td>Receive <a href="https://tools.ietf.org/html/rfc6455#section-5.4">fragmented</a> message<td>Yes</td><td><a href="https://code.google.com/p/go/issues/detail?id=7632">No</a>, see note 1</td></tr>
-<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close</a> message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=4588">No</a></td></tr>
-<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">pings</a> and receive <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pongs</a></td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td>No</td></tr>
-<tr><td>Get the <a href="https://tools.ietf.org/html/rfc6455#section-5.6">type</a> of a received data message</td><td>Yes</td><td>Yes, see note 2</td></tr>
-<tr><td colspan="3">Other Features</tr></td>
-<tr><td><a href="https://tools.ietf.org/html/rfc7692">Compression Extensions</a></td><td>Experimental</td><td>No</td></tr>
-<tr><td>Read message using io.Reader</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextReader">Yes</a></td><td>No, see note 3</td></tr>
-<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr>
-</table>
-
-Notes:
-
-1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
-2. The application can get the type of a received data message by implementing
-   a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal)
-   function.
-3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries.
-  Read returns when the input buffer is full or a frame boundary is
-  encountered. Each call to Write sends a single frame message. The Gorilla
-  io.Reader and io.WriteCloser operate on a single WebSocket message.
-
diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go
deleted file mode 100644
index 2e32fd5..0000000
--- a/vendor/github.com/gorilla/websocket/client.go
+++ /dev/null
@@ -1,395 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"bytes"
-	"context"
-	"crypto/tls"
-	"errors"
-	"io"
-	"io/ioutil"
-	"net"
-	"net/http"
-	"net/http/httptrace"
-	"net/url"
-	"strings"
-	"time"
-)
-
-// ErrBadHandshake is returned when the server response to opening handshake is
-// invalid.
-var ErrBadHandshake = errors.New("websocket: bad handshake")
-
-var errInvalidCompression = errors.New("websocket: invalid compression negotiation")
-
-// NewClient creates a new client connection using the given net connection.
-// The URL u specifies the host and request URI. Use requestHeader to specify
-// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies
-// (Cookie). Use the response.Header to get the selected subprotocol
-// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
-//
-// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
-// non-nil *http.Response so that callers can handle redirects, authentication,
-// etc.
-//
-// Deprecated: Use Dialer instead.
-func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {
-	d := Dialer{
-		ReadBufferSize:  readBufSize,
-		WriteBufferSize: writeBufSize,
-		NetDial: func(net, addr string) (net.Conn, error) {
-			return netConn, nil
-		},
-	}
-	return d.Dial(u.String(), requestHeader)
-}
-
-// A Dialer contains options for connecting to WebSocket server.
-type Dialer struct {
-	// NetDial specifies the dial function for creating TCP connections. If
-	// NetDial is nil, net.Dial is used.
-	NetDial func(network, addr string) (net.Conn, error)
-
-	// NetDialContext specifies the dial function for creating TCP connections. If
-	// NetDialContext is nil, net.DialContext is used.
-	NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error)
-
-	// Proxy specifies a function to return a proxy for a given
-	// Request. If the function returns a non-nil error, the
-	// request is aborted with the provided error.
-	// If Proxy is nil or returns a nil *URL, no proxy is used.
-	Proxy func(*http.Request) (*url.URL, error)
-
-	// TLSClientConfig specifies the TLS configuration to use with tls.Client.
-	// If nil, the default configuration is used.
-	TLSClientConfig *tls.Config
-
-	// HandshakeTimeout specifies the duration for the handshake to complete.
-	HandshakeTimeout time.Duration
-
-	// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
-	// size is zero, then a useful default size is used. The I/O buffer sizes
-	// do not limit the size of the messages that can be sent or received.
-	ReadBufferSize, WriteBufferSize int
-
-	// WriteBufferPool is a pool of buffers for write operations. If the value
-	// is not set, then write buffers are allocated to the connection for the
-	// lifetime of the connection.
-	//
-	// A pool is most useful when the application has a modest volume of writes
-	// across a large number of connections.
-	//
-	// Applications should use a single pool for each unique value of
-	// WriteBufferSize.
-	WriteBufferPool BufferPool
-
-	// Subprotocols specifies the client's requested subprotocols.
-	Subprotocols []string
-
-	// EnableCompression specifies if the client should attempt to negotiate
-	// per message compression (RFC 7692). Setting this value to true does not
-	// guarantee that compression will be supported. Currently only "no context
-	// takeover" modes are supported.
-	EnableCompression bool
-
-	// Jar specifies the cookie jar.
-	// If Jar is nil, cookies are not sent in requests and ignored
-	// in responses.
-	Jar http.CookieJar
-}
-
-// Dial creates a new client connection by calling DialContext with a background context.
-func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
-	return d.DialContext(context.Background(), urlStr, requestHeader)
-}
-
-var errMalformedURL = errors.New("malformed ws or wss URL")
-
-func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
-	hostPort = u.Host
-	hostNoPort = u.Host
-	if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") {
-		hostNoPort = hostNoPort[:i]
-	} else {
-		switch u.Scheme {
-		case "wss":
-			hostPort += ":443"
-		case "https":
-			hostPort += ":443"
-		default:
-			hostPort += ":80"
-		}
-	}
-	return hostPort, hostNoPort
-}
-
-// DefaultDialer is a dialer with all fields set to the default values.
-var DefaultDialer = &Dialer{
-	Proxy:            http.ProxyFromEnvironment,
-	HandshakeTimeout: 45 * time.Second,
-}
-
-// nilDialer is dialer to use when receiver is nil.
-var nilDialer = *DefaultDialer
-
-// DialContext creates a new client connection. Use requestHeader to specify the
-// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).
-// Use the response.Header to get the selected subprotocol
-// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
-//
-// The context will be used in the request and in the Dialer
-//
-// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
-// non-nil *http.Response so that callers can handle redirects, authentication,
-// etcetera. The response body may not contain the entire response and does not
-// need to be closed by the application.
-func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
-	if d == nil {
-		d = &nilDialer
-	}
-
-	challengeKey, err := generateChallengeKey()
-	if err != nil {
-		return nil, nil, err
-	}
-
-	u, err := url.Parse(urlStr)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	switch u.Scheme {
-	case "ws":
-		u.Scheme = "http"
-	case "wss":
-		u.Scheme = "https"
-	default:
-		return nil, nil, errMalformedURL
-	}
-
-	if u.User != nil {
-		// User name and password are not allowed in websocket URIs.
-		return nil, nil, errMalformedURL
-	}
-
-	req := &http.Request{
-		Method:     "GET",
-		URL:        u,
-		Proto:      "HTTP/1.1",
-		ProtoMajor: 1,
-		ProtoMinor: 1,
-		Header:     make(http.Header),
-		Host:       u.Host,
-	}
-	req = req.WithContext(ctx)
-
-	// Set the cookies present in the cookie jar of the dialer
-	if d.Jar != nil {
-		for _, cookie := range d.Jar.Cookies(u) {
-			req.AddCookie(cookie)
-		}
-	}
-
-	// Set the request headers using the capitalization for names and values in
-	// RFC examples. Although the capitalization shouldn't matter, there are
-	// servers that depend on it. The Header.Set method is not used because the
-	// method canonicalizes the header names.
-	req.Header["Upgrade"] = []string{"websocket"}
-	req.Header["Connection"] = []string{"Upgrade"}
-	req.Header["Sec-WebSocket-Key"] = []string{challengeKey}
-	req.Header["Sec-WebSocket-Version"] = []string{"13"}
-	if len(d.Subprotocols) > 0 {
-		req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")}
-	}
-	for k, vs := range requestHeader {
-		switch {
-		case k == "Host":
-			if len(vs) > 0 {
-				req.Host = vs[0]
-			}
-		case k == "Upgrade" ||
-			k == "Connection" ||
-			k == "Sec-Websocket-Key" ||
-			k == "Sec-Websocket-Version" ||
-			k == "Sec-Websocket-Extensions" ||
-			(k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
-			return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
-		case k == "Sec-Websocket-Protocol":
-			req.Header["Sec-WebSocket-Protocol"] = vs
-		default:
-			req.Header[k] = vs
-		}
-	}
-
-	if d.EnableCompression {
-		req.Header["Sec-WebSocket-Extensions"] = []string{"permessage-deflate; server_no_context_takeover; client_no_context_takeover"}
-	}
-
-	if d.HandshakeTimeout != 0 {
-		var cancel func()
-		ctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout)
-		defer cancel()
-	}
-
-	// Get network dial function.
-	var netDial func(network, add string) (net.Conn, error)
-
-	if d.NetDialContext != nil {
-		netDial = func(network, addr string) (net.Conn, error) {
-			return d.NetDialContext(ctx, network, addr)
-		}
-	} else if d.NetDial != nil {
-		netDial = d.NetDial
-	} else {
-		netDialer := &net.Dialer{}
-		netDial = func(network, addr string) (net.Conn, error) {
-			return netDialer.DialContext(ctx, network, addr)
-		}
-	}
-
-	// If needed, wrap the dial function to set the connection deadline.
-	if deadline, ok := ctx.Deadline(); ok {
-		forwardDial := netDial
-		netDial = func(network, addr string) (net.Conn, error) {
-			c, err := forwardDial(network, addr)
-			if err != nil {
-				return nil, err
-			}
-			err = c.SetDeadline(deadline)
-			if err != nil {
-				c.Close()
-				return nil, err
-			}
-			return c, nil
-		}
-	}
-
-	// If needed, wrap the dial function to connect through a proxy.
-	if d.Proxy != nil {
-		proxyURL, err := d.Proxy(req)
-		if err != nil {
-			return nil, nil, err
-		}
-		if proxyURL != nil {
-			dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial))
-			if err != nil {
-				return nil, nil, err
-			}
-			netDial = dialer.Dial
-		}
-	}
-
-	hostPort, hostNoPort := hostPortNoPort(u)
-	trace := httptrace.ContextClientTrace(ctx)
-	if trace != nil && trace.GetConn != nil {
-		trace.GetConn(hostPort)
-	}
-
-	netConn, err := netDial("tcp", hostPort)
-	if trace != nil && trace.GotConn != nil {
-		trace.GotConn(httptrace.GotConnInfo{
-			Conn: netConn,
-		})
-	}
-	if err != nil {
-		return nil, nil, err
-	}
-
-	defer func() {
-		if netConn != nil {
-			netConn.Close()
-		}
-	}()
-
-	if u.Scheme == "https" {
-		cfg := cloneTLSConfig(d.TLSClientConfig)
-		if cfg.ServerName == "" {
-			cfg.ServerName = hostNoPort
-		}
-		tlsConn := tls.Client(netConn, cfg)
-		netConn = tlsConn
-
-		var err error
-		if trace != nil {
-			err = doHandshakeWithTrace(trace, tlsConn, cfg)
-		} else {
-			err = doHandshake(tlsConn, cfg)
-		}
-
-		if err != nil {
-			return nil, nil, err
-		}
-	}
-
-	conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil)
-
-	if err := req.Write(netConn); err != nil {
-		return nil, nil, err
-	}
-
-	if trace != nil && trace.GotFirstResponseByte != nil {
-		if peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 {
-			trace.GotFirstResponseByte()
-		}
-	}
-
-	resp, err := http.ReadResponse(conn.br, req)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	if d.Jar != nil {
-		if rc := resp.Cookies(); len(rc) > 0 {
-			d.Jar.SetCookies(u, rc)
-		}
-	}
-
-	if resp.StatusCode != 101 ||
-		!strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") ||
-		!strings.EqualFold(resp.Header.Get("Connection"), "upgrade") ||
-		resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) {
-		// Before closing the network connection on return from this
-		// function, slurp up some of the response to aid application
-		// debugging.
-		buf := make([]byte, 1024)
-		n, _ := io.ReadFull(resp.Body, buf)
-		resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
-		return nil, resp, ErrBadHandshake
-	}
-
-	for _, ext := range parseExtensions(resp.Header) {
-		if ext[""] != "permessage-deflate" {
-			continue
-		}
-		_, snct := ext["server_no_context_takeover"]
-		_, cnct := ext["client_no_context_takeover"]
-		if !snct || !cnct {
-			return nil, resp, errInvalidCompression
-		}
-		conn.newCompressionWriter = compressNoContextTakeover
-		conn.newDecompressionReader = decompressNoContextTakeover
-		break
-	}
-
-	resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
-	conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
-
-	netConn.SetDeadline(time.Time{})
-	netConn = nil // to avoid close in defer.
-	return conn, resp, nil
-}
-
-func doHandshake(tlsConn *tls.Conn, cfg *tls.Config) error {
-	if err := tlsConn.Handshake(); err != nil {
-		return err
-	}
-	if !cfg.InsecureSkipVerify {
-		if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/gorilla/websocket/client_clone.go b/vendor/github.com/gorilla/websocket/client_clone.go
deleted file mode 100644
index 4f0d943..0000000
--- a/vendor/github.com/gorilla/websocket/client_clone.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.8
-
-package websocket
-
-import "crypto/tls"
-
-func cloneTLSConfig(cfg *tls.Config) *tls.Config {
-	if cfg == nil {
-		return &tls.Config{}
-	}
-	return cfg.Clone()
-}
diff --git a/vendor/github.com/gorilla/websocket/client_clone_legacy.go b/vendor/github.com/gorilla/websocket/client_clone_legacy.go
deleted file mode 100644
index babb007..0000000
--- a/vendor/github.com/gorilla/websocket/client_clone_legacy.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.8
-
-package websocket
-
-import "crypto/tls"
-
-// cloneTLSConfig clones all public fields except the fields
-// SessionTicketsDisabled and SessionTicketKey. This avoids copying the
-// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a
-// config in active use.
-func cloneTLSConfig(cfg *tls.Config) *tls.Config {
-	if cfg == nil {
-		return &tls.Config{}
-	}
-	return &tls.Config{
-		Rand:                     cfg.Rand,
-		Time:                     cfg.Time,
-		Certificates:             cfg.Certificates,
-		NameToCertificate:        cfg.NameToCertificate,
-		GetCertificate:           cfg.GetCertificate,
-		RootCAs:                  cfg.RootCAs,
-		NextProtos:               cfg.NextProtos,
-		ServerName:               cfg.ServerName,
-		ClientAuth:               cfg.ClientAuth,
-		ClientCAs:                cfg.ClientCAs,
-		InsecureSkipVerify:       cfg.InsecureSkipVerify,
-		CipherSuites:             cfg.CipherSuites,
-		PreferServerCipherSuites: cfg.PreferServerCipherSuites,
-		ClientSessionCache:       cfg.ClientSessionCache,
-		MinVersion:               cfg.MinVersion,
-		MaxVersion:               cfg.MaxVersion,
-		CurvePreferences:         cfg.CurvePreferences,
-	}
-}
diff --git a/vendor/github.com/gorilla/websocket/compression.go b/vendor/github.com/gorilla/websocket/compression.go
deleted file mode 100644
index 813ffb1..0000000
--- a/vendor/github.com/gorilla/websocket/compression.go
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"compress/flate"
-	"errors"
-	"io"
-	"strings"
-	"sync"
-)
-
-const (
-	minCompressionLevel     = -2 // flate.HuffmanOnly not defined in Go < 1.6
-	maxCompressionLevel     = flate.BestCompression
-	defaultCompressionLevel = 1
-)
-
-var (
-	flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool
-	flateReaderPool  = sync.Pool{New: func() interface{} {
-		return flate.NewReader(nil)
-	}}
-)
-
-func decompressNoContextTakeover(r io.Reader) io.ReadCloser {
-	const tail =
-	// Add four bytes as specified in RFC
-	"\x00\x00\xff\xff" +
-		// Add final block to squelch unexpected EOF error from flate reader.
-		"\x01\x00\x00\xff\xff"
-
-	fr, _ := flateReaderPool.Get().(io.ReadCloser)
-	fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil)
-	return &flateReadWrapper{fr}
-}
-
-func isValidCompressionLevel(level int) bool {
-	return minCompressionLevel <= level && level <= maxCompressionLevel
-}
-
-func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser {
-	p := &flateWriterPools[level-minCompressionLevel]
-	tw := &truncWriter{w: w}
-	fw, _ := p.Get().(*flate.Writer)
-	if fw == nil {
-		fw, _ = flate.NewWriter(tw, level)
-	} else {
-		fw.Reset(tw)
-	}
-	return &flateWriteWrapper{fw: fw, tw: tw, p: p}
-}
-
-// truncWriter is an io.Writer that writes all but the last four bytes of the
-// stream to another io.Writer.
-type truncWriter struct {
-	w io.WriteCloser
-	n int
-	p [4]byte
-}
-
-func (w *truncWriter) Write(p []byte) (int, error) {
-	n := 0
-
-	// fill buffer first for simplicity.
-	if w.n < len(w.p) {
-		n = copy(w.p[w.n:], p)
-		p = p[n:]
-		w.n += n
-		if len(p) == 0 {
-			return n, nil
-		}
-	}
-
-	m := len(p)
-	if m > len(w.p) {
-		m = len(w.p)
-	}
-
-	if nn, err := w.w.Write(w.p[:m]); err != nil {
-		return n + nn, err
-	}
-
-	copy(w.p[:], w.p[m:])
-	copy(w.p[len(w.p)-m:], p[len(p)-m:])
-	nn, err := w.w.Write(p[:len(p)-m])
-	return n + nn, err
-}
-
-type flateWriteWrapper struct {
-	fw *flate.Writer
-	tw *truncWriter
-	p  *sync.Pool
-}
-
-func (w *flateWriteWrapper) Write(p []byte) (int, error) {
-	if w.fw == nil {
-		return 0, errWriteClosed
-	}
-	return w.fw.Write(p)
-}
-
-func (w *flateWriteWrapper) Close() error {
-	if w.fw == nil {
-		return errWriteClosed
-	}
-	err1 := w.fw.Flush()
-	w.p.Put(w.fw)
-	w.fw = nil
-	if w.tw.p != [4]byte{0, 0, 0xff, 0xff} {
-		return errors.New("websocket: internal error, unexpected bytes at end of flate stream")
-	}
-	err2 := w.tw.w.Close()
-	if err1 != nil {
-		return err1
-	}
-	return err2
-}
-
-type flateReadWrapper struct {
-	fr io.ReadCloser
-}
-
-func (r *flateReadWrapper) Read(p []byte) (int, error) {
-	if r.fr == nil {
-		return 0, io.ErrClosedPipe
-	}
-	n, err := r.fr.Read(p)
-	if err == io.EOF {
-		// Preemptively place the reader back in the pool. This helps with
-		// scenarios where the application does not call NextReader() soon after
-		// this final read.
-		r.Close()
-	}
-	return n, err
-}
-
-func (r *flateReadWrapper) Close() error {
-	if r.fr == nil {
-		return io.ErrClosedPipe
-	}
-	err := r.fr.Close()
-	flateReaderPool.Put(r.fr)
-	r.fr = nil
-	return err
-}
diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go
deleted file mode 100644
index d2a21c1..0000000
--- a/vendor/github.com/gorilla/websocket/conn.go
+++ /dev/null
@@ -1,1165 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"bufio"
-	"encoding/binary"
-	"errors"
-	"io"
-	"io/ioutil"
-	"math/rand"
-	"net"
-	"strconv"
-	"sync"
-	"time"
-	"unicode/utf8"
-)
-
-const (
-	// Frame header byte 0 bits from Section 5.2 of RFC 6455
-	finalBit = 1 << 7
-	rsv1Bit  = 1 << 6
-	rsv2Bit  = 1 << 5
-	rsv3Bit  = 1 << 4
-
-	// Frame header byte 1 bits from Section 5.2 of RFC 6455
-	maskBit = 1 << 7
-
-	maxFrameHeaderSize         = 2 + 8 + 4 // Fixed header + length + mask
-	maxControlFramePayloadSize = 125
-
-	writeWait = time.Second
-
-	defaultReadBufferSize  = 4096
-	defaultWriteBufferSize = 4096
-
-	continuationFrame = 0
-	noFrame           = -1
-)
-
-// Close codes defined in RFC 6455, section 11.7.
-const (
-	CloseNormalClosure           = 1000
-	CloseGoingAway               = 1001
-	CloseProtocolError           = 1002
-	CloseUnsupportedData         = 1003
-	CloseNoStatusReceived        = 1005
-	CloseAbnormalClosure         = 1006
-	CloseInvalidFramePayloadData = 1007
-	ClosePolicyViolation         = 1008
-	CloseMessageTooBig           = 1009
-	CloseMandatoryExtension      = 1010
-	CloseInternalServerErr       = 1011
-	CloseServiceRestart          = 1012
-	CloseTryAgainLater           = 1013
-	CloseTLSHandshake            = 1015
-)
-
-// The message types are defined in RFC 6455, section 11.8.
-const (
-	// TextMessage denotes a text data message. The text message payload is
-	// interpreted as UTF-8 encoded text data.
-	TextMessage = 1
-
-	// BinaryMessage denotes a binary data message.
-	BinaryMessage = 2
-
-	// CloseMessage denotes a close control message. The optional message
-	// payload contains a numeric code and text. Use the FormatCloseMessage
-	// function to format a close message payload.
-	CloseMessage = 8
-
-	// PingMessage denotes a ping control message. The optional message payload
-	// is UTF-8 encoded text.
-	PingMessage = 9
-
-	// PongMessage denotes a pong control message. The optional message payload
-	// is UTF-8 encoded text.
-	PongMessage = 10
-)
-
-// ErrCloseSent is returned when the application writes a message to the
-// connection after sending a close message.
-var ErrCloseSent = errors.New("websocket: close sent")
-
-// ErrReadLimit is returned when reading a message that is larger than the
-// read limit set for the connection.
-var ErrReadLimit = errors.New("websocket: read limit exceeded")
-
-// netError satisfies the net Error interface.
-type netError struct {
-	msg       string
-	temporary bool
-	timeout   bool
-}
-
-func (e *netError) Error() string   { return e.msg }
-func (e *netError) Temporary() bool { return e.temporary }
-func (e *netError) Timeout() bool   { return e.timeout }
-
-// CloseError represents a close message.
-type CloseError struct {
-	// Code is defined in RFC 6455, section 11.7.
-	Code int
-
-	// Text is the optional text payload.
-	Text string
-}
-
-func (e *CloseError) Error() string {
-	s := []byte("websocket: close ")
-	s = strconv.AppendInt(s, int64(e.Code), 10)
-	switch e.Code {
-	case CloseNormalClosure:
-		s = append(s, " (normal)"...)
-	case CloseGoingAway:
-		s = append(s, " (going away)"...)
-	case CloseProtocolError:
-		s = append(s, " (protocol error)"...)
-	case CloseUnsupportedData:
-		s = append(s, " (unsupported data)"...)
-	case CloseNoStatusReceived:
-		s = append(s, " (no status)"...)
-	case CloseAbnormalClosure:
-		s = append(s, " (abnormal closure)"...)
-	case CloseInvalidFramePayloadData:
-		s = append(s, " (invalid payload data)"...)
-	case ClosePolicyViolation:
-		s = append(s, " (policy violation)"...)
-	case CloseMessageTooBig:
-		s = append(s, " (message too big)"...)
-	case CloseMandatoryExtension:
-		s = append(s, " (mandatory extension missing)"...)
-	case CloseInternalServerErr:
-		s = append(s, " (internal server error)"...)
-	case CloseTLSHandshake:
-		s = append(s, " (TLS handshake error)"...)
-	}
-	if e.Text != "" {
-		s = append(s, ": "...)
-		s = append(s, e.Text...)
-	}
-	return string(s)
-}
-
-// IsCloseError returns boolean indicating whether the error is a *CloseError
-// with one of the specified codes.
-func IsCloseError(err error, codes ...int) bool {
-	if e, ok := err.(*CloseError); ok {
-		for _, code := range codes {
-			if e.Code == code {
-				return true
-			}
-		}
-	}
-	return false
-}
-
-// IsUnexpectedCloseError returns boolean indicating whether the error is a
-// *CloseError with a code not in the list of expected codes.
-func IsUnexpectedCloseError(err error, expectedCodes ...int) bool {
-	if e, ok := err.(*CloseError); ok {
-		for _, code := range expectedCodes {
-			if e.Code == code {
-				return false
-			}
-		}
-		return true
-	}
-	return false
-}
-
-var (
-	errWriteTimeout        = &netError{msg: "websocket: write timeout", timeout: true, temporary: true}
-	errUnexpectedEOF       = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}
-	errBadWriteOpCode      = errors.New("websocket: bad write message type")
-	errWriteClosed         = errors.New("websocket: write closed")
-	errInvalidControlFrame = errors.New("websocket: invalid control frame")
-)
-
-func newMaskKey() [4]byte {
-	n := rand.Uint32()
-	return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
-}
-
-func hideTempErr(err error) error {
-	if e, ok := err.(net.Error); ok && e.Temporary() {
-		err = &netError{msg: e.Error(), timeout: e.Timeout()}
-	}
-	return err
-}
-
-func isControl(frameType int) bool {
-	return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage
-}
-
-func isData(frameType int) bool {
-	return frameType == TextMessage || frameType == BinaryMessage
-}
-
-var validReceivedCloseCodes = map[int]bool{
-	// see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number
-
-	CloseNormalClosure:           true,
-	CloseGoingAway:               true,
-	CloseProtocolError:           true,
-	CloseUnsupportedData:         true,
-	CloseNoStatusReceived:        false,
-	CloseAbnormalClosure:         false,
-	CloseInvalidFramePayloadData: true,
-	ClosePolicyViolation:         true,
-	CloseMessageTooBig:           true,
-	CloseMandatoryExtension:      true,
-	CloseInternalServerErr:       true,
-	CloseServiceRestart:          true,
-	CloseTryAgainLater:           true,
-	CloseTLSHandshake:            false,
-}
-
-func isValidReceivedCloseCode(code int) bool {
-	return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)
-}
-
-// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this
-// interface.  The type of the value stored in a pool is not specified.
-type BufferPool interface {
-	// Get gets a value from the pool or returns nil if the pool is empty.
-	Get() interface{}
-	// Put adds a value to the pool.
-	Put(interface{})
-}
-
-// writePoolData is the type added to the write buffer pool. This wrapper is
-// used to prevent applications from peeking at and depending on the values
-// added to the pool.
-type writePoolData struct{ buf []byte }
-
-// The Conn type represents a WebSocket connection.
-type Conn struct {
-	conn        net.Conn
-	isServer    bool
-	subprotocol string
-
-	// Write fields
-	mu            chan bool // used as mutex to protect write to conn
-	writeBuf      []byte    // frame is constructed in this buffer.
-	writePool     BufferPool
-	writeBufSize  int
-	writeDeadline time.Time
-	writer        io.WriteCloser // the current writer returned to the application
-	isWriting     bool           // for best-effort concurrent write detection
-
-	writeErrMu sync.Mutex
-	writeErr   error
-
-	enableWriteCompression bool
-	compressionLevel       int
-	newCompressionWriter   func(io.WriteCloser, int) io.WriteCloser
-
-	// Read fields
-	reader        io.ReadCloser // the current reader returned to the application
-	readErr       error
-	br            *bufio.Reader
-	readRemaining int64 // bytes remaining in current frame.
-	readFinal     bool  // true the current message has more frames.
-	readLength    int64 // Message size.
-	readLimit     int64 // Maximum message size.
-	readMaskPos   int
-	readMaskKey   [4]byte
-	handlePong    func(string) error
-	handlePing    func(string) error
-	handleClose   func(int, string) error
-	readErrCount  int
-	messageReader *messageReader // the current low-level reader
-
-	readDecompress         bool // whether last read frame had RSV1 set
-	newDecompressionReader func(io.Reader) io.ReadCloser
-}
-
-func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn {
-
-	if br == nil {
-		if readBufferSize == 0 {
-			readBufferSize = defaultReadBufferSize
-		} else if readBufferSize < maxControlFramePayloadSize {
-			// must be large enough for control frame
-			readBufferSize = maxControlFramePayloadSize
-		}
-		br = bufio.NewReaderSize(conn, readBufferSize)
-	}
-
-	if writeBufferSize <= 0 {
-		writeBufferSize = defaultWriteBufferSize
-	}
-	writeBufferSize += maxFrameHeaderSize
-
-	if writeBuf == nil && writeBufferPool == nil {
-		writeBuf = make([]byte, writeBufferSize)
-	}
-
-	mu := make(chan bool, 1)
-	mu <- true
-	c := &Conn{
-		isServer:               isServer,
-		br:                     br,
-		conn:                   conn,
-		mu:                     mu,
-		readFinal:              true,
-		writeBuf:               writeBuf,
-		writePool:              writeBufferPool,
-		writeBufSize:           writeBufferSize,
-		enableWriteCompression: true,
-		compressionLevel:       defaultCompressionLevel,
-	}
-	c.SetCloseHandler(nil)
-	c.SetPingHandler(nil)
-	c.SetPongHandler(nil)
-	return c
-}
-
-// Subprotocol returns the negotiated protocol for the connection.
-func (c *Conn) Subprotocol() string {
-	return c.subprotocol
-}
-
-// Close closes the underlying network connection without sending or waiting
-// for a close message.
-func (c *Conn) Close() error {
-	return c.conn.Close()
-}
-
-// LocalAddr returns the local network address.
-func (c *Conn) LocalAddr() net.Addr {
-	return c.conn.LocalAddr()
-}
-
-// RemoteAddr returns the remote network address.
-func (c *Conn) RemoteAddr() net.Addr {
-	return c.conn.RemoteAddr()
-}
-
-// Write methods
-
-func (c *Conn) writeFatal(err error) error {
-	err = hideTempErr(err)
-	c.writeErrMu.Lock()
-	if c.writeErr == nil {
-		c.writeErr = err
-	}
-	c.writeErrMu.Unlock()
-	return err
-}
-
-func (c *Conn) read(n int) ([]byte, error) {
-	p, err := c.br.Peek(n)
-	if err == io.EOF {
-		err = errUnexpectedEOF
-	}
-	c.br.Discard(len(p))
-	return p, err
-}
-
-func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error {
-	<-c.mu
-	defer func() { c.mu <- true }()
-
-	c.writeErrMu.Lock()
-	err := c.writeErr
-	c.writeErrMu.Unlock()
-	if err != nil {
-		return err
-	}
-
-	c.conn.SetWriteDeadline(deadline)
-	if len(buf1) == 0 {
-		_, err = c.conn.Write(buf0)
-	} else {
-		err = c.writeBufs(buf0, buf1)
-	}
-	if err != nil {
-		return c.writeFatal(err)
-	}
-	if frameType == CloseMessage {
-		c.writeFatal(ErrCloseSent)
-	}
-	return nil
-}
-
-// WriteControl writes a control message with the given deadline. The allowed
-// message types are CloseMessage, PingMessage and PongMessage.
-func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {
-	if !isControl(messageType) {
-		return errBadWriteOpCode
-	}
-	if len(data) > maxControlFramePayloadSize {
-		return errInvalidControlFrame
-	}
-
-	b0 := byte(messageType) | finalBit
-	b1 := byte(len(data))
-	if !c.isServer {
-		b1 |= maskBit
-	}
-
-	buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize)
-	buf = append(buf, b0, b1)
-
-	if c.isServer {
-		buf = append(buf, data...)
-	} else {
-		key := newMaskKey()
-		buf = append(buf, key[:]...)
-		buf = append(buf, data...)
-		maskBytes(key, 0, buf[6:])
-	}
-
-	d := time.Hour * 1000
-	if !deadline.IsZero() {
-		d = deadline.Sub(time.Now())
-		if d < 0 {
-			return errWriteTimeout
-		}
-	}
-
-	timer := time.NewTimer(d)
-	select {
-	case <-c.mu:
-		timer.Stop()
-	case <-timer.C:
-		return errWriteTimeout
-	}
-	defer func() { c.mu <- true }()
-
-	c.writeErrMu.Lock()
-	err := c.writeErr
-	c.writeErrMu.Unlock()
-	if err != nil {
-		return err
-	}
-
-	c.conn.SetWriteDeadline(deadline)
-	_, err = c.conn.Write(buf)
-	if err != nil {
-		return c.writeFatal(err)
-	}
-	if messageType == CloseMessage {
-		c.writeFatal(ErrCloseSent)
-	}
-	return err
-}
-
-func (c *Conn) prepWrite(messageType int) error {
-	// Close previous writer if not already closed by the application. It's
-	// probably better to return an error in this situation, but we cannot
-	// change this without breaking existing applications.
-	if c.writer != nil {
-		c.writer.Close()
-		c.writer = nil
-	}
-
-	if !isControl(messageType) && !isData(messageType) {
-		return errBadWriteOpCode
-	}
-
-	c.writeErrMu.Lock()
-	err := c.writeErr
-	c.writeErrMu.Unlock()
-	if err != nil {
-		return err
-	}
-
-	if c.writeBuf == nil {
-		wpd, ok := c.writePool.Get().(writePoolData)
-		if ok {
-			c.writeBuf = wpd.buf
-		} else {
-			c.writeBuf = make([]byte, c.writeBufSize)
-		}
-	}
-	return nil
-}
-
-// NextWriter returns a writer for the next message to send. The writer's Close
-// method flushes the complete message to the network.
-//
-// There can be at most one open writer on a connection. NextWriter closes the
-// previous writer if the application has not already done so.
-//
-// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and
-// PongMessage) are supported.
-func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
-	if err := c.prepWrite(messageType); err != nil {
-		return nil, err
-	}
-
-	mw := &messageWriter{
-		c:         c,
-		frameType: messageType,
-		pos:       maxFrameHeaderSize,
-	}
-	c.writer = mw
-	if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) {
-		w := c.newCompressionWriter(c.writer, c.compressionLevel)
-		mw.compress = true
-		c.writer = w
-	}
-	return c.writer, nil
-}
-
-type messageWriter struct {
-	c         *Conn
-	compress  bool // whether next call to flushFrame should set RSV1
-	pos       int  // end of data in writeBuf.
-	frameType int  // type of the current frame.
-	err       error
-}
-
-func (w *messageWriter) fatal(err error) error {
-	if w.err != nil {
-		w.err = err
-		w.c.writer = nil
-	}
-	return err
-}
-
-// flushFrame writes buffered data and extra as a frame to the network. The
-// final argument indicates that this is the last frame in the message.
-func (w *messageWriter) flushFrame(final bool, extra []byte) error {
-	c := w.c
-	length := w.pos - maxFrameHeaderSize + len(extra)
-
-	// Check for invalid control frames.
-	if isControl(w.frameType) &&
-		(!final || length > maxControlFramePayloadSize) {
-		return w.fatal(errInvalidControlFrame)
-	}
-
-	b0 := byte(w.frameType)
-	if final {
-		b0 |= finalBit
-	}
-	if w.compress {
-		b0 |= rsv1Bit
-	}
-	w.compress = false
-
-	b1 := byte(0)
-	if !c.isServer {
-		b1 |= maskBit
-	}
-
-	// Assume that the frame starts at beginning of c.writeBuf.
-	framePos := 0
-	if c.isServer {
-		// Adjust up if mask not included in the header.
-		framePos = 4
-	}
-
-	switch {
-	case length >= 65536:
-		c.writeBuf[framePos] = b0
-		c.writeBuf[framePos+1] = b1 | 127
-		binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length))
-	case length > 125:
-		framePos += 6
-		c.writeBuf[framePos] = b0
-		c.writeBuf[framePos+1] = b1 | 126
-		binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length))
-	default:
-		framePos += 8
-		c.writeBuf[framePos] = b0
-		c.writeBuf[framePos+1] = b1 | byte(length)
-	}
-
-	if !c.isServer {
-		key := newMaskKey()
-		copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
-		maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos])
-		if len(extra) > 0 {
-			return c.writeFatal(errors.New("websocket: internal error, extra used in client mode"))
-		}
-	}
-
-	// Write the buffers to the connection with best-effort detection of
-	// concurrent writes. See the concurrency section in the package
-	// documentation for more info.
-
-	if c.isWriting {
-		panic("concurrent write to websocket connection")
-	}
-	c.isWriting = true
-
-	err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra)
-
-	if !c.isWriting {
-		panic("concurrent write to websocket connection")
-	}
-	c.isWriting = false
-
-	if err != nil {
-		return w.fatal(err)
-	}
-
-	if final {
-		c.writer = nil
-		if c.writePool != nil {
-			c.writePool.Put(writePoolData{buf: c.writeBuf})
-			c.writeBuf = nil
-		}
-		return nil
-	}
-
-	// Setup for next frame.
-	w.pos = maxFrameHeaderSize
-	w.frameType = continuationFrame
-	return nil
-}
-
-func (w *messageWriter) ncopy(max int) (int, error) {
-	n := len(w.c.writeBuf) - w.pos
-	if n <= 0 {
-		if err := w.flushFrame(false, nil); err != nil {
-			return 0, err
-		}
-		n = len(w.c.writeBuf) - w.pos
-	}
-	if n > max {
-		n = max
-	}
-	return n, nil
-}
-
-func (w *messageWriter) Write(p []byte) (int, error) {
-	if w.err != nil {
-		return 0, w.err
-	}
-
-	if len(p) > 2*len(w.c.writeBuf) && w.c.isServer {
-		// Don't buffer large messages.
-		err := w.flushFrame(false, p)
-		if err != nil {
-			return 0, err
-		}
-		return len(p), nil
-	}
-
-	nn := len(p)
-	for len(p) > 0 {
-		n, err := w.ncopy(len(p))
-		if err != nil {
-			return 0, err
-		}
-		copy(w.c.writeBuf[w.pos:], p[:n])
-		w.pos += n
-		p = p[n:]
-	}
-	return nn, nil
-}
-
-func (w *messageWriter) WriteString(p string) (int, error) {
-	if w.err != nil {
-		return 0, w.err
-	}
-
-	nn := len(p)
-	for len(p) > 0 {
-		n, err := w.ncopy(len(p))
-		if err != nil {
-			return 0, err
-		}
-		copy(w.c.writeBuf[w.pos:], p[:n])
-		w.pos += n
-		p = p[n:]
-	}
-	return nn, nil
-}
-
-func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
-	if w.err != nil {
-		return 0, w.err
-	}
-	for {
-		if w.pos == len(w.c.writeBuf) {
-			err = w.flushFrame(false, nil)
-			if err != nil {
-				break
-			}
-		}
-		var n int
-		n, err = r.Read(w.c.writeBuf[w.pos:])
-		w.pos += n
-		nn += int64(n)
-		if err != nil {
-			if err == io.EOF {
-				err = nil
-			}
-			break
-		}
-	}
-	return nn, err
-}
-
-func (w *messageWriter) Close() error {
-	if w.err != nil {
-		return w.err
-	}
-	if err := w.flushFrame(true, nil); err != nil {
-		return err
-	}
-	w.err = errWriteClosed
-	return nil
-}
-
-// WritePreparedMessage writes prepared message into connection.
-func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error {
-	frameType, frameData, err := pm.frame(prepareKey{
-		isServer:         c.isServer,
-		compress:         c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType),
-		compressionLevel: c.compressionLevel,
-	})
-	if err != nil {
-		return err
-	}
-	if c.isWriting {
-		panic("concurrent write to websocket connection")
-	}
-	c.isWriting = true
-	err = c.write(frameType, c.writeDeadline, frameData, nil)
-	if !c.isWriting {
-		panic("concurrent write to websocket connection")
-	}
-	c.isWriting = false
-	return err
-}
-
-// WriteMessage is a helper method for getting a writer using NextWriter,
-// writing the message and closing the writer.
-func (c *Conn) WriteMessage(messageType int, data []byte) error {
-
-	if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) {
-		// Fast path with no allocations and single frame.
-
-		if err := c.prepWrite(messageType); err != nil {
-			return err
-		}
-		mw := messageWriter{c: c, frameType: messageType, pos: maxFrameHeaderSize}
-		n := copy(c.writeBuf[mw.pos:], data)
-		mw.pos += n
-		data = data[n:]
-		return mw.flushFrame(true, data)
-	}
-
-	w, err := c.NextWriter(messageType)
-	if err != nil {
-		return err
-	}
-	if _, err = w.Write(data); err != nil {
-		return err
-	}
-	return w.Close()
-}
-
-// SetWriteDeadline sets the write deadline on the underlying network
-// connection. After a write has timed out, the websocket state is corrupt and
-// all future writes will return an error. A zero value for t means writes will
-// not time out.
-func (c *Conn) SetWriteDeadline(t time.Time) error {
-	c.writeDeadline = t
-	return nil
-}
-
-// Read methods
-
-func (c *Conn) advanceFrame() (int, error) {
-	// 1. Skip remainder of previous frame.
-
-	if c.readRemaining > 0 {
-		if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {
-			return noFrame, err
-		}
-	}
-
-	// 2. Read and parse first two bytes of frame header.
-
-	p, err := c.read(2)
-	if err != nil {
-		return noFrame, err
-	}
-
-	final := p[0]&finalBit != 0
-	frameType := int(p[0] & 0xf)
-	mask := p[1]&maskBit != 0
-	c.readRemaining = int64(p[1] & 0x7f)
-
-	c.readDecompress = false
-	if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 {
-		c.readDecompress = true
-		p[0] &^= rsv1Bit
-	}
-
-	if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 {
-		return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16))
-	}
-
-	switch frameType {
-	case CloseMessage, PingMessage, PongMessage:
-		if c.readRemaining > maxControlFramePayloadSize {
-			return noFrame, c.handleProtocolError("control frame length > 125")
-		}
-		if !final {
-			return noFrame, c.handleProtocolError("control frame not final")
-		}
-	case TextMessage, BinaryMessage:
-		if !c.readFinal {
-			return noFrame, c.handleProtocolError("message start before final message frame")
-		}
-		c.readFinal = final
-	case continuationFrame:
-		if c.readFinal {
-			return noFrame, c.handleProtocolError("continuation after final message frame")
-		}
-		c.readFinal = final
-	default:
-		return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType))
-	}
-
-	// 3. Read and parse frame length.
-
-	switch c.readRemaining {
-	case 126:
-		p, err := c.read(2)
-		if err != nil {
-			return noFrame, err
-		}
-		c.readRemaining = int64(binary.BigEndian.Uint16(p))
-	case 127:
-		p, err := c.read(8)
-		if err != nil {
-			return noFrame, err
-		}
-		c.readRemaining = int64(binary.BigEndian.Uint64(p))
-	}
-
-	// 4. Handle frame masking.
-
-	if mask != c.isServer {
-		return noFrame, c.handleProtocolError("incorrect mask flag")
-	}
-
-	if mask {
-		c.readMaskPos = 0
-		p, err := c.read(len(c.readMaskKey))
-		if err != nil {
-			return noFrame, err
-		}
-		copy(c.readMaskKey[:], p)
-	}
-
-	// 5. For text and binary messages, enforce read limit and return.
-
-	if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {
-
-		c.readLength += c.readRemaining
-		if c.readLimit > 0 && c.readLength > c.readLimit {
-			c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))
-			return noFrame, ErrReadLimit
-		}
-
-		return frameType, nil
-	}
-
-	// 6. Read control frame payload.
-
-	var payload []byte
-	if c.readRemaining > 0 {
-		payload, err = c.read(int(c.readRemaining))
-		c.readRemaining = 0
-		if err != nil {
-			return noFrame, err
-		}
-		if c.isServer {
-			maskBytes(c.readMaskKey, 0, payload)
-		}
-	}
-
-	// 7. Process control frame payload.
-
-	switch frameType {
-	case PongMessage:
-		if err := c.handlePong(string(payload)); err != nil {
-			return noFrame, err
-		}
-	case PingMessage:
-		if err := c.handlePing(string(payload)); err != nil {
-			return noFrame, err
-		}
-	case CloseMessage:
-		closeCode := CloseNoStatusReceived
-		closeText := ""
-		if len(payload) >= 2 {
-			closeCode = int(binary.BigEndian.Uint16(payload))
-			if !isValidReceivedCloseCode(closeCode) {
-				return noFrame, c.handleProtocolError("invalid close code")
-			}
-			closeText = string(payload[2:])
-			if !utf8.ValidString(closeText) {
-				return noFrame, c.handleProtocolError("invalid utf8 payload in close frame")
-			}
-		}
-		if err := c.handleClose(closeCode, closeText); err != nil {
-			return noFrame, err
-		}
-		return noFrame, &CloseError{Code: closeCode, Text: closeText}
-	}
-
-	return frameType, nil
-}
-
-func (c *Conn) handleProtocolError(message string) error {
-	c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait))
-	return errors.New("websocket: " + message)
-}
-
-// NextReader returns the next data message received from the peer. The
-// returned messageType is either TextMessage or BinaryMessage.
-//
-// There can be at most one open reader on a connection. NextReader discards
-// the previous message if the application has not already consumed it.
-//
-// Applications must break out of the application's read loop when this method
-// returns a non-nil error value. Errors returned from this method are
-// permanent. Once this method returns a non-nil error, all subsequent calls to
-// this method return the same error.
-func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
-	// Close previous reader, only relevant for decompression.
-	if c.reader != nil {
-		c.reader.Close()
-		c.reader = nil
-	}
-
-	c.messageReader = nil
-	c.readLength = 0
-
-	for c.readErr == nil {
-		frameType, err := c.advanceFrame()
-		if err != nil {
-			c.readErr = hideTempErr(err)
-			break
-		}
-		if frameType == TextMessage || frameType == BinaryMessage {
-			c.messageReader = &messageReader{c}
-			c.reader = c.messageReader
-			if c.readDecompress {
-				c.reader = c.newDecompressionReader(c.reader)
-			}
-			return frameType, c.reader, nil
-		}
-	}
-
-	// Applications that do handle the error returned from this method spin in
-	// tight loop on connection failure. To help application developers detect
-	// this error, panic on repeated reads to the failed connection.
-	c.readErrCount++
-	if c.readErrCount >= 1000 {
-		panic("repeated read on failed websocket connection")
-	}
-
-	return noFrame, nil, c.readErr
-}
-
-type messageReader struct{ c *Conn }
-
-func (r *messageReader) Read(b []byte) (int, error) {
-	c := r.c
-	if c.messageReader != r {
-		return 0, io.EOF
-	}
-
-	for c.readErr == nil {
-
-		if c.readRemaining > 0 {
-			if int64(len(b)) > c.readRemaining {
-				b = b[:c.readRemaining]
-			}
-			n, err := c.br.Read(b)
-			c.readErr = hideTempErr(err)
-			if c.isServer {
-				c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])
-			}
-			c.readRemaining -= int64(n)
-			if c.readRemaining > 0 && c.readErr == io.EOF {
-				c.readErr = errUnexpectedEOF
-			}
-			return n, c.readErr
-		}
-
-		if c.readFinal {
-			c.messageReader = nil
-			return 0, io.EOF
-		}
-
-		frameType, err := c.advanceFrame()
-		switch {
-		case err != nil:
-			c.readErr = hideTempErr(err)
-		case frameType == TextMessage || frameType == BinaryMessage:
-			c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
-		}
-	}
-
-	err := c.readErr
-	if err == io.EOF && c.messageReader == r {
-		err = errUnexpectedEOF
-	}
-	return 0, err
-}
-
-func (r *messageReader) Close() error {
-	return nil
-}
-
-// ReadMessage is a helper method for getting a reader using NextReader and
-// reading from that reader to a buffer.
-func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
-	var r io.Reader
-	messageType, r, err = c.NextReader()
-	if err != nil {
-		return messageType, nil, err
-	}
-	p, err = ioutil.ReadAll(r)
-	return messageType, p, err
-}
-
-// SetReadDeadline sets the read deadline on the underlying network connection.
-// After a read has timed out, the websocket connection state is corrupt and
-// all future reads will return an error. A zero value for t means reads will
-// not time out.
-func (c *Conn) SetReadDeadline(t time.Time) error {
-	return c.conn.SetReadDeadline(t)
-}
-
-// SetReadLimit sets the maximum size for a message read from the peer. If a
-// message exceeds the limit, the connection sends a close message to the peer
-// and returns ErrReadLimit to the application.
-func (c *Conn) SetReadLimit(limit int64) {
-	c.readLimit = limit
-}
-
-// CloseHandler returns the current close handler
-func (c *Conn) CloseHandler() func(code int, text string) error {
-	return c.handleClose
-}
-
-// SetCloseHandler sets the handler for close messages received from the peer.
-// The code argument to h is the received close code or CloseNoStatusReceived
-// if the close message is empty. The default close handler sends a close
-// message back to the peer.
-//
-// The handler function is called from the NextReader, ReadMessage and message
-// reader Read methods. The application must read the connection to process
-// close messages as described in the section on Control Messages above.
-//
-// The connection read methods return a CloseError when a close message is
-// received. Most applications should handle close messages as part of their
-// normal error handling. Applications should only set a close handler when the
-// application must perform some action before sending a close message back to
-// the peer.
-func (c *Conn) SetCloseHandler(h func(code int, text string) error) {
-	if h == nil {
-		h = func(code int, text string) error {
-			message := FormatCloseMessage(code, "")
-			c.WriteControl(CloseMessage, message, time.Now().Add(writeWait))
-			return nil
-		}
-	}
-	c.handleClose = h
-}
-
-// PingHandler returns the current ping handler
-func (c *Conn) PingHandler() func(appData string) error {
-	return c.handlePing
-}
-
-// SetPingHandler sets the handler for ping messages received from the peer.
-// The appData argument to h is the PING message application data. The default
-// ping handler sends a pong to the peer.
-//
-// The handler function is called from the NextReader, ReadMessage and message
-// reader Read methods. The application must read the connection to process
-// ping messages as described in the section on Control Messages above.
-func (c *Conn) SetPingHandler(h func(appData string) error) {
-	if h == nil {
-		h = func(message string) error {
-			err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
-			if err == ErrCloseSent {
-				return nil
-			} else if e, ok := err.(net.Error); ok && e.Temporary() {
-				return nil
-			}
-			return err
-		}
-	}
-	c.handlePing = h
-}
-
-// PongHandler returns the current pong handler
-func (c *Conn) PongHandler() func(appData string) error {
-	return c.handlePong
-}
-
-// SetPongHandler sets the handler for pong messages received from the peer.
-// The appData argument to h is the PONG message application data. The default
-// pong handler does nothing.
-//
-// The handler function is called from the NextReader, ReadMessage and message
-// reader Read methods. The application must read the connection to process
-// pong messages as described in the section on Control Messages above.
-func (c *Conn) SetPongHandler(h func(appData string) error) {
-	if h == nil {
-		h = func(string) error { return nil }
-	}
-	c.handlePong = h
-}
-
-// UnderlyingConn returns the internal net.Conn. This can be used to further
-// modifications to connection specific flags.
-func (c *Conn) UnderlyingConn() net.Conn {
-	return c.conn
-}
-
-// EnableWriteCompression enables and disables write compression of
-// subsequent text and binary messages. This function is a noop if
-// compression was not negotiated with the peer.
-func (c *Conn) EnableWriteCompression(enable bool) {
-	c.enableWriteCompression = enable
-}
-
-// SetCompressionLevel sets the flate compression level for subsequent text and
-// binary messages. This function is a noop if compression was not negotiated
-// with the peer. See the compress/flate package for a description of
-// compression levels.
-func (c *Conn) SetCompressionLevel(level int) error {
-	if !isValidCompressionLevel(level) {
-		return errors.New("websocket: invalid compression level")
-	}
-	c.compressionLevel = level
-	return nil
-}
-
-// FormatCloseMessage formats closeCode and text as a WebSocket close message.
-// An empty message is returned for code CloseNoStatusReceived.
-func FormatCloseMessage(closeCode int, text string) []byte {
-	if closeCode == CloseNoStatusReceived {
-		// Return empty message because it's illegal to send
-		// CloseNoStatusReceived. Return non-nil value in case application
-		// checks for nil.
-		return []byte{}
-	}
-	buf := make([]byte, 2+len(text))
-	binary.BigEndian.PutUint16(buf, uint16(closeCode))
-	copy(buf[2:], text)
-	return buf
-}
diff --git a/vendor/github.com/gorilla/websocket/conn_write.go b/vendor/github.com/gorilla/websocket/conn_write.go
deleted file mode 100644
index a509a21..0000000
--- a/vendor/github.com/gorilla/websocket/conn_write.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.8
-
-package websocket
-
-import "net"
-
-func (c *Conn) writeBufs(bufs ...[]byte) error {
-	b := net.Buffers(bufs)
-	_, err := b.WriteTo(c.conn)
-	return err
-}
diff --git a/vendor/github.com/gorilla/websocket/conn_write_legacy.go b/vendor/github.com/gorilla/websocket/conn_write_legacy.go
deleted file mode 100644
index 37edaff..0000000
--- a/vendor/github.com/gorilla/websocket/conn_write_legacy.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.8
-
-package websocket
-
-func (c *Conn) writeBufs(bufs ...[]byte) error {
-	for _, buf := range bufs {
-		if len(buf) > 0 {
-			if _, err := c.conn.Write(buf); err != nil {
-				return err
-			}
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/gorilla/websocket/doc.go b/vendor/github.com/gorilla/websocket/doc.go
deleted file mode 100644
index dcce1a6..0000000
--- a/vendor/github.com/gorilla/websocket/doc.go
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package websocket implements the WebSocket protocol defined in RFC 6455.
-//
-// Overview
-//
-// The Conn type represents a WebSocket connection. A server application calls
-// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn:
-//
-//  var upgrader = websocket.Upgrader{
-//      ReadBufferSize:  1024,
-//      WriteBufferSize: 1024,
-//  }
-//
-//  func handler(w http.ResponseWriter, r *http.Request) {
-//      conn, err := upgrader.Upgrade(w, r, nil)
-//      if err != nil {
-//          log.Println(err)
-//          return
-//      }
-//      ... Use conn to send and receive messages.
-//  }
-//
-// Call the connection's WriteMessage and ReadMessage methods to send and
-// receive messages as a slice of bytes. This snippet of code shows how to echo
-// messages using these methods:
-//
-//  for {
-//      messageType, p, err := conn.ReadMessage()
-//      if err != nil {
-//          log.Println(err)
-//          return
-//      }
-//      if err := conn.WriteMessage(messageType, p); err != nil {
-//          log.Println(err)
-//          return
-//      }
-//  }
-//
-// In above snippet of code, p is a []byte and messageType is an int with value
-// websocket.BinaryMessage or websocket.TextMessage.
-//
-// An application can also send and receive messages using the io.WriteCloser
-// and io.Reader interfaces. To send a message, call the connection NextWriter
-// method to get an io.WriteCloser, write the message to the writer and close
-// the writer when done. To receive a message, call the connection NextReader
-// method to get an io.Reader and read until io.EOF is returned. This snippet
-// shows how to echo messages using the NextWriter and NextReader methods:
-//
-//  for {
-//      messageType, r, err := conn.NextReader()
-//      if err != nil {
-//          return
-//      }
-//      w, err := conn.NextWriter(messageType)
-//      if err != nil {
-//          return err
-//      }
-//      if _, err := io.Copy(w, r); err != nil {
-//          return err
-//      }
-//      if err := w.Close(); err != nil {
-//          return err
-//      }
-//  }
-//
-// Data Messages
-//
-// The WebSocket protocol distinguishes between text and binary data messages.
-// Text messages are interpreted as UTF-8 encoded text. The interpretation of
-// binary messages is left to the application.
-//
-// This package uses the TextMessage and BinaryMessage integer constants to
-// identify the two data message types. The ReadMessage and NextReader methods
-// return the type of the received message. The messageType argument to the
-// WriteMessage and NextWriter methods specifies the type of a sent message.
-//
-// It is the application's responsibility to ensure that text messages are
-// valid UTF-8 encoded text.
-//
-// Control Messages
-//
-// The WebSocket protocol defines three types of control messages: close, ping
-// and pong. Call the connection WriteControl, WriteMessage or NextWriter
-// methods to send a control message to the peer.
-//
-// Connections handle received close messages by calling the handler function
-// set with the SetCloseHandler method and by returning a *CloseError from the
-// NextReader, ReadMessage or the message Read method. The default close
-// handler sends a close message to the peer.
-//
-// Connections handle received ping messages by calling the handler function
-// set with the SetPingHandler method. The default ping handler sends a pong
-// message to the peer.
-//
-// Connections handle received pong messages by calling the handler function
-// set with the SetPongHandler method. The default pong handler does nothing.
-// If an application sends ping messages, then the application should set a
-// pong handler to receive the corresponding pong.
-//
-// The control message handler functions are called from the NextReader,
-// ReadMessage and message reader Read methods. The default close and ping
-// handlers can block these methods for a short time when the handler writes to
-// the connection.
-//
-// The application must read the connection to process close, ping and pong
-// messages sent from the peer. If the application is not otherwise interested
-// in messages from the peer, then the application should start a goroutine to
-// read and discard messages from the peer. A simple example is:
-//
-//  func readLoop(c *websocket.Conn) {
-//      for {
-//          if _, _, err := c.NextReader(); err != nil {
-//              c.Close()
-//              break
-//          }
-//      }
-//  }
-//
-// Concurrency
-//
-// Connections support one concurrent reader and one concurrent writer.
-//
-// Applications are responsible for ensuring that no more than one goroutine
-// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,
-// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and
-// that no more than one goroutine calls the read methods (NextReader,
-// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler)
-// concurrently.
-//
-// The Close and WriteControl methods can be called concurrently with all other
-// methods.
-//
-// Origin Considerations
-//
-// Web browsers allow Javascript applications to open a WebSocket connection to
-// any host. It's up to the server to enforce an origin policy using the Origin
-// request header sent by the browser.
-//
-// The Upgrader calls the function specified in the CheckOrigin field to check
-// the origin. If the CheckOrigin function returns false, then the Upgrade
-// method fails the WebSocket handshake with HTTP status 403.
-//
-// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail
-// the handshake if the Origin request header is present and the Origin host is
-// not equal to the Host request header.
-//
-// The deprecated package-level Upgrade function does not perform origin
-// checking. The application is responsible for checking the Origin header
-// before calling the Upgrade function.
-//
-// Compression EXPERIMENTAL
-//
-// Per message compression extensions (RFC 7692) are experimentally supported
-// by this package in a limited capacity. Setting the EnableCompression option
-// to true in Dialer or Upgrader will attempt to negotiate per message deflate
-// support.
-//
-//  var upgrader = websocket.Upgrader{
-//      EnableCompression: true,
-//  }
-//
-// If compression was successfully negotiated with the connection's peer, any
-// message received in compressed form will be automatically decompressed.
-// All Read methods will return uncompressed bytes.
-//
-// Per message compression of messages written to a connection can be enabled
-// or disabled by calling the corresponding Conn method:
-//
-//  conn.EnableWriteCompression(false)
-//
-// Currently this package does not support compression with "context takeover".
-// This means that messages must be compressed and decompressed in isolation,
-// without retaining sliding window or dictionary state across messages. For
-// more details refer to RFC 7692.
-//
-// Use of compression is experimental and may result in decreased performance.
-package websocket
diff --git a/vendor/github.com/gorilla/websocket/json.go b/vendor/github.com/gorilla/websocket/json.go
deleted file mode 100644
index dc2c1f6..0000000
--- a/vendor/github.com/gorilla/websocket/json.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"encoding/json"
-	"io"
-)
-
-// WriteJSON writes the JSON encoding of v as a message.
-//
-// Deprecated: Use c.WriteJSON instead.
-func WriteJSON(c *Conn, v interface{}) error {
-	return c.WriteJSON(v)
-}
-
-// WriteJSON writes the JSON encoding of v as a message.
-//
-// See the documentation for encoding/json Marshal for details about the
-// conversion of Go values to JSON.
-func (c *Conn) WriteJSON(v interface{}) error {
-	w, err := c.NextWriter(TextMessage)
-	if err != nil {
-		return err
-	}
-	err1 := json.NewEncoder(w).Encode(v)
-	err2 := w.Close()
-	if err1 != nil {
-		return err1
-	}
-	return err2
-}
-
-// ReadJSON reads the next JSON-encoded message from the connection and stores
-// it in the value pointed to by v.
-//
-// Deprecated: Use c.ReadJSON instead.
-func ReadJSON(c *Conn, v interface{}) error {
-	return c.ReadJSON(v)
-}
-
-// ReadJSON reads the next JSON-encoded message from the connection and stores
-// it in the value pointed to by v.
-//
-// See the documentation for the encoding/json Unmarshal function for details
-// about the conversion of JSON to a Go value.
-func (c *Conn) ReadJSON(v interface{}) error {
-	_, r, err := c.NextReader()
-	if err != nil {
-		return err
-	}
-	err = json.NewDecoder(r).Decode(v)
-	if err == io.EOF {
-		// One value is expected in the message.
-		err = io.ErrUnexpectedEOF
-	}
-	return err
-}
diff --git a/vendor/github.com/gorilla/websocket/mask.go b/vendor/github.com/gorilla/websocket/mask.go
deleted file mode 100644
index 577fce9..0000000
--- a/vendor/github.com/gorilla/websocket/mask.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.  Use of
-// this source code is governed by a BSD-style license that can be found in the
-// LICENSE file.
-
-// +build !appengine
-
-package websocket
-
-import "unsafe"
-
-const wordSize = int(unsafe.Sizeof(uintptr(0)))
-
-func maskBytes(key [4]byte, pos int, b []byte) int {
-	// Mask one byte at a time for small buffers.
-	if len(b) < 2*wordSize {
-		for i := range b {
-			b[i] ^= key[pos&3]
-			pos++
-		}
-		return pos & 3
-	}
-
-	// Mask one byte at a time to word boundary.
-	if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {
-		n = wordSize - n
-		for i := range b[:n] {
-			b[i] ^= key[pos&3]
-			pos++
-		}
-		b = b[n:]
-	}
-
-	// Create aligned word size key.
-	var k [wordSize]byte
-	for i := range k {
-		k[i] = key[(pos+i)&3]
-	}
-	kw := *(*uintptr)(unsafe.Pointer(&k))
-
-	// Mask one word at a time.
-	n := (len(b) / wordSize) * wordSize
-	for i := 0; i < n; i += wordSize {
-		*(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw
-	}
-
-	// Mask one byte at a time for remaining bytes.
-	b = b[n:]
-	for i := range b {
-		b[i] ^= key[pos&3]
-		pos++
-	}
-
-	return pos & 3
-}
diff --git a/vendor/github.com/gorilla/websocket/mask_safe.go b/vendor/github.com/gorilla/websocket/mask_safe.go
deleted file mode 100644
index 2aac060..0000000
--- a/vendor/github.com/gorilla/websocket/mask_safe.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.  Use of
-// this source code is governed by a BSD-style license that can be found in the
-// LICENSE file.
-
-// +build appengine
-
-package websocket
-
-func maskBytes(key [4]byte, pos int, b []byte) int {
-	for i := range b {
-		b[i] ^= key[pos&3]
-		pos++
-	}
-	return pos & 3
-}
diff --git a/vendor/github.com/gorilla/websocket/prepared.go b/vendor/github.com/gorilla/websocket/prepared.go
deleted file mode 100644
index 74ec565..0000000
--- a/vendor/github.com/gorilla/websocket/prepared.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"bytes"
-	"net"
-	"sync"
-	"time"
-)
-
-// PreparedMessage caches on the wire representations of a message payload.
-// Use PreparedMessage to efficiently send a message payload to multiple
-// connections. PreparedMessage is especially useful when compression is used
-// because the CPU and memory expensive compression operation can be executed
-// once for a given set of compression options.
-type PreparedMessage struct {
-	messageType int
-	data        []byte
-	mu          sync.Mutex
-	frames      map[prepareKey]*preparedFrame
-}
-
-// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage.
-type prepareKey struct {
-	isServer         bool
-	compress         bool
-	compressionLevel int
-}
-
-// preparedFrame contains data in wire representation.
-type preparedFrame struct {
-	once sync.Once
-	data []byte
-}
-
-// NewPreparedMessage returns an initialized PreparedMessage. You can then send
-// it to connection using WritePreparedMessage method. Valid wire
-// representation will be calculated lazily only once for a set of current
-// connection options.
-func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) {
-	pm := &PreparedMessage{
-		messageType: messageType,
-		frames:      make(map[prepareKey]*preparedFrame),
-		data:        data,
-	}
-
-	// Prepare a plain server frame.
-	_, frameData, err := pm.frame(prepareKey{isServer: true, compress: false})
-	if err != nil {
-		return nil, err
-	}
-
-	// To protect against caller modifying the data argument, remember the data
-	// copied to the plain server frame.
-	pm.data = frameData[len(frameData)-len(data):]
-	return pm, nil
-}
-
-func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) {
-	pm.mu.Lock()
-	frame, ok := pm.frames[key]
-	if !ok {
-		frame = &preparedFrame{}
-		pm.frames[key] = frame
-	}
-	pm.mu.Unlock()
-
-	var err error
-	frame.once.Do(func() {
-		// Prepare a frame using a 'fake' connection.
-		// TODO: Refactor code in conn.go to allow more direct construction of
-		// the frame.
-		mu := make(chan bool, 1)
-		mu <- true
-		var nc prepareConn
-		c := &Conn{
-			conn:                   &nc,
-			mu:                     mu,
-			isServer:               key.isServer,
-			compressionLevel:       key.compressionLevel,
-			enableWriteCompression: true,
-			writeBuf:               make([]byte, defaultWriteBufferSize+maxFrameHeaderSize),
-		}
-		if key.compress {
-			c.newCompressionWriter = compressNoContextTakeover
-		}
-		err = c.WriteMessage(pm.messageType, pm.data)
-		frame.data = nc.buf.Bytes()
-	})
-	return pm.messageType, frame.data, err
-}
-
-type prepareConn struct {
-	buf bytes.Buffer
-	net.Conn
-}
-
-func (pc *prepareConn) Write(p []byte) (int, error)        { return pc.buf.Write(p) }
-func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil }
diff --git a/vendor/github.com/gorilla/websocket/proxy.go b/vendor/github.com/gorilla/websocket/proxy.go
deleted file mode 100644
index bf2478e..0000000
--- a/vendor/github.com/gorilla/websocket/proxy.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"bufio"
-	"encoding/base64"
-	"errors"
-	"net"
-	"net/http"
-	"net/url"
-	"strings"
-)
-
-type netDialerFunc func(network, addr string) (net.Conn, error)
-
-func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {
-	return fn(network, addr)
-}
-
-func init() {
-	proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {
-		return &httpProxyDialer{proxyURL: proxyURL, fowardDial: forwardDialer.Dial}, nil
-	})
-}
-
-type httpProxyDialer struct {
-	proxyURL   *url.URL
-	fowardDial func(network, addr string) (net.Conn, error)
-}
-
-func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {
-	hostPort, _ := hostPortNoPort(hpd.proxyURL)
-	conn, err := hpd.fowardDial(network, hostPort)
-	if err != nil {
-		return nil, err
-	}
-
-	connectHeader := make(http.Header)
-	if user := hpd.proxyURL.User; user != nil {
-		proxyUser := user.Username()
-		if proxyPassword, passwordSet := user.Password(); passwordSet {
-			credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword))
-			connectHeader.Set("Proxy-Authorization", "Basic "+credential)
-		}
-	}
-
-	connectReq := &http.Request{
-		Method: "CONNECT",
-		URL:    &url.URL{Opaque: addr},
-		Host:   addr,
-		Header: connectHeader,
-	}
-
-	if err := connectReq.Write(conn); err != nil {
-		conn.Close()
-		return nil, err
-	}
-
-	// Read response. It's OK to use and discard buffered reader here becaue
-	// the remote server does not speak until spoken to.
-	br := bufio.NewReader(conn)
-	resp, err := http.ReadResponse(br, connectReq)
-	if err != nil {
-		conn.Close()
-		return nil, err
-	}
-
-	if resp.StatusCode != 200 {
-		conn.Close()
-		f := strings.SplitN(resp.Status, " ", 2)
-		return nil, errors.New(f[1])
-	}
-	return conn, nil
-}
diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go
deleted file mode 100644
index a761824..0000000
--- a/vendor/github.com/gorilla/websocket/server.go
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"bufio"
-	"errors"
-	"io"
-	"net/http"
-	"net/url"
-	"strings"
-	"time"
-)
-
-// HandshakeError describes an error with the handshake from the peer.
-type HandshakeError struct {
-	message string
-}
-
-func (e HandshakeError) Error() string { return e.message }
-
-// Upgrader specifies parameters for upgrading an HTTP connection to a
-// WebSocket connection.
-type Upgrader struct {
-	// HandshakeTimeout specifies the duration for the handshake to complete.
-	HandshakeTimeout time.Duration
-
-	// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
-	// size is zero, then buffers allocated by the HTTP server are used. The
-	// I/O buffer sizes do not limit the size of the messages that can be sent
-	// or received.
-	ReadBufferSize, WriteBufferSize int
-
-	// WriteBufferPool is a pool of buffers for write operations. If the value
-	// is not set, then write buffers are allocated to the connection for the
-	// lifetime of the connection.
-	//
-	// A pool is most useful when the application has a modest volume of writes
-	// across a large number of connections.
-	//
-	// Applications should use a single pool for each unique value of
-	// WriteBufferSize.
-	WriteBufferPool BufferPool
-
-	// Subprotocols specifies the server's supported protocols in order of
-	// preference. If this field is not nil, then the Upgrade method negotiates a
-	// subprotocol by selecting the first match in this list with a protocol
-	// requested by the client. If there's no match, then no protocol is
-	// negotiated (the Sec-Websocket-Protocol header is not included in the
-	// handshake response).
-	Subprotocols []string
-
-	// Error specifies the function for generating HTTP error responses. If Error
-	// is nil, then http.Error is used to generate the HTTP response.
-	Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
-
-	// CheckOrigin returns true if the request Origin header is acceptable. If
-	// CheckOrigin is nil, then a safe default is used: return false if the
-	// Origin request header is present and the origin host is not equal to
-	// request Host header.
-	//
-	// A CheckOrigin function should carefully validate the request origin to
-	// prevent cross-site request forgery.
-	CheckOrigin func(r *http.Request) bool
-
-	// EnableCompression specify if the server should attempt to negotiate per
-	// message compression (RFC 7692). Setting this value to true does not
-	// guarantee that compression will be supported. Currently only "no context
-	// takeover" modes are supported.
-	EnableCompression bool
-}
-
-func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) {
-	err := HandshakeError{reason}
-	if u.Error != nil {
-		u.Error(w, r, status, err)
-	} else {
-		w.Header().Set("Sec-Websocket-Version", "13")
-		http.Error(w, http.StatusText(status), status)
-	}
-	return nil, err
-}
-
-// checkSameOrigin returns true if the origin is not set or is equal to the request host.
-func checkSameOrigin(r *http.Request) bool {
-	origin := r.Header["Origin"]
-	if len(origin) == 0 {
-		return true
-	}
-	u, err := url.Parse(origin[0])
-	if err != nil {
-		return false
-	}
-	return equalASCIIFold(u.Host, r.Host)
-}
-
-func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string {
-	if u.Subprotocols != nil {
-		clientProtocols := Subprotocols(r)
-		for _, serverProtocol := range u.Subprotocols {
-			for _, clientProtocol := range clientProtocols {
-				if clientProtocol == serverProtocol {
-					return clientProtocol
-				}
-			}
-		}
-	} else if responseHeader != nil {
-		return responseHeader.Get("Sec-Websocket-Protocol")
-	}
-	return ""
-}
-
-// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
-//
-// The responseHeader is included in the response to the client's upgrade
-// request. Use the responseHeader to specify cookies (Set-Cookie) and the
-// application negotiated subprotocol (Sec-WebSocket-Protocol).
-//
-// If the upgrade fails, then Upgrade replies to the client with an HTTP error
-// response.
-func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {
-	const badHandshake = "websocket: the client is not using the websocket protocol: "
-
-	if !tokenListContainsValue(r.Header, "Connection", "upgrade") {
-		return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header")
-	}
-
-	if !tokenListContainsValue(r.Header, "Upgrade", "websocket") {
-		return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header")
-	}
-
-	if r.Method != "GET" {
-		return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET")
-	}
-
-	if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") {
-		return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header")
-	}
-
-	if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok {
-		return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported")
-	}
-
-	checkOrigin := u.CheckOrigin
-	if checkOrigin == nil {
-		checkOrigin = checkSameOrigin
-	}
-	if !checkOrigin(r) {
-		return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin")
-	}
-
-	challengeKey := r.Header.Get("Sec-Websocket-Key")
-	if challengeKey == "" {
-		return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: `Sec-WebSocket-Key' header is missing or blank")
-	}
-
-	subprotocol := u.selectSubprotocol(r, responseHeader)
-
-	// Negotiate PMCE
-	var compress bool
-	if u.EnableCompression {
-		for _, ext := range parseExtensions(r.Header) {
-			if ext[""] != "permessage-deflate" {
-				continue
-			}
-			compress = true
-			break
-		}
-	}
-
-	h, ok := w.(http.Hijacker)
-	if !ok {
-		return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker")
-	}
-	var brw *bufio.ReadWriter
-	netConn, brw, err := h.Hijack()
-	if err != nil {
-		return u.returnError(w, r, http.StatusInternalServerError, err.Error())
-	}
-
-	if brw.Reader.Buffered() > 0 {
-		netConn.Close()
-		return nil, errors.New("websocket: client sent data before handshake is complete")
-	}
-
-	var br *bufio.Reader
-	if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 {
-		// Reuse hijacked buffered reader as connection reader.
-		br = brw.Reader
-	}
-
-	buf := bufioWriterBuffer(netConn, brw.Writer)
-
-	var writeBuf []byte
-	if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 {
-		// Reuse hijacked write buffer as connection buffer.
-		writeBuf = buf
-	}
-
-	c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf)
-	c.subprotocol = subprotocol
-
-	if compress {
-		c.newCompressionWriter = compressNoContextTakeover
-		c.newDecompressionReader = decompressNoContextTakeover
-	}
-
-	// Use larger of hijacked buffer and connection write buffer for header.
-	p := buf
-	if len(c.writeBuf) > len(p) {
-		p = c.writeBuf
-	}
-	p = p[:0]
-
-	p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...)
-	p = append(p, computeAcceptKey(challengeKey)...)
-	p = append(p, "\r\n"...)
-	if c.subprotocol != "" {
-		p = append(p, "Sec-WebSocket-Protocol: "...)
-		p = append(p, c.subprotocol...)
-		p = append(p, "\r\n"...)
-	}
-	if compress {
-		p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...)
-	}
-	for k, vs := range responseHeader {
-		if k == "Sec-Websocket-Protocol" {
-			continue
-		}
-		for _, v := range vs {
-			p = append(p, k...)
-			p = append(p, ": "...)
-			for i := 0; i < len(v); i++ {
-				b := v[i]
-				if b <= 31 {
-					// prevent response splitting.
-					b = ' '
-				}
-				p = append(p, b)
-			}
-			p = append(p, "\r\n"...)
-		}
-	}
-	p = append(p, "\r\n"...)
-
-	// Clear deadlines set by HTTP server.
-	netConn.SetDeadline(time.Time{})
-
-	if u.HandshakeTimeout > 0 {
-		netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout))
-	}
-	if _, err = netConn.Write(p); err != nil {
-		netConn.Close()
-		return nil, err
-	}
-	if u.HandshakeTimeout > 0 {
-		netConn.SetWriteDeadline(time.Time{})
-	}
-
-	return c, nil
-}
-
-// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
-//
-// Deprecated: Use websocket.Upgrader instead.
-//
-// Upgrade does not perform origin checking. The application is responsible for
-// checking the Origin header before calling Upgrade. An example implementation
-// of the same origin policy check is:
-//
-//	if req.Header.Get("Origin") != "http://"+req.Host {
-//		http.Error(w, "Origin not allowed", http.StatusForbidden)
-//		return
-//	}
-//
-// If the endpoint supports subprotocols, then the application is responsible
-// for negotiating the protocol used on the connection. Use the Subprotocols()
-// function to get the subprotocols requested by the client. Use the
-// Sec-Websocket-Protocol response header to specify the subprotocol selected
-// by the application.
-//
-// The responseHeader is included in the response to the client's upgrade
-// request. Use the responseHeader to specify cookies (Set-Cookie) and the
-// negotiated subprotocol (Sec-Websocket-Protocol).
-//
-// The connection buffers IO to the underlying network connection. The
-// readBufSize and writeBufSize parameters specify the size of the buffers to
-// use. Messages can be larger than the buffers.
-//
-// If the request is not a valid WebSocket handshake, then Upgrade returns an
-// error of type HandshakeError. Applications should handle this error by
-// replying to the client with an HTTP error response.
-func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) {
-	u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize}
-	u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) {
-		// don't return errors to maintain backwards compatibility
-	}
-	u.CheckOrigin = func(r *http.Request) bool {
-		// allow all connections by default
-		return true
-	}
-	return u.Upgrade(w, r, responseHeader)
-}
-
-// Subprotocols returns the subprotocols requested by the client in the
-// Sec-Websocket-Protocol header.
-func Subprotocols(r *http.Request) []string {
-	h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol"))
-	if h == "" {
-		return nil
-	}
-	protocols := strings.Split(h, ",")
-	for i := range protocols {
-		protocols[i] = strings.TrimSpace(protocols[i])
-	}
-	return protocols
-}
-
-// IsWebSocketUpgrade returns true if the client requested upgrade to the
-// WebSocket protocol.
-func IsWebSocketUpgrade(r *http.Request) bool {
-	return tokenListContainsValue(r.Header, "Connection", "upgrade") &&
-		tokenListContainsValue(r.Header, "Upgrade", "websocket")
-}
-
-// bufioReaderSize size returns the size of a bufio.Reader.
-func bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int {
-	// This code assumes that peek on a reset reader returns
-	// bufio.Reader.buf[:0].
-	// TODO: Use bufio.Reader.Size() after Go 1.10
-	br.Reset(originalReader)
-	if p, err := br.Peek(0); err == nil {
-		return cap(p)
-	}
-	return 0
-}
-
-// writeHook is an io.Writer that records the last slice passed to it vio
-// io.Writer.Write.
-type writeHook struct {
-	p []byte
-}
-
-func (wh *writeHook) Write(p []byte) (int, error) {
-	wh.p = p
-	return len(p), nil
-}
-
-// bufioWriterBuffer grabs the buffer from a bufio.Writer.
-func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte {
-	// This code assumes that bufio.Writer.buf[:1] is passed to the
-	// bufio.Writer's underlying writer.
-	var wh writeHook
-	bw.Reset(&wh)
-	bw.WriteByte(0)
-	bw.Flush()
-
-	bw.Reset(originalWriter)
-
-	return wh.p[:cap(wh.p)]
-}
diff --git a/vendor/github.com/gorilla/websocket/trace.go b/vendor/github.com/gorilla/websocket/trace.go
deleted file mode 100644
index 834f122..0000000
--- a/vendor/github.com/gorilla/websocket/trace.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// +build go1.8
-
-package websocket
-
-import (
-	"crypto/tls"
-	"net/http/httptrace"
-)
-
-func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error {
-	if trace.TLSHandshakeStart != nil {
-		trace.TLSHandshakeStart()
-	}
-	err := doHandshake(tlsConn, cfg)
-	if trace.TLSHandshakeDone != nil {
-		trace.TLSHandshakeDone(tlsConn.ConnectionState(), err)
-	}
-	return err
-}
diff --git a/vendor/github.com/gorilla/websocket/trace_17.go b/vendor/github.com/gorilla/websocket/trace_17.go
deleted file mode 100644
index 77d05a0..0000000
--- a/vendor/github.com/gorilla/websocket/trace_17.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// +build !go1.8
-
-package websocket
-
-import (
-	"crypto/tls"
-	"net/http/httptrace"
-)
-
-func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error {
-	return doHandshake(tlsConn, cfg)
-}
diff --git a/vendor/github.com/gorilla/websocket/util.go b/vendor/github.com/gorilla/websocket/util.go
deleted file mode 100644
index 354001e..0000000
--- a/vendor/github.com/gorilla/websocket/util.go
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package websocket
-
-import (
-	"crypto/rand"
-	"crypto/sha1"
-	"encoding/base64"
-	"io"
-	"net/http"
-	"strings"
-	"unicode/utf8"
-)
-
-var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
-
-func computeAcceptKey(challengeKey string) string {
-	h := sha1.New()
-	h.Write([]byte(challengeKey))
-	h.Write(keyGUID)
-	return base64.StdEncoding.EncodeToString(h.Sum(nil))
-}
-
-func generateChallengeKey() (string, error) {
-	p := make([]byte, 16)
-	if _, err := io.ReadFull(rand.Reader, p); err != nil {
-		return "", err
-	}
-	return base64.StdEncoding.EncodeToString(p), nil
-}
-
-// Octet types from RFC 2616.
-var octetTypes [256]byte
-
-const (
-	isTokenOctet = 1 << iota
-	isSpaceOctet
-)
-
-func init() {
-	// From RFC 2616
-	//
-	// OCTET      = <any 8-bit sequence of data>
-	// CHAR       = <any US-ASCII character (octets 0 - 127)>
-	// CTL        = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
-	// CR         = <US-ASCII CR, carriage return (13)>
-	// LF         = <US-ASCII LF, linefeed (10)>
-	// SP         = <US-ASCII SP, space (32)>
-	// HT         = <US-ASCII HT, horizontal-tab (9)>
-	// <">        = <US-ASCII double-quote mark (34)>
-	// CRLF       = CR LF
-	// LWS        = [CRLF] 1*( SP | HT )
-	// TEXT       = <any OCTET except CTLs, but including LWS>
-	// separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
-	//              | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
-	// token      = 1*<any CHAR except CTLs or separators>
-	// qdtext     = <any TEXT except <">>
-
-	for c := 0; c < 256; c++ {
-		var t byte
-		isCtl := c <= 31 || c == 127
-		isChar := 0 <= c && c <= 127
-		isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0
-		if strings.IndexRune(" \t\r\n", rune(c)) >= 0 {
-			t |= isSpaceOctet
-		}
-		if isChar && !isCtl && !isSeparator {
-			t |= isTokenOctet
-		}
-		octetTypes[c] = t
-	}
-}
-
-func skipSpace(s string) (rest string) {
-	i := 0
-	for ; i < len(s); i++ {
-		if octetTypes[s[i]]&isSpaceOctet == 0 {
-			break
-		}
-	}
-	return s[i:]
-}
-
-func nextToken(s string) (token, rest string) {
-	i := 0
-	for ; i < len(s); i++ {
-		if octetTypes[s[i]]&isTokenOctet == 0 {
-			break
-		}
-	}
-	return s[:i], s[i:]
-}
-
-func nextTokenOrQuoted(s string) (value string, rest string) {
-	if !strings.HasPrefix(s, "\"") {
-		return nextToken(s)
-	}
-	s = s[1:]
-	for i := 0; i < len(s); i++ {
-		switch s[i] {
-		case '"':
-			return s[:i], s[i+1:]
-		case '\\':
-			p := make([]byte, len(s)-1)
-			j := copy(p, s[:i])
-			escape := true
-			for i = i + 1; i < len(s); i++ {
-				b := s[i]
-				switch {
-				case escape:
-					escape = false
-					p[j] = b
-					j++
-				case b == '\\':
-					escape = true
-				case b == '"':
-					return string(p[:j]), s[i+1:]
-				default:
-					p[j] = b
-					j++
-				}
-			}
-			return "", ""
-		}
-	}
-	return "", ""
-}
-
-// equalASCIIFold returns true if s is equal to t with ASCII case folding.
-func equalASCIIFold(s, t string) bool {
-	for s != "" && t != "" {
-		sr, size := utf8.DecodeRuneInString(s)
-		s = s[size:]
-		tr, size := utf8.DecodeRuneInString(t)
-		t = t[size:]
-		if sr == tr {
-			continue
-		}
-		if 'A' <= sr && sr <= 'Z' {
-			sr = sr + 'a' - 'A'
-		}
-		if 'A' <= tr && tr <= 'Z' {
-			tr = tr + 'a' - 'A'
-		}
-		if sr != tr {
-			return false
-		}
-	}
-	return s == t
-}
-
-// tokenListContainsValue returns true if the 1#token header with the given
-// name contains a token equal to value with ASCII case folding.
-func tokenListContainsValue(header http.Header, name string, value string) bool {
-headers:
-	for _, s := range header[name] {
-		for {
-			var t string
-			t, s = nextToken(skipSpace(s))
-			if t == "" {
-				continue headers
-			}
-			s = skipSpace(s)
-			if s != "" && s[0] != ',' {
-				continue headers
-			}
-			if equalASCIIFold(t, value) {
-				return true
-			}
-			if s == "" {
-				continue headers
-			}
-			s = s[1:]
-		}
-	}
-	return false
-}
-
-// parseExtensions parses WebSocket extensions from a header.
-func parseExtensions(header http.Header) []map[string]string {
-	// From RFC 6455:
-	//
-	//  Sec-WebSocket-Extensions = extension-list
-	//  extension-list = 1#extension
-	//  extension = extension-token *( ";" extension-param )
-	//  extension-token = registered-token
-	//  registered-token = token
-	//  extension-param = token [ "=" (token | quoted-string) ]
-	//     ;When using the quoted-string syntax variant, the value
-	//     ;after quoted-string unescaping MUST conform to the
-	//     ;'token' ABNF.
-
-	var result []map[string]string
-headers:
-	for _, s := range header["Sec-Websocket-Extensions"] {
-		for {
-			var t string
-			t, s = nextToken(skipSpace(s))
-			if t == "" {
-				continue headers
-			}
-			ext := map[string]string{"": t}
-			for {
-				s = skipSpace(s)
-				if !strings.HasPrefix(s, ";") {
-					break
-				}
-				var k string
-				k, s = nextToken(skipSpace(s[1:]))
-				if k == "" {
-					continue headers
-				}
-				s = skipSpace(s)
-				var v string
-				if strings.HasPrefix(s, "=") {
-					v, s = nextTokenOrQuoted(skipSpace(s[1:]))
-					s = skipSpace(s)
-				}
-				if s != "" && s[0] != ',' && s[0] != ';' {
-					continue headers
-				}
-				ext[k] = v
-			}
-			if s != "" && s[0] != ',' {
-				continue headers
-			}
-			result = append(result, ext)
-			if s == "" {
-				continue headers
-			}
-			s = s[1:]
-		}
-	}
-	return result
-}
diff --git a/vendor/github.com/gorilla/websocket/x_net_proxy.go b/vendor/github.com/gorilla/websocket/x_net_proxy.go
deleted file mode 100644
index 2e668f6..0000000
--- a/vendor/github.com/gorilla/websocket/x_net_proxy.go
+++ /dev/null
@@ -1,473 +0,0 @@
-// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
-//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy
-
-// Package proxy provides support for a variety of protocols to proxy network
-// data.
-//
-
-package websocket
-
-import (
-	"errors"
-	"io"
-	"net"
-	"net/url"
-	"os"
-	"strconv"
-	"strings"
-	"sync"
-)
-
-type proxy_direct struct{}
-
-// Direct is a direct proxy: one that makes network connections directly.
-var proxy_Direct = proxy_direct{}
-
-func (proxy_direct) Dial(network, addr string) (net.Conn, error) {
-	return net.Dial(network, addr)
-}
-
-// A PerHost directs connections to a default Dialer unless the host name
-// requested matches one of a number of exceptions.
-type proxy_PerHost struct {
-	def, bypass proxy_Dialer
-
-	bypassNetworks []*net.IPNet
-	bypassIPs      []net.IP
-	bypassZones    []string
-	bypassHosts    []string
-}
-
-// NewPerHost returns a PerHost Dialer that directs connections to either
-// defaultDialer or bypass, depending on whether the connection matches one of
-// the configured rules.
-func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost {
-	return &proxy_PerHost{
-		def:    defaultDialer,
-		bypass: bypass,
-	}
-}
-
-// Dial connects to the address addr on the given network through either
-// defaultDialer or bypass.
-func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) {
-	host, _, err := net.SplitHostPort(addr)
-	if err != nil {
-		return nil, err
-	}
-
-	return p.dialerForRequest(host).Dial(network, addr)
-}
-
-func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer {
-	if ip := net.ParseIP(host); ip != nil {
-		for _, net := range p.bypassNetworks {
-			if net.Contains(ip) {
-				return p.bypass
-			}
-		}
-		for _, bypassIP := range p.bypassIPs {
-			if bypassIP.Equal(ip) {
-				return p.bypass
-			}
-		}
-		return p.def
-	}
-
-	for _, zone := range p.bypassZones {
-		if strings.HasSuffix(host, zone) {
-			return p.bypass
-		}
-		if host == zone[1:] {
-			// For a zone ".example.com", we match "example.com"
-			// too.
-			return p.bypass
-		}
-	}
-	for _, bypassHost := range p.bypassHosts {
-		if bypassHost == host {
-			return p.bypass
-		}
-	}
-	return p.def
-}
-
-// AddFromString parses a string that contains comma-separated values
-// specifying hosts that should use the bypass proxy. Each value is either an
-// IP address, a CIDR range, a zone (*.example.com) or a host name
-// (localhost). A best effort is made to parse the string and errors are
-// ignored.
-func (p *proxy_PerHost) AddFromString(s string) {
-	hosts := strings.Split(s, ",")
-	for _, host := range hosts {
-		host = strings.TrimSpace(host)
-		if len(host) == 0 {
-			continue
-		}
-		if strings.Contains(host, "/") {
-			// We assume that it's a CIDR address like 127.0.0.0/8
-			if _, net, err := net.ParseCIDR(host); err == nil {
-				p.AddNetwork(net)
-			}
-			continue
-		}
-		if ip := net.ParseIP(host); ip != nil {
-			p.AddIP(ip)
-			continue
-		}
-		if strings.HasPrefix(host, "*.") {
-			p.AddZone(host[1:])
-			continue
-		}
-		p.AddHost(host)
-	}
-}
-
-// AddIP specifies an IP address that will use the bypass proxy. Note that
-// this will only take effect if a literal IP address is dialed. A connection
-// to a named host will never match an IP.
-func (p *proxy_PerHost) AddIP(ip net.IP) {
-	p.bypassIPs = append(p.bypassIPs, ip)
-}
-
-// AddNetwork specifies an IP range that will use the bypass proxy. Note that
-// this will only take effect if a literal IP address is dialed. A connection
-// to a named host will never match.
-func (p *proxy_PerHost) AddNetwork(net *net.IPNet) {
-	p.bypassNetworks = append(p.bypassNetworks, net)
-}
-
-// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
-// "example.com" matches "example.com" and all of its subdomains.
-func (p *proxy_PerHost) AddZone(zone string) {
-	if strings.HasSuffix(zone, ".") {
-		zone = zone[:len(zone)-1]
-	}
-	if !strings.HasPrefix(zone, ".") {
-		zone = "." + zone
-	}
-	p.bypassZones = append(p.bypassZones, zone)
-}
-
-// AddHost specifies a host name that will use the bypass proxy.
-func (p *proxy_PerHost) AddHost(host string) {
-	if strings.HasSuffix(host, ".") {
-		host = host[:len(host)-1]
-	}
-	p.bypassHosts = append(p.bypassHosts, host)
-}
-
-// A Dialer is a means to establish a connection.
-type proxy_Dialer interface {
-	// Dial connects to the given address via the proxy.
-	Dial(network, addr string) (c net.Conn, err error)
-}
-
-// Auth contains authentication parameters that specific Dialers may require.
-type proxy_Auth struct {
-	User, Password string
-}
-
-// FromEnvironment returns the dialer specified by the proxy related variables in
-// the environment.
-func proxy_FromEnvironment() proxy_Dialer {
-	allProxy := proxy_allProxyEnv.Get()
-	if len(allProxy) == 0 {
-		return proxy_Direct
-	}
-
-	proxyURL, err := url.Parse(allProxy)
-	if err != nil {
-		return proxy_Direct
-	}
-	proxy, err := proxy_FromURL(proxyURL, proxy_Direct)
-	if err != nil {
-		return proxy_Direct
-	}
-
-	noProxy := proxy_noProxyEnv.Get()
-	if len(noProxy) == 0 {
-		return proxy
-	}
-
-	perHost := proxy_NewPerHost(proxy, proxy_Direct)
-	perHost.AddFromString(noProxy)
-	return perHost
-}
-
-// proxySchemes is a map from URL schemes to a function that creates a Dialer
-// from a URL with such a scheme.
-var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)
-
-// RegisterDialerType takes a URL scheme and a function to generate Dialers from
-// a URL with that scheme and a forwarding Dialer. Registered schemes are used
-// by FromURL.
-func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) {
-	if proxy_proxySchemes == nil {
-		proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error))
-	}
-	proxy_proxySchemes[scheme] = f
-}
-
-// FromURL returns a Dialer given a URL specification and an underlying
-// Dialer for it to make network requests.
-func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) {
-	var auth *proxy_Auth
-	if u.User != nil {
-		auth = new(proxy_Auth)
-		auth.User = u.User.Username()
-		if p, ok := u.User.Password(); ok {
-			auth.Password = p
-		}
-	}
-
-	switch u.Scheme {
-	case "socks5":
-		return proxy_SOCKS5("tcp", u.Host, auth, forward)
-	}
-
-	// If the scheme doesn't match any of the built-in schemes, see if it
-	// was registered by another package.
-	if proxy_proxySchemes != nil {
-		if f, ok := proxy_proxySchemes[u.Scheme]; ok {
-			return f(u, forward)
-		}
-	}
-
-	return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
-}
-
-var (
-	proxy_allProxyEnv = &proxy_envOnce{
-		names: []string{"ALL_PROXY", "all_proxy"},
-	}
-	proxy_noProxyEnv = &proxy_envOnce{
-		names: []string{"NO_PROXY", "no_proxy"},
-	}
-)
-
-// envOnce looks up an environment variable (optionally by multiple
-// names) once. It mitigates expensive lookups on some platforms
-// (e.g. Windows).
-// (Borrowed from net/http/transport.go)
-type proxy_envOnce struct {
-	names []string
-	once  sync.Once
-	val   string
-}
-
-func (e *proxy_envOnce) Get() string {
-	e.once.Do(e.init)
-	return e.val
-}
-
-func (e *proxy_envOnce) init() {
-	for _, n := range e.names {
-		e.val = os.Getenv(n)
-		if e.val != "" {
-			return
-		}
-	}
-}
-
-// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address
-// with an optional username and password. See RFC 1928 and RFC 1929.
-func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) {
-	s := &proxy_socks5{
-		network: network,
-		addr:    addr,
-		forward: forward,
-	}
-	if auth != nil {
-		s.user = auth.User
-		s.password = auth.Password
-	}
-
-	return s, nil
-}
-
-type proxy_socks5 struct {
-	user, password string
-	network, addr  string
-	forward        proxy_Dialer
-}
-
-const proxy_socks5Version = 5
-
-const (
-	proxy_socks5AuthNone     = 0
-	proxy_socks5AuthPassword = 2
-)
-
-const proxy_socks5Connect = 1
-
-const (
-	proxy_socks5IP4    = 1
-	proxy_socks5Domain = 3
-	proxy_socks5IP6    = 4
-)
-
-var proxy_socks5Errors = []string{
-	"",
-	"general failure",
-	"connection forbidden",
-	"network unreachable",
-	"host unreachable",
-	"connection refused",
-	"TTL expired",
-	"command not supported",
-	"address type not supported",
-}
-
-// Dial connects to the address addr on the given network via the SOCKS5 proxy.
-func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) {
-	switch network {
-	case "tcp", "tcp6", "tcp4":
-	default:
-		return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network)
-	}
-
-	conn, err := s.forward.Dial(s.network, s.addr)
-	if err != nil {
-		return nil, err
-	}
-	if err := s.connect(conn, addr); err != nil {
-		conn.Close()
-		return nil, err
-	}
-	return conn, nil
-}
-
-// connect takes an existing connection to a socks5 proxy server,
-// and commands the server to extend that connection to target,
-// which must be a canonical address with a host and port.
-func (s *proxy_socks5) connect(conn net.Conn, target string) error {
-	host, portStr, err := net.SplitHostPort(target)
-	if err != nil {
-		return err
-	}
-
-	port, err := strconv.Atoi(portStr)
-	if err != nil {
-		return errors.New("proxy: failed to parse port number: " + portStr)
-	}
-	if port < 1 || port > 0xffff {
-		return errors.New("proxy: port number out of range: " + portStr)
-	}
-
-	// the size here is just an estimate
-	buf := make([]byte, 0, 6+len(host))
-
-	buf = append(buf, proxy_socks5Version)
-	if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 {
-		buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword)
-	} else {
-		buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone)
-	}
-
-	if _, err := conn.Write(buf); err != nil {
-		return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error())
-	}
-
-	if _, err := io.ReadFull(conn, buf[:2]); err != nil {
-		return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-	}
-	if buf[0] != 5 {
-		return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0])))
-	}
-	if buf[1] == 0xff {
-		return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication")
-	}
-
-	// See RFC 1929
-	if buf[1] == proxy_socks5AuthPassword {
-		buf = buf[:0]
-		buf = append(buf, 1 /* password protocol version */)
-		buf = append(buf, uint8(len(s.user)))
-		buf = append(buf, s.user...)
-		buf = append(buf, uint8(len(s.password)))
-		buf = append(buf, s.password...)
-
-		if _, err := conn.Write(buf); err != nil {
-			return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
-		}
-
-		if _, err := io.ReadFull(conn, buf[:2]); err != nil {
-			return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-		}
-
-		if buf[1] != 0 {
-			return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password")
-		}
-	}
-
-	buf = buf[:0]
-	buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */)
-
-	if ip := net.ParseIP(host); ip != nil {
-		if ip4 := ip.To4(); ip4 != nil {
-			buf = append(buf, proxy_socks5IP4)
-			ip = ip4
-		} else {
-			buf = append(buf, proxy_socks5IP6)
-		}
-		buf = append(buf, ip...)
-	} else {
-		if len(host) > 255 {
-			return errors.New("proxy: destination host name too long: " + host)
-		}
-		buf = append(buf, proxy_socks5Domain)
-		buf = append(buf, byte(len(host)))
-		buf = append(buf, host...)
-	}
-	buf = append(buf, byte(port>>8), byte(port))
-
-	if _, err := conn.Write(buf); err != nil {
-		return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
-	}
-
-	if _, err := io.ReadFull(conn, buf[:4]); err != nil {
-		return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-	}
-
-	failure := "unknown error"
-	if int(buf[1]) < len(proxy_socks5Errors) {
-		failure = proxy_socks5Errors[buf[1]]
-	}
-
-	if len(failure) > 0 {
-		return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure)
-	}
-
-	bytesToDiscard := 0
-	switch buf[3] {
-	case proxy_socks5IP4:
-		bytesToDiscard = net.IPv4len
-	case proxy_socks5IP6:
-		bytesToDiscard = net.IPv6len
-	case proxy_socks5Domain:
-		_, err := io.ReadFull(conn, buf[:1])
-		if err != nil {
-			return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-		}
-		bytesToDiscard = int(buf[0])
-	default:
-		return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr)
-	}
-
-	if cap(buf) < bytesToDiscard {
-		buf = make([]byte, bytesToDiscard)
-	} else {
-		buf = buf[:bytesToDiscard]
-	}
-	if _, err := io.ReadFull(conn, buf); err != nil {
-		return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-	}
-
-	// Also need to discard the port number
-	if _, err := io.ReadFull(conn, buf[:2]); err != nil {
-		return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-	}
-
-	return nil
-}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.gitignore b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.gitignore
deleted file mode 100644
index c198e6a..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.gitignore
+++ /dev/null
@@ -1,202 +0,0 @@
-# Created by .ignore support plugin (hsz.mobi)
-### Go template
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
-*.prof
-### Windows template
-# Windows image file caches
-Thumbs.db
-ehthumbs.db
-
-# Folder config file
-Desktop.ini
-
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
-
-# Windows Installer files
-*.cab
-*.msi
-*.msm
-*.msp
-
-# Windows shortcuts
-*.lnk
-### Kate template
-# Swap Files #
-.*.kate-swp
-.swp.*
-### SublimeText template
-# cache files for sublime text
-*.tmlanguage.cache
-*.tmPreferences.cache
-*.stTheme.cache
-
-# workspace files are user-specific
-*.sublime-workspace
-
-# project files should be checked into the repository, unless a significant
-# proportion of contributors will probably not be using SublimeText
-# *.sublime-project
-
-# sftp configuration file
-sftp-config.json
-### Linux template
-*~
-
-# temporary files which can be created if a process still has a handle open of a deleted file
-.fuse_hidden*
-
-# KDE directory preferences
-.directory
-
-# Linux trash folder which might appear on any partition or disk
-.Trash-*
-### JetBrains template
-# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
-# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
-
-# User-specific stuff:
-.idea
-.idea/tasks.xml
-.idea/dictionaries
-.idea/vcs.xml
-.idea/jsLibraryMappings.xml
-
-# Sensitive or high-churn files:
-.idea/dataSources.ids
-.idea/dataSources.xml
-.idea/dataSources.local.xml
-.idea/sqlDataSources.xml
-.idea/dynamic.xml
-.idea/uiDesigner.xml
-
-# Gradle:
-.idea/gradle.xml
-.idea/libraries
-
-# Mongo Explorer plugin:
-.idea/mongoSettings.xml
-
-## File-based project format:
-*.iws
-
-## Plugin-specific files:
-
-# IntelliJ
-/out/
-
-# mpeltonen/sbt-idea plugin
-.idea_modules/
-
-# JIRA plugin
-atlassian-ide-plugin.xml
-
-# Crashlytics plugin (for Android Studio and IntelliJ)
-com_crashlytics_export_strings.xml
-crashlytics.properties
-crashlytics-build.properties
-fabric.properties
-### Xcode template
-# Xcode
-#
-# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
-
-## Build generated
-build/
-DerivedData/
-
-## Various settings
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata/
-
-## Other
-*.moved-aside
-*.xccheckout
-*.xcscmblueprint
-### Eclipse template
-
-.metadata
-bin/
-tmp/
-*.tmp
-*.bak
-*.swp
-*~.nib
-local.properties
-.settings/
-.loadpath
-.recommenders
-
-# Eclipse Core
-.project
-
-# External tool builders
-.externalToolBuilders/
-
-# Locally stored "Eclipse launch configurations"
-*.launch
-
-# PyDev specific (Python IDE for Eclipse)
-*.pydevproject
-
-# CDT-specific (C/C++ Development Tooling)
-.cproject
-
-# JDT-specific (Eclipse Java Development Tools)
-.classpath
-
-# Java annotation processor (APT)
-.factorypath
-
-# PDT-specific (PHP Development Tools)
-.buildpath
-
-# sbteclipse plugin
-.target
-
-# Tern plugin
-.tern-project
-
-# TeXlipse plugin
-.texlipse
-
-# STS (Spring Tool Suite)
-.springBeans
-
-# Code Recommenders
-.recommenders/
-
-
-coverage.txt
-
-#vendor
-vendor/
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.travis.yml b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.travis.yml
deleted file mode 100644
index 2fc21dd..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/.travis.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-sudo: false
-language: go
-go:
-  - 1.8.x
-env:
-  - DEP_VERSION="0.3.2"
-
-before_install:
-  # Download the binary to bin folder in $GOPATH
-  - curl -L -s https://github.com/golang/dep/releases/download/v${DEP_VERSION}/dep-linux-amd64 -o $GOPATH/bin/dep
-  # Make the binary executable
-  - chmod +x $GOPATH/bin/dep
-
-install:
-  - dep ensure
-
-script:
- - make checkdocs
- - make test
- 
-after_success:
-  - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CONTRIBUTING.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CONTRIBUTING.md
deleted file mode 100644
index dd52ab8..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/CONTRIBUTING.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Contributing
-
-We would love to have people submit pull requests and help make `grpc-ecosystem/go-grpc-middleware` even better 👍.
-
-Fork, then clone the repo:
-
-```bash
-git clone git@github.com:your-username/go-grpc-middleware.git
-```    
-
-Before checking in please run the following:
-
-```bash
-make all
-```
-
-This will `vet`, `fmt`, regenerate documentation and run all tests.
-
-
-Push to your fork and open a pull request.
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/DOC.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/DOC.md
deleted file mode 100644
index 511d953..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/DOC.md
+++ /dev/null
@@ -1,166 +0,0 @@
-# grpc_middleware
-`import "github.com/grpc-ecosystem/go-grpc-middleware"`
-
-* [Overview](#pkg-overview)
-* [Imported Packages](#pkg-imports)
-* [Index](#pkg-index)
-
-## <a name="pkg-overview">Overview</a>
-`grpc_middleware` is a collection of gRPC middleware packages: interceptors, helpers and tools.
-
-### Middleware
-gRPC is a fantastic RPC middleware, which sees a lot of adoption in the Golang world. However, the
-upstream gRPC codebase is relatively bare bones.
-
-This package, and most of its child packages provides commonly needed middleware for gRPC:
-client-side interceptors for retires, server-side interceptors for input validation and auth,
-functions for chaining said interceptors, metadata convenience methods and more.
-
-### Chaining
-By default, gRPC doesn't allow one to have more than one interceptor either on the client nor on
-the server side. `grpc_middleware` provides convenient chaining methods
-
-Simple way of turning a multiple interceptors into a single interceptor. Here's an example for
-server chaining:
-
-	myServer := grpc.NewServer(
-	    grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(loggingStream, monitoringStream, authStream)),
-	    grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(loggingUnary, monitoringUnary, authUnary),
-	)
-
-These interceptors will be executed from left to right: logging, monitoring and auth.
-
-Here's an example for client side chaining:
-
-	clientConn, err = grpc.Dial(
-	    address,
-	        grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(monitoringClientUnary, retryUnary)),
-	        grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(monitoringClientStream, retryStream)),
-	)
-	client = pb_testproto.NewTestServiceClient(clientConn)
-	resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"})
-
-These interceptors will be executed from left to right: monitoring and then retry logic.
-
-The retry interceptor will call every interceptor that follows it whenever when a retry happens.
-
-### Writing Your Own
-Implementing your own interceptor is pretty trivial: there are interfaces for that. But the interesting
-bit exposing common data to handlers (and other middleware), similarly to HTTP Middleware design.
-For example, you may want to pass the identity of the caller from the auth interceptor all the way
-to the handling function.
-
-For example, a client side interceptor example for auth looks like:
-
-	func FakeAuthUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-	   newCtx := context.WithValue(ctx, "user_id", "john@example.com")
-	   return handler(newCtx, req)
-	}
-
-Unfortunately, it's not as easy for streaming RPCs. These have the `context.Context` embedded within
-the `grpc.ServerStream` object. To pass values through context, a wrapper (`WrappedServerStream`) is
-needed. For example:
-
-	func FakeAuthStreamingInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
-	   newStream := grpc_middleware.WrapServerStream(stream)
-	   newStream.WrappedContext = context.WithValue(ctx, "user_id", "john@example.com")
-	   return handler(srv, stream)
-	}
-
-## <a name="pkg-imports">Imported Packages</a>
-
-- [golang.org/x/net/context](https://godoc.org/golang.org/x/net/context)
-- [google.golang.org/grpc](https://godoc.org/google.golang.org/grpc)
-
-## <a name="pkg-index">Index</a>
-* [func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor](#ChainStreamClient)
-* [func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor](#ChainStreamServer)
-* [func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor](#ChainUnaryClient)
-* [func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor](#ChainUnaryServer)
-* [func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption](#WithStreamServerChain)
-* [func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption](#WithUnaryServerChain)
-* [type WrappedServerStream](#WrappedServerStream)
-  * [func WrapServerStream(stream grpc.ServerStream) \*WrappedServerStream](#WrapServerStream)
-  * [func (w \*WrappedServerStream) Context() context.Context](#WrappedServerStream.Context)
-
-#### <a name="pkg-files">Package files</a>
-[chain.go](./chain.go) [doc.go](./doc.go) [wrappers.go](./wrappers.go) 
-
-## <a name="ChainStreamClient">func</a> [ChainStreamClient](./chain.go#L136)
-``` go
-func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor
-```
-ChainStreamClient creates a single interceptor out of a chain of many interceptors.
-
-Execution is done in left-to-right order, including passing of context.
-For example ChainStreamClient(one, two, three) will execute one before two before three.
-
-## <a name="ChainStreamServer">func</a> [ChainStreamServer](./chain.go#L58)
-``` go
-func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor
-```
-ChainStreamServer creates a single interceptor out of a chain of many interceptors.
-
-Execution is done in left-to-right order, including passing of context.
-For example ChainUnaryServer(one, two, three) will execute one before two before three.
-If you want to pass context between interceptors, use WrapServerStream.
-
-## <a name="ChainUnaryClient">func</a> [ChainUnaryClient](./chain.go#L97)
-``` go
-func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor
-```
-ChainUnaryClient creates a single interceptor out of a chain of many interceptors.
-
-Execution is done in left-to-right order, including passing of context.
-For example ChainUnaryClient(one, two, three) will execute one before two before three.
-
-## <a name="ChainUnaryServer">func</a> [ChainUnaryServer](./chain.go#L18)
-``` go
-func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor
-```
-ChainUnaryServer creates a single interceptor out of a chain of many interceptors.
-
-Execution is done in left-to-right order, including passing of context.
-For example ChainUnaryServer(one, two, three) will execute one before two before three, and three
-will see context changes of one and two.
-
-## <a name="WithStreamServerChain">func</a> [WithStreamServerChain](./chain.go#L181)
-``` go
-func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption
-```
-WithStreamServerChain is a grpc.Server config option that accepts multiple stream interceptors.
-Basically syntactic sugar.
-
-## <a name="WithUnaryServerChain">func</a> [WithUnaryServerChain](./chain.go#L175)
-``` go
-func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption
-```
-Chain creates a single interceptor out of a chain of many interceptors.
-
-WithUnaryServerChain is a grpc.Server config option that accepts multiple unary interceptors.
-Basically syntactic sugar.
-
-## <a name="WrappedServerStream">type</a> [WrappedServerStream](./wrappers.go#L12-L16)
-``` go
-type WrappedServerStream struct {
-    grpc.ServerStream
-    // WrappedContext is the wrapper's own Context. You can assign it.
-    WrappedContext context.Context
-}
-```
-WrappedServerStream is a thin wrapper around grpc.ServerStream that allows modifying context.
-
-### <a name="WrapServerStream">func</a> [WrapServerStream](./wrappers.go#L24)
-``` go
-func WrapServerStream(stream grpc.ServerStream) *WrappedServerStream
-```
-WrapServerStream returns a ServerStream that has the ability to overwrite context.
-
-### <a name="WrappedServerStream.Context">func</a> (\*WrappedServerStream) [Context](./wrappers.go#L19)
-``` go
-func (w *WrappedServerStream) Context() context.Context
-```
-Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context()
-
-- - -
-Generated by [godoc2ghmd](https://github.com/GandalfUK/godoc2ghmd)
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.lock b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.lock
deleted file mode 100644
index ebdcb75..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.lock
+++ /dev/null
@@ -1,123 +0,0 @@
-# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
-
-
-[[projects]]
-  name = "cloud.google.com/go"
-  packages = ["compute/metadata"]
-  revision = "2d3a6656c17a60b0815b7e06ab0be04eacb6e613"
-  version = "v0.16.0"
-
-[[projects]]
-  name = "github.com/davecgh/go-spew"
-  packages = ["spew"]
-  revision = "346938d642f2ec3594ed81d874461961cd0faa76"
-  version = "v1.1.0"
-
-[[projects]]
-  name = "github.com/gogo/protobuf"
-  packages = ["gogoproto","proto","protoc-gen-gogo/descriptor"]
-  revision = "342cbe0a04158f6dcb03ca0079991a51a4248c02"
-  version = "v0.5"
-
-[[projects]]
-  branch = "master"
-  name = "github.com/golang/protobuf"
-  packages = ["jsonpb","proto","ptypes","ptypes/any","ptypes/duration","ptypes/struct","ptypes/timestamp"]
-  revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
-
-[[projects]]
-  name = "github.com/opentracing/opentracing-go"
-  packages = [".","ext","log","mocktracer"]
-  revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38"
-  version = "v1.0.2"
-
-[[projects]]
-  name = "github.com/pmezard/go-difflib"
-  packages = ["difflib"]
-  revision = "792786c7400a136282c1664665ae0a8db921c6c2"
-  version = "v1.0.0"
-
-[[projects]]
-  name = "github.com/sirupsen/logrus"
-  packages = ["."]
-  revision = "f006c2ac4710855cf0f916dd6b77acf6b048dc6e"
-  version = "v1.0.3"
-
-[[projects]]
-  name = "github.com/stretchr/testify"
-  packages = ["assert","require","suite"]
-  revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0"
-  version = "v1.1.4"
-
-[[projects]]
-  name = "go.uber.org/atomic"
-  packages = ["."]
-  revision = "8474b86a5a6f79c443ce4b2992817ff32cf208b8"
-  version = "v1.3.1"
-
-[[projects]]
-  name = "go.uber.org/multierr"
-  packages = ["."]
-  revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a"
-  version = "v1.1.0"
-
-[[projects]]
-  name = "go.uber.org/zap"
-  packages = [".","buffer","internal/bufferpool","internal/color","internal/exit","zapcore"]
-  revision = "35aad584952c3e7020db7b839f6b102de6271f89"
-  version = "v1.7.1"
-
-[[projects]]
-  branch = "master"
-  name = "golang.org/x/crypto"
-  packages = ["ssh/terminal"]
-  revision = "94eea52f7b742c7cbe0b03b22f0c4c8631ece122"
-
-[[projects]]
-  branch = "master"
-  name = "golang.org/x/net"
-  packages = ["context","context/ctxhttp","http2","http2/hpack","idna","internal/timeseries","lex/httplex","trace"]
-  revision = "a8b9294777976932365dabb6640cf1468d95c70f"
-
-[[projects]]
-  branch = "master"
-  name = "golang.org/x/oauth2"
-  packages = [".","google","internal","jws","jwt"]
-  revision = "f95fa95eaa936d9d87489b15d1d18b97c1ba9c28"
-
-[[projects]]
-  branch = "master"
-  name = "golang.org/x/sys"
-  packages = ["unix","windows"]
-  revision = "13fcbd661c8ececa8807a29b48407d674b1d8ed8"
-
-[[projects]]
-  branch = "master"
-  name = "golang.org/x/text"
-  packages = ["collate","collate/build","internal/colltab","internal/gen","internal/tag","internal/triegen","internal/ucd","language","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
-  revision = "75cc3cad82b5f47d3fb229ddda8c5167da14f294"
-
-[[projects]]
-  name = "google.golang.org/appengine"
-  packages = [".","internal","internal/app_identity","internal/base","internal/datastore","internal/log","internal/modules","internal/remote_api","internal/urlfetch","urlfetch"]
-  revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
-  version = "v1.0.0"
-
-[[projects]]
-  branch = "master"
-  name = "google.golang.org/genproto"
-  packages = ["googleapis/rpc/status"]
-  revision = "7f0da29060c682909f650ad8ed4e515bd74fa12a"
-
-[[projects]]
-  name = "google.golang.org/grpc"
-  packages = [".","balancer","balancer/roundrobin","codes","connectivity","credentials","credentials/oauth","encoding","grpclb/grpc_lb_v1/messages","grpclog","internal","keepalive","metadata","naming","peer","resolver","resolver/dns","resolver/passthrough","stats","status","tap","transport"]
-  revision = "5a9f7b402fe85096d2e1d0383435ee1876e863d0"
-  version = "v1.8.0"
-
-[solve-meta]
-  analyzer-name = "dep"
-  analyzer-version = 1
-  inputs-digest = "b24c6670412eb0bc44ed1db77fecc52333f8725f3e3272bdc568f5683a63031f"
-  solver-name = "gps-cdcl"
-  solver-version = 1
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.toml b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.toml
deleted file mode 100644
index 0a7d4c1..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/Gopkg.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[[constraint]]
-  name = "github.com/gogo/protobuf"
-  version = "0.5.0"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/golang/protobuf"
-
-[[constraint]]
-  name = "github.com/opentracing/opentracing-go"
-  version = "1.0.2"
-
-[[constraint]]
-  name = "github.com/sirupsen/logrus"
-  version = "1.0.3"
-
-[[constraint]]
-  name = "github.com/stretchr/testify"
-  version = "1.1.4"
-
-[[constraint]]
-  name = "go.uber.org/zap"
-  version = "1.7.1"
-
-[[constraint]]
-  branch = "master"
-  name = "golang.org/x/net"
-
-[[constraint]]
-  branch = "master"
-  name = "golang.org/x/oauth2"
-
-[[constraint]]
-  name = "google.golang.org/grpc"
-  version = "1.8.0"
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE
deleted file mode 100644
index b2b0650..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md
deleted file mode 100644
index 52e5373..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/README.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Go gRPC Middleware
-
-[![Travis Build](https://travis-ci.org/grpc-ecosystem/go-grpc-middleware.svg?branch=master)](https://travis-ci.org/grpc-ecosystem/go-grpc-middleware)
-[![Go Report Card](https://goreportcard.com/badge/github.com/grpc-ecosystem/go-grpc-middleware)](https://goreportcard.com/report/github.com/grpc-ecosystem/go-grpc-middleware)
-[![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/grpc-ecosystem/go-grpc-middleware)
-[![SourceGraph](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-middleware/-/badge.svg)](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-middleware/?badge)
-[![codecov](https://codecov.io/gh/grpc-ecosystem/go-grpc-middleware/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc-ecosystem/go-grpc-middleware)
-[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
-[![quality: production](https://img.shields.io/badge/quality-production-orange.svg)](#status)
-[![Slack](slack.png)](https://join.slack.com/t/improbable-eng/shared_invite/enQtMzQ1ODcyMzQ5MjM4LWY5ZWZmNGM2ODc5MmViNmQ3ZTA3ZTY3NzQwOTBlMTkzZmIxZTIxODk0OWU3YjZhNWVlNDU3MDlkZGViZjhkMjc)
-
-[gRPC Go](https://github.com/grpc/grpc-go) Middleware: interceptors, helpers, utilities.
-
-**Important** The repo recently moved to `github.com/grpc-ecosystem/go-grpc-middleware`, please update your import paths.
-
-## Middleware
-
-[gRPC Go](https://github.com/grpc/grpc-go) recently acquired support for
-Interceptors, i.e. [middleware](https://medium.com/@matryer/writing-middleware-in-golang-and-how-go-makes-it-so-much-fun-4375c1246e81#.gv7tdlghs) 
-that is executed either on the gRPC Server before the request is passed onto the user's application logic, or on the gRPC client either around the user call. It is a perfect way to implement
-common patterns: auth, logging, message, validation, retries or monitoring.
-
-These are generic building blocks that make it easy to build multiple microservices easily.
-The purpose of this repository is to act as a go-to point for such reusable functionality. It contains
-some of them itself, but also will link to useful external repos.
-
-`grpc_middleware` itself provides support for chaining interceptors. See [Documentation](DOC.md), but here's an example:
-
-```go
-import "github.com/grpc-ecosystem/go-grpc-middleware"
-
-myServer := grpc.NewServer(
-    grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
-        grpc_ctxtags.StreamServerInterceptor(),
-        grpc_opentracing.StreamServerInterceptor(),
-        grpc_prometheus.StreamServerInterceptor,
-        grpc_zap.StreamServerInterceptor(zapLogger),
-        grpc_auth.StreamServerInterceptor(myAuthFunction),
-        grpc_recovery.StreamServerInterceptor(),
-    )),
-    grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
-        grpc_ctxtags.UnaryServerInterceptor(),
-        grpc_opentracing.UnaryServerInterceptor(),
-        grpc_prometheus.UnaryServerInterceptor,
-        grpc_zap.UnaryServerInterceptor(zapLogger),
-        grpc_auth.UnaryServerInterceptor(myAuthFunction),
-        grpc_recovery.UnaryServerInterceptor(),
-    )),
-)
-```
-
-## Interceptors
-
-*Please send a PR to add new interceptors or middleware to this list*
-
-#### Auth
-   * [`grpc_auth`](auth) - a customizable (via `AuthFunc`) piece of auth middleware 
-
-#### Logging
-   * [`grpc_ctxtags`](tags/) - a library that adds a `Tag` map to context, with data populated from request body
-   * [`grpc_zap`](logging/zap/) - integration of [zap](https://github.com/uber-go/zap) logging library into gRPC handlers.
-   * [`grpc_logrus`](logging/logrus/) - integration of [logrus](https://github.com/sirupsen/logrus) logging library into gRPC handlers.
-
-
-#### Monitoring
-   * [`grpc_prometheus`⚡](https://github.com/grpc-ecosystem/go-grpc-prometheus) - Prometheus client-side and server-side monitoring middleware
-   * [`otgrpc`⚡](https://github.com/grpc-ecosystem/grpc-opentracing/tree/master/go/otgrpc) - [OpenTracing](http://opentracing.io/) client-side and server-side interceptors
-   * [`grpc_opentracing`](tracing/opentracing) - [OpenTracing](http://opentracing.io/) client-side and server-side interceptors with support for streaming and handler-returned tags
-
-#### Client
-   * [`grpc_retry`](retry/) - a generic gRPC response code retry mechanism, client-side middleware
-
-#### Server
-   * [`grpc_validator`](validator/) - codegen inbound message validation from `.proto` options
-   * [`grpc_recovery`](recovery/) - turn panics into gRPC errors
-
-
-## Status
-
-This code has been running in *production* since May 2016 as the basis of the gRPC micro services stack at [Improbable](https://improbable.io).
-
-Additional tooling will be added, and contributions are welcome.
-
-## License
-
-`go-grpc-middleware` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/README.md
deleted file mode 120000
index 71bfc07..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/auth/README.md
+++ /dev/null
@@ -1 +0,0 @@
-DOC.md
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go
deleted file mode 100644
index 45a2f5f..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/chain.go
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2016 Michal Witkowski. All Rights Reserved.
-// See LICENSE for licensing terms.
-
-// gRPC Server Interceptor chaining middleware.
-
-package grpc_middleware
-
-import (
-	"golang.org/x/net/context"
-	"google.golang.org/grpc"
-)
-
-// ChainUnaryServer creates a single interceptor out of a chain of many interceptors.
-//
-// Execution is done in left-to-right order, including passing of context.
-// For example ChainUnaryServer(one, two, three) will execute one before two before three, and three
-// will see context changes of one and two.
-func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor {
-	n := len(interceptors)
-
-	if n > 1 {
-		lastI := n - 1
-		return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-			var (
-				chainHandler grpc.UnaryHandler
-				curI         int
-			)
-
-			chainHandler = func(currentCtx context.Context, currentReq interface{}) (interface{}, error) {
-				if curI == lastI {
-					return handler(currentCtx, currentReq)
-				}
-				curI++
-				resp, err := interceptors[curI](currentCtx, currentReq, info, chainHandler)
-				curI--
-				return resp, err
-			}
-
-			return interceptors[0](ctx, req, info, chainHandler)
-		}
-	}
-
-	if n == 1 {
-		return interceptors[0]
-	}
-
-	// n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
-	return func(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-		return handler(ctx, req)
-	}
-}
-
-// ChainStreamServer creates a single interceptor out of a chain of many interceptors.
-//
-// Execution is done in left-to-right order, including passing of context.
-// For example ChainUnaryServer(one, two, three) will execute one before two before three.
-// If you want to pass context between interceptors, use WrapServerStream.
-func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor {
-	n := len(interceptors)
-
-	if n > 1 {
-		lastI := n - 1
-		return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
-			var (
-				chainHandler grpc.StreamHandler
-				curI         int
-			)
-
-			chainHandler = func(currentSrv interface{}, currentStream grpc.ServerStream) error {
-				if curI == lastI {
-					return handler(currentSrv, currentStream)
-				}
-				curI++
-				err := interceptors[curI](currentSrv, currentStream, info, chainHandler)
-				curI--
-				return err
-			}
-
-			return interceptors[0](srv, stream, info, chainHandler)
-		}
-	}
-
-	if n == 1 {
-		return interceptors[0]
-	}
-
-	// n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
-	return func(srv interface{}, stream grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
-		return handler(srv, stream)
-	}
-}
-
-// ChainUnaryClient creates a single interceptor out of a chain of many interceptors.
-//
-// Execution is done in left-to-right order, including passing of context.
-// For example ChainUnaryClient(one, two, three) will execute one before two before three.
-func ChainUnaryClient(interceptors ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor {
-	n := len(interceptors)
-
-	if n > 1 {
-		lastI := n - 1
-		return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
-			var (
-				chainHandler grpc.UnaryInvoker
-				curI         int
-			)
-
-			chainHandler = func(currentCtx context.Context, currentMethod string, currentReq, currentRepl interface{}, currentConn *grpc.ClientConn, currentOpts ...grpc.CallOption) error {
-				if curI == lastI {
-					return invoker(currentCtx, currentMethod, currentReq, currentRepl, currentConn, currentOpts...)
-				}
-				curI++
-				err := interceptors[curI](currentCtx, currentMethod, currentReq, currentRepl, currentConn, chainHandler, currentOpts...)
-				curI--
-				return err
-			}
-
-			return interceptors[0](ctx, method, req, reply, cc, chainHandler, opts...)
-		}
-	}
-
-	if n == 1 {
-		return interceptors[0]
-	}
-
-	// n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
-	return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
-		return invoker(ctx, method, req, reply, cc, opts...)
-	}
-}
-
-// ChainStreamClient creates a single interceptor out of a chain of many interceptors.
-//
-// Execution is done in left-to-right order, including passing of context.
-// For example ChainStreamClient(one, two, three) will execute one before two before three.
-func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor {
-	n := len(interceptors)
-
-	if n > 1 {
-		lastI := n - 1
-		return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
-			var (
-				chainHandler grpc.Streamer
-				curI         int
-			)
-
-			chainHandler = func(currentCtx context.Context, currentDesc *grpc.StreamDesc, currentConn *grpc.ClientConn, currentMethod string, currentOpts ...grpc.CallOption) (grpc.ClientStream, error) {
-				if curI == lastI {
-					return streamer(currentCtx, currentDesc, currentConn, currentMethod, currentOpts...)
-				}
-				curI++
-				stream, err := interceptors[curI](currentCtx, currentDesc, currentConn, currentMethod, chainHandler, currentOpts...)
-				curI--
-				return stream, err
-			}
-
-			return interceptors[0](ctx, desc, cc, method, chainHandler, opts...)
-		}
-	}
-
-	if n == 1 {
-		return interceptors[0]
-	}
-
-	// n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
-	return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
-		return streamer(ctx, desc, cc, method, opts...)
-	}
-}
-
-// Chain creates a single interceptor out of a chain of many interceptors.
-//
-// WithUnaryServerChain is a grpc.Server config option that accepts multiple unary interceptors.
-// Basically syntactic sugar.
-func WithUnaryServerChain(interceptors ...grpc.UnaryServerInterceptor) grpc.ServerOption {
-	return grpc.UnaryInterceptor(ChainUnaryServer(interceptors...))
-}
-
-// WithStreamServerChain is a grpc.Server config option that accepts multiple stream interceptors.
-// Basically syntactic sugar.
-func WithStreamServerChain(interceptors ...grpc.StreamServerInterceptor) grpc.ServerOption {
-	return grpc.StreamInterceptor(ChainStreamServer(interceptors...))
-}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go
deleted file mode 100644
index 7168950..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/doc.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 Michal Witkowski. All Rights Reserved.
-// See LICENSE for licensing terms.
-
-/*
-`grpc_middleware` is a collection of gRPC middleware packages: interceptors, helpers and tools.
-
-Middleware
-
-gRPC is a fantastic RPC middleware, which sees a lot of adoption in the Golang world. However, the
-upstream gRPC codebase is relatively bare bones.
-
-This package, and most of its child packages provides commonly needed middleware for gRPC:
-client-side interceptors for retires, server-side interceptors for input validation and auth,
-functions for chaining said interceptors, metadata convenience methods and more.
-
-Chaining
-
-By default, gRPC doesn't allow one to have more than one interceptor either on the client nor on
-the server side. `grpc_middleware` provides convenient chaining methods
-
-Simple way of turning a multiple interceptors into a single interceptor. Here's an example for
-server chaining:
-
-	myServer := grpc.NewServer(
-	    grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(loggingStream, monitoringStream, authStream)),
-	    grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(loggingUnary, monitoringUnary, authUnary),
-	)
-
-These interceptors will be executed from left to right: logging, monitoring and auth.
-
-Here's an example for client side chaining:
-
-	clientConn, err = grpc.Dial(
-	    address,
-	        grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(monitoringClientUnary, retryUnary)),
-	        grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(monitoringClientStream, retryStream)),
-	)
-	client = pb_testproto.NewTestServiceClient(clientConn)
-	resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"})
-
-These interceptors will be executed from left to right: monitoring and then retry logic.
-
-The retry interceptor will call every interceptor that follows it whenever when a retry happens.
-
-Writing Your Own
-
-Implementing your own interceptor is pretty trivial: there are interfaces for that. But the interesting
-bit exposing common data to handlers (and other middleware), similarly to HTTP Middleware design.
-For example, you may want to pass the identity of the caller from the auth interceptor all the way
-to the handling function.
-
-For example, a client side interceptor example for auth looks like:
-
-	func FakeAuthUnaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-	   newCtx := context.WithValue(ctx, "user_id", "john@example.com")
-	   return handler(newCtx, req)
-	}
-
-Unfortunately, it's not as easy for streaming RPCs. These have the `context.Context` embedded within
-the `grpc.ServerStream` object. To pass values through context, a wrapper (`WrappedServerStream`) is
-needed. For example:
-
-	func FakeAuthStreamingInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
-	   newStream := grpc_middleware.WrapServerStream(stream)
-	   newStream.WrappedContext = context.WithValue(ctx, "user_id", "john@example.com")
-	   return handler(srv, stream)
-	}
-*/
-package grpc_middleware
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/README.md
deleted file mode 120000
index 71bfc07..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/README.md
+++ /dev/null
@@ -1 +0,0 @@
-DOC.md
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/README.md
deleted file mode 120000
index 71bfc07..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/README.md
+++ /dev/null
@@ -1 +0,0 @@
-DOC.md
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/README.md
deleted file mode 120000
index 71bfc07..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/README.md
+++ /dev/null
@@ -1 +0,0 @@
-DOC.md
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile
deleted file mode 100644
index 3e0f296..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-SHELL="/bin/bash"
-
-GOFILES_NOVENDOR = $(shell go list ./... | grep -v /vendor/)
-
-all: vet fmt docs test
-
-docs:
-	./scripts/docs.sh generate
-
-checkdocs:
-	./scripts/docs.sh check
-
-fmt:
-	go fmt $(GOFILES_NOVENDOR)
-
-vet:
-	go vet $(GOFILES_NOVENDOR)
-
-test: vet
-	./scripts/test_all.sh
-
-.PHONY: all docs validate test
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/README.md
deleted file mode 120000
index 71bfc07..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/recovery/README.md
+++ /dev/null
@@ -1 +0,0 @@
-DOC.md
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/README.md
deleted file mode 120000
index 71bfc07..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/README.md
+++ /dev/null
@@ -1 +0,0 @@
-DOC.md
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/slack.png b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/slack.png
deleted file mode 100644
index cc8f9a6..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/slack.png
+++ /dev/null
Binary files differ
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/README.md
deleted file mode 120000
index 71bfc07..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tags/README.md
+++ /dev/null
@@ -1 +0,0 @@
-DOC.md
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/README.md
deleted file mode 120000
index 71bfc07..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing/README.md
+++ /dev/null
@@ -1 +0,0 @@
-DOC.md
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/README.md
deleted file mode 120000
index 71bfc07..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/README.md
+++ /dev/null
@@ -1 +0,0 @@
-DOC.md
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go
deleted file mode 100644
index 597b862..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/wrappers.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 Michal Witkowski. All Rights Reserved.
-// See LICENSE for licensing terms.
-
-package grpc_middleware
-
-import (
-	"golang.org/x/net/context"
-	"google.golang.org/grpc"
-)
-
-// WrappedServerStream is a thin wrapper around grpc.ServerStream that allows modifying context.
-type WrappedServerStream struct {
-	grpc.ServerStream
-	// WrappedContext is the wrapper's own Context. You can assign it.
-	WrappedContext context.Context
-}
-
-// Context returns the wrapper's WrappedContext, overwriting the nested grpc.ServerStream.Context()
-func (w *WrappedServerStream) Context() context.Context {
-	return w.WrappedContext
-}
-
-// WrapServerStream returns a ServerStream that has the ability to overwrite context.
-func WrapServerStream(stream grpc.ServerStream) *WrappedServerStream {
-	if existing, ok := stream.(*WrappedServerStream); ok {
-		return existing
-	}
-	return &WrappedServerStream{ServerStream: stream, WrappedContext: stream.Context()}
-}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore
deleted file mode 100644
index 2233cff..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore
+++ /dev/null
@@ -1,201 +0,0 @@
-#vendor
-vendor/
-
-# Created by .ignore support plugin (hsz.mobi)
-coverage.txt
-### Go template
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
-*.prof
-### Windows template
-# Windows image file caches
-Thumbs.db
-ehthumbs.db
-
-# Folder config file
-Desktop.ini
-
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
-
-# Windows Installer files
-*.cab
-*.msi
-*.msm
-*.msp
-
-# Windows shortcuts
-*.lnk
-### Kate template
-# Swap Files #
-.*.kate-swp
-.swp.*
-### SublimeText template
-# cache files for sublime text
-*.tmlanguage.cache
-*.tmPreferences.cache
-*.stTheme.cache
-
-# workspace files are user-specific
-*.sublime-workspace
-
-# project files should be checked into the repository, unless a significant
-# proportion of contributors will probably not be using SublimeText
-# *.sublime-project
-
-# sftp configuration file
-sftp-config.json
-### Linux template
-*~
-
-# temporary files which can be created if a process still has a handle open of a deleted file
-.fuse_hidden*
-
-# KDE directory preferences
-.directory
-
-# Linux trash folder which might appear on any partition or disk
-.Trash-*
-### JetBrains template
-# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
-# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
-
-# User-specific stuff:
-.idea
-.idea/tasks.xml
-.idea/dictionaries
-.idea/vcs.xml
-.idea/jsLibraryMappings.xml
-
-# Sensitive or high-churn files:
-.idea/dataSources.ids
-.idea/dataSources.xml
-.idea/dataSources.local.xml
-.idea/sqlDataSources.xml
-.idea/dynamic.xml
-.idea/uiDesigner.xml
-
-# Gradle:
-.idea/gradle.xml
-.idea/libraries
-
-# Mongo Explorer plugin:
-.idea/mongoSettings.xml
-
-## File-based project format:
-*.iws
-
-## Plugin-specific files:
-
-# IntelliJ
-/out/
-
-# mpeltonen/sbt-idea plugin
-.idea_modules/
-
-# JIRA plugin
-atlassian-ide-plugin.xml
-
-# Crashlytics plugin (for Android Studio and IntelliJ)
-com_crashlytics_export_strings.xml
-crashlytics.properties
-crashlytics-build.properties
-fabric.properties
-### Xcode template
-# Xcode
-#
-# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
-
-## Build generated
-build/
-DerivedData/
-
-## Various settings
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata/
-
-## Other
-*.moved-aside
-*.xccheckout
-*.xcscmblueprint
-### Eclipse template
-
-.metadata
-bin/
-tmp/
-*.tmp
-*.bak
-*.swp
-*~.nib
-local.properties
-.settings/
-.loadpath
-.recommenders
-
-# Eclipse Core
-.project
-
-# External tool builders
-.externalToolBuilders/
-
-# Locally stored "Eclipse launch configurations"
-*.launch
-
-# PyDev specific (Python IDE for Eclipse)
-*.pydevproject
-
-# CDT-specific (C/C++ Development Tooling)
-.cproject
-
-# JDT-specific (Eclipse Java Development Tools)
-.classpath
-
-# Java annotation processor (APT)
-.factorypath
-
-# PDT-specific (PHP Development Tools)
-.buildpath
-
-# sbteclipse plugin
-.target
-
-# Tern plugin
-.tern-project
-
-# TeXlipse plugin
-.texlipse
-
-# STS (Spring Tool Suite)
-.springBeans
-
-# Code Recommenders
-.recommenders/
-
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml
deleted file mode 100644
index 2a845b9..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.travis.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-sudo: false
-language: go
-# * github.com/grpc/grpc-go still supports go1.6
-#   - When we drop support for go1.6 we can remove golang.org/x/net/context
-#     below as it is part of the Go std library since go1.7
-# * github.com/prometheus/client_golang already requires at least go1.7 since
-#   September 2017
-go:
-  - 1.6.x
-  - 1.7.x
-  - 1.8.x
-  - 1.9.x
-  - 1.10.x
-  - master
-
-install:
-  - go get github.com/prometheus/client_golang/prometheus
-  - go get google.golang.org/grpc
-  - go get golang.org/x/net/context
-  - go get github.com/stretchr/testify
-script:
- - make test 
-
-after_success:
-  - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md
deleted file mode 100644
index 19a8059..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# Changelog
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
-and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
-
-## [Unreleased]
-
-## [1.2.0](https://github.com/grpc-ecosystem/go-grpc-prometheus/releases/tag/v1.2.0) - 2018-06-04
-
-### Added
-
-* Provide metrics object as `prometheus.Collector`, for conventional metric registration.
-* Support non-default/global Prometheus registry.
-* Allow configuring counters with `prometheus.CounterOpts`.
-
-### Changed
-
-* Remove usage of deprecated `grpc.Code()`.
-* Remove usage of deprecated `grpc.Errorf` and replace with `status.Errorf`.
-
----
-
-This changelog was started with version `v1.2.0`, for earlier versions refer to the respective [GitHub releases](https://github.com/grpc-ecosystem/go-grpc-prometheus/releases).
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE
deleted file mode 100644
index b2b0650..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
\ No newline at end of file
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md
deleted file mode 100644
index 499c583..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md
+++ /dev/null
@@ -1,247 +0,0 @@
-# Go gRPC Interceptors for Prometheus monitoring 
-
-[![Travis Build](https://travis-ci.org/grpc-ecosystem/go-grpc-prometheus.svg)](https://travis-ci.org/grpc-ecosystem/go-grpc-prometheus)
-[![Go Report Card](https://goreportcard.com/badge/github.com/grpc-ecosystem/go-grpc-prometheus)](http://goreportcard.com/report/grpc-ecosystem/go-grpc-prometheus)
-[![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/grpc-ecosystem/go-grpc-prometheus)
-[![SourceGraph](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/-/badge.svg)](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/?badge)
-[![codecov](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus)
-[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
-
-[Prometheus](https://prometheus.io/) monitoring for your [gRPC Go](https://github.com/grpc/grpc-go) servers and clients.
-
-A sister implementation for [gRPC Java](https://github.com/grpc/grpc-java) (same metrics, same semantics) is in [grpc-ecosystem/java-grpc-prometheus](https://github.com/grpc-ecosystem/java-grpc-prometheus).
-
-## Interceptors
-
-[gRPC Go](https://github.com/grpc/grpc-go) recently acquired support for Interceptors, i.e. middleware that is executed
-by a gRPC Server before the request is passed onto the user's application logic. It is a perfect way to implement
-common patterns: auth, logging and... monitoring.
-
-To use Interceptors in chains, please see [`go-grpc-middleware`](https://github.com/mwitkow/go-grpc-middleware).
-
-## Usage
-
-There are two types of interceptors: client-side and server-side. This package provides monitoring Interceptors for both.
-
-### Server-side
-
-```go
-import "github.com/grpc-ecosystem/go-grpc-prometheus"
-...
-    // Initialize your gRPC server's interceptor.
-    myServer := grpc.NewServer(
-        grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
-        grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
-    )
-    // Register your gRPC service implementations.
-    myservice.RegisterMyServiceServer(s.server, &myServiceImpl{})
-    // After all your registrations, make sure all of the Prometheus metrics are initialized.
-    grpc_prometheus.Register(myServer)
-    // Register Prometheus metrics handler.    
-    http.Handle("/metrics", promhttp.Handler())
-...
-```
-
-### Client-side
-
-```go
-import "github.com/grpc-ecosystem/go-grpc-prometheus"
-...
-   clientConn, err = grpc.Dial(
-       address,
-		   grpc.WithUnaryInterceptor(grpc_prometheus.UnaryClientInterceptor),
-		   grpc.WithStreamInterceptor(grpc_prometheus.StreamClientInterceptor)
-   )
-   client = pb_testproto.NewTestServiceClient(clientConn)
-   resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"})
-...
-```
-
-# Metrics
-
-## Labels
-
-All server-side metrics start with `grpc_server` as Prometheus subsystem name. All client-side metrics start with `grpc_client`. Both of them have mirror-concepts. Similarly all methods
-contain the same rich labels:
-  
-  * `grpc_service` - the [gRPC service](http://www.grpc.io/docs/#defining-a-service) name, which is the combination of protobuf `package` and
-    the `grpc_service` section name. E.g. for `package = mwitkow.testproto` and 
-     `service TestService` the label will be `grpc_service="mwitkow.testproto.TestService"`
-  * `grpc_method` - the name of the method called on the gRPC service. E.g.  
-    `grpc_method="Ping"`
-  * `grpc_type` - the gRPC [type of request](http://www.grpc.io/docs/guides/concepts.html#rpc-life-cycle). 
-    Differentiating between the two is important especially for latency measurements.
-
-     - `unary` is single request, single response RPC
-     - `client_stream` is a multi-request, single response RPC
-     - `server_stream` is a single request, multi-response RPC
-     - `bidi_stream` is a multi-request, multi-response RPC
-    
-
-Additionally for completed RPCs, the following labels are used:
-
-  * `grpc_code` - the human-readable [gRPC status code](https://github.com/grpc/grpc-go/blob/master/codes/codes.go).
-    The list of all statuses is to long, but here are some common ones:
-      
-      - `OK` - means the RPC was successful
-      - `IllegalArgument` - RPC contained bad values
-      - `Internal` - server-side error not disclosed to the clients
-      
-## Counters
-
-The counters and their up to date documentation is in [server_reporter.go](server_reporter.go) and [client_reporter.go](client_reporter.go) 
-the respective Prometheus handler (usually `/metrics`). 
-
-For the purpose of this documentation we will only discuss `grpc_server` metrics. The `grpc_client` ones contain mirror concepts.
-
-For simplicity, let's assume we're tracking a single server-side RPC call of [`mwitkow.testproto.TestService`](examples/testproto/test.proto),
-calling the method `PingList`. The call succeeds and returns 20 messages in the stream.
-
-First, immediately after the server receives the call it will increment the
-`grpc_server_started_total` and start the handling time clock (if histograms are enabled). 
-
-```jsoniq
-grpc_server_started_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1
-```
-
-Then the user logic gets invoked. It receives one message from the client containing the request 
-(it's a `server_stream`):
-
-```jsoniq
-grpc_server_msg_received_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1
-```
-
-The user logic may return an error, or send multiple messages back to the client. In this case, on 
-each of the 20 messages sent back, a counter will be incremented:
-
-```jsoniq
-grpc_server_msg_sent_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 20
-```
-
-After the call completes, its status (`OK` or other [gRPC status code](https://github.com/grpc/grpc-go/blob/master/codes/codes.go)) 
-and the relevant call labels increment the `grpc_server_handled_total` counter.
-
-```jsoniq
-grpc_server_handled_total{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1
-```
-
-## Histograms
-
-[Prometheus histograms](https://prometheus.io/docs/concepts/metric_types/#histogram) are a great way
-to measure latency distributions of your RPCs. However, since it is bad practice to have metrics
-of [high cardinality](https://prometheus.io/docs/practices/instrumentation/#do-not-overuse-labels)
-the latency monitoring metrics are disabled by default. To enable them please call the following
-in your server initialization code:
-
-```jsoniq
-grpc_prometheus.EnableHandlingTimeHistogram()
-```
-
-After the call completes, its handling time will be recorded in a [Prometheus histogram](https://prometheus.io/docs/concepts/metric_types/#histogram)
-variable `grpc_server_handling_seconds`. The histogram variable contains three sub-metrics:
-
- * `grpc_server_handling_seconds_count` - the count of all completed RPCs by status and method 
- * `grpc_server_handling_seconds_sum` - cumulative time of RPCs by status and method, useful for 
-   calculating average handling times
- * `grpc_server_handling_seconds_bucket` - contains the counts of RPCs by status and method in respective
-   handling-time buckets. These buckets can be used by Prometheus to estimate SLAs (see [here](https://prometheus.io/docs/practices/histograms/))
-
-The counter values will look as follows:
-
-```jsoniq
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.005"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.01"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.025"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.05"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.1"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.25"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.5"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="1"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="2.5"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="5"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="10"} 1
-grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="+Inf"} 1
-grpc_server_handling_seconds_sum{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 0.0003866430000000001
-grpc_server_handling_seconds_count{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1
-```
-
-
-## Useful query examples
-
-Prometheus philosophy is to provide raw metrics to the monitoring system, and
-let the aggregations be handled there. The verbosity of above metrics make it possible to have that
-flexibility. Here's a couple of useful monitoring queries:
-
-
-### request inbound rate
-```jsoniq
-sum(rate(grpc_server_started_total{job="foo"}[1m])) by (grpc_service)
-```
-For `job="foo"` (common label to differentiate between Prometheus monitoring targets), calculate the
-rate of requests per second (1 minute window) for each gRPC `grpc_service` that the job has. Please note
-how the `grpc_method` is being omitted here: all methods of a given gRPC service will be summed together.
-
-### unary request error rate
-```jsoniq
-sum(rate(grpc_server_handled_total{job="foo",grpc_type="unary",grpc_code!="OK"}[1m])) by (grpc_service)
-```
-For `job="foo"`, calculate the per-`grpc_service` rate of `unary` (1:1) RPCs that failed, i.e. the 
-ones that didn't finish with `OK` code.
-
-### unary request error percentage
-```jsoniq
-sum(rate(grpc_server_handled_total{job="foo",grpc_type="unary",grpc_code!="OK"}[1m])) by (grpc_service)
- / 
-sum(rate(grpc_server_started_total{job="foo",grpc_type="unary"}[1m])) by (grpc_service)
- * 100.0
-```
-For `job="foo"`, calculate the percentage of failed requests by service. It's easy to notice that
-this is a combination of the two above examples. This is an example of a query you would like to
-[alert on](https://prometheus.io/docs/alerting/rules/) in your system for SLA violations, e.g.
-"no more than 1% requests should fail".
-
-### average response stream size
-```jsoniq
-sum(rate(grpc_server_msg_sent_total{job="foo",grpc_type="server_stream"}[10m])) by (grpc_service)
- /
-sum(rate(grpc_server_started_total{job="foo",grpc_type="server_stream"}[10m])) by (grpc_service)
-```
-For `job="foo"` what is the `grpc_service`-wide `10m` average of messages returned for all `
-server_stream` RPCs. This allows you to track the stream sizes returned by your system, e.g. allows 
-you to track when clients started to send "wide" queries that ret
-Note the divisor is the number of started RPCs, in order to account for in-flight requests.
-
-### 99%-tile latency of unary requests
-```jsoniq
-histogram_quantile(0.99, 
-  sum(rate(grpc_server_handling_seconds_bucket{job="foo",grpc_type="unary"}[5m])) by (grpc_service,le)
-)
-```
-For `job="foo"`, returns an 99%-tile [quantile estimation](https://prometheus.io/docs/practices/histograms/#quantiles)
-of the handling time of RPCs per service. Please note the `5m` rate, this means that the quantile
-estimation will take samples in a rolling `5m` window. When combined with other quantiles
-(e.g. 50%, 90%), this query gives you tremendous insight into the responsiveness of your system 
-(e.g. impact of caching).
-
-### percentage of slow unary queries (>250ms)
-```jsoniq
-100.0 - (
-sum(rate(grpc_server_handling_seconds_bucket{job="foo",grpc_type="unary",le="0.25"}[5m])) by (grpc_service)
- / 
-sum(rate(grpc_server_handling_seconds_count{job="foo",grpc_type="unary"}[5m])) by (grpc_service)
-) * 100.0
-```
-For `job="foo"` calculate the by-`grpc_service` fraction of slow requests that took longer than `0.25` 
-seconds. This query is relatively complex, since the Prometheus aggregations use `le` (less or equal)
-buckets, meaning that counting "fast" requests fractions is easier. However, simple maths helps.
-This is an example of a query you would like to alert on in your system for SLA violations, 
-e.g. "less than 1% of requests are slower than 250ms".
-
-
-## Status
-
-This code has been used since August 2015 as the basis for monitoring of *production* gRPC micro services  at [Improbable](https://improbable.io).
-
-## License
-
-`go-grpc-prometheus` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go
deleted file mode 100644
index 751a4c7..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2016 Michal Witkowski. All Rights Reserved.
-// See LICENSE for licensing terms.
-
-// gRPC Prometheus monitoring interceptors for client-side gRPC.
-
-package grpc_prometheus
-
-import (
-	prom "github.com/prometheus/client_golang/prometheus"
-)
-
-var (
-	// DefaultClientMetrics is the default instance of ClientMetrics. It is
-	// intended to be used in conjunction the default Prometheus metrics
-	// registry.
-	DefaultClientMetrics = NewClientMetrics()
-
-	// UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs.
-	UnaryClientInterceptor = DefaultClientMetrics.UnaryClientInterceptor()
-
-	// StreamClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs.
-	StreamClientInterceptor = DefaultClientMetrics.StreamClientInterceptor()
-)
-
-func init() {
-	prom.MustRegister(DefaultClientMetrics.clientStartedCounter)
-	prom.MustRegister(DefaultClientMetrics.clientHandledCounter)
-	prom.MustRegister(DefaultClientMetrics.clientStreamMsgReceived)
-	prom.MustRegister(DefaultClientMetrics.clientStreamMsgSent)
-}
-
-// EnableClientHandlingTimeHistogram turns on recording of handling time of
-// RPCs. Histogram metrics can be very expensive for Prometheus to retain and
-// query. This function acts on the DefaultClientMetrics variable and the
-// default Prometheus metrics registry.
-func EnableClientHandlingTimeHistogram(opts ...HistogramOption) {
-	DefaultClientMetrics.EnableClientHandlingTimeHistogram(opts...)
-	prom.Register(DefaultClientMetrics.clientHandledHistogram)
-}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go
deleted file mode 100644
index 9b476f9..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go
+++ /dev/null
@@ -1,170 +0,0 @@
-package grpc_prometheus
-
-import (
-	"io"
-
-	prom "github.com/prometheus/client_golang/prometheus"
-	"golang.org/x/net/context"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/status"
-)
-
-// ClientMetrics represents a collection of metrics to be registered on a
-// Prometheus metrics registry for a gRPC client.
-type ClientMetrics struct {
-	clientStartedCounter          *prom.CounterVec
-	clientHandledCounter          *prom.CounterVec
-	clientStreamMsgReceived       *prom.CounterVec
-	clientStreamMsgSent           *prom.CounterVec
-	clientHandledHistogramEnabled bool
-	clientHandledHistogramOpts    prom.HistogramOpts
-	clientHandledHistogram        *prom.HistogramVec
-}
-
-// NewClientMetrics returns a ClientMetrics object. Use a new instance of
-// ClientMetrics when not using the default Prometheus metrics registry, for
-// example when wanting to control which metrics are added to a registry as
-// opposed to automatically adding metrics via init functions.
-func NewClientMetrics(counterOpts ...CounterOption) *ClientMetrics {
-	opts := counterOptions(counterOpts)
-	return &ClientMetrics{
-		clientStartedCounter: prom.NewCounterVec(
-			opts.apply(prom.CounterOpts{
-				Name: "grpc_client_started_total",
-				Help: "Total number of RPCs started on the client.",
-			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
-
-		clientHandledCounter: prom.NewCounterVec(
-			opts.apply(prom.CounterOpts{
-				Name: "grpc_client_handled_total",
-				Help: "Total number of RPCs completed by the client, regardless of success or failure.",
-			}), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}),
-
-		clientStreamMsgReceived: prom.NewCounterVec(
-			opts.apply(prom.CounterOpts{
-				Name: "grpc_client_msg_received_total",
-				Help: "Total number of RPC stream messages received by the client.",
-			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
-
-		clientStreamMsgSent: prom.NewCounterVec(
-			opts.apply(prom.CounterOpts{
-				Name: "grpc_client_msg_sent_total",
-				Help: "Total number of gRPC stream messages sent by the client.",
-			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
-
-		clientHandledHistogramEnabled: false,
-		clientHandledHistogramOpts: prom.HistogramOpts{
-			Name:    "grpc_client_handling_seconds",
-			Help:    "Histogram of response latency (seconds) of the gRPC until it is finished by the application.",
-			Buckets: prom.DefBuckets,
-		},
-		clientHandledHistogram: nil,
-	}
-}
-
-// Describe sends the super-set of all possible descriptors of metrics
-// collected by this Collector to the provided channel and returns once
-// the last descriptor has been sent.
-func (m *ClientMetrics) Describe(ch chan<- *prom.Desc) {
-	m.clientStartedCounter.Describe(ch)
-	m.clientHandledCounter.Describe(ch)
-	m.clientStreamMsgReceived.Describe(ch)
-	m.clientStreamMsgSent.Describe(ch)
-	if m.clientHandledHistogramEnabled {
-		m.clientHandledHistogram.Describe(ch)
-	}
-}
-
-// Collect is called by the Prometheus registry when collecting
-// metrics. The implementation sends each collected metric via the
-// provided channel and returns once the last metric has been sent.
-func (m *ClientMetrics) Collect(ch chan<- prom.Metric) {
-	m.clientStartedCounter.Collect(ch)
-	m.clientHandledCounter.Collect(ch)
-	m.clientStreamMsgReceived.Collect(ch)
-	m.clientStreamMsgSent.Collect(ch)
-	if m.clientHandledHistogramEnabled {
-		m.clientHandledHistogram.Collect(ch)
-	}
-}
-
-// EnableClientHandlingTimeHistogram turns on recording of handling time of RPCs.
-// Histogram metrics can be very expensive for Prometheus to retain and query.
-func (m *ClientMetrics) EnableClientHandlingTimeHistogram(opts ...HistogramOption) {
-	for _, o := range opts {
-		o(&m.clientHandledHistogramOpts)
-	}
-	if !m.clientHandledHistogramEnabled {
-		m.clientHandledHistogram = prom.NewHistogramVec(
-			m.clientHandledHistogramOpts,
-			[]string{"grpc_type", "grpc_service", "grpc_method"},
-		)
-	}
-	m.clientHandledHistogramEnabled = true
-}
-
-// UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs.
-func (m *ClientMetrics) UnaryClientInterceptor() func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
-	return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
-		monitor := newClientReporter(m, Unary, method)
-		monitor.SentMessage()
-		err := invoker(ctx, method, req, reply, cc, opts...)
-		if err != nil {
-			monitor.ReceivedMessage()
-		}
-		st, _ := status.FromError(err)
-		monitor.Handled(st.Code())
-		return err
-	}
-}
-
-// StreamClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs.
-func (m *ClientMetrics) StreamClientInterceptor() func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
-	return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
-		monitor := newClientReporter(m, clientStreamType(desc), method)
-		clientStream, err := streamer(ctx, desc, cc, method, opts...)
-		if err != nil {
-			st, _ := status.FromError(err)
-			monitor.Handled(st.Code())
-			return nil, err
-		}
-		return &monitoredClientStream{clientStream, monitor}, nil
-	}
-}
-
-func clientStreamType(desc *grpc.StreamDesc) grpcType {
-	if desc.ClientStreams && !desc.ServerStreams {
-		return ClientStream
-	} else if !desc.ClientStreams && desc.ServerStreams {
-		return ServerStream
-	}
-	return BidiStream
-}
-
-// monitoredClientStream wraps grpc.ClientStream allowing each Sent/Recv of message to increment counters.
-type monitoredClientStream struct {
-	grpc.ClientStream
-	monitor *clientReporter
-}
-
-func (s *monitoredClientStream) SendMsg(m interface{}) error {
-	err := s.ClientStream.SendMsg(m)
-	if err == nil {
-		s.monitor.SentMessage()
-	}
-	return err
-}
-
-func (s *monitoredClientStream) RecvMsg(m interface{}) error {
-	err := s.ClientStream.RecvMsg(m)
-	if err == nil {
-		s.monitor.ReceivedMessage()
-	} else if err == io.EOF {
-		s.monitor.Handled(codes.OK)
-	} else {
-		st, _ := status.FromError(err)
-		s.monitor.Handled(st.Code())
-	}
-	return err
-}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go
deleted file mode 100644
index cbf1532..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 Michal Witkowski. All Rights Reserved.
-// See LICENSE for licensing terms.
-
-package grpc_prometheus
-
-import (
-	"time"
-
-	"google.golang.org/grpc/codes"
-)
-
-type clientReporter struct {
-	metrics     *ClientMetrics
-	rpcType     grpcType
-	serviceName string
-	methodName  string
-	startTime   time.Time
-}
-
-func newClientReporter(m *ClientMetrics, rpcType grpcType, fullMethod string) *clientReporter {
-	r := &clientReporter{
-		metrics: m,
-		rpcType: rpcType,
-	}
-	if r.metrics.clientHandledHistogramEnabled {
-		r.startTime = time.Now()
-	}
-	r.serviceName, r.methodName = splitMethodName(fullMethod)
-	r.metrics.clientStartedCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc()
-	return r
-}
-
-func (r *clientReporter) ReceivedMessage() {
-	r.metrics.clientStreamMsgReceived.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc()
-}
-
-func (r *clientReporter) SentMessage() {
-	r.metrics.clientStreamMsgSent.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc()
-}
-
-func (r *clientReporter) Handled(code codes.Code) {
-	r.metrics.clientHandledCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName, code.String()).Inc()
-	if r.metrics.clientHandledHistogramEnabled {
-		r.metrics.clientHandledHistogram.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Observe(time.Since(r.startTime).Seconds())
-	}
-}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile
deleted file mode 100644
index 74c0842..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-SHELL="/bin/bash"
-
-GOFILES_NOVENDOR = $(shell go list ./... | grep -v /vendor/)
-
-all: vet fmt test
-
-fmt:
-	go fmt $(GOFILES_NOVENDOR)
-
-vet:
-	go vet $(GOFILES_NOVENDOR)
-
-test: vet
-	./scripts/test_all.sh
-
-.PHONY: all vet test
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go
deleted file mode 100644
index 9d51aec..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package grpc_prometheus
-
-import (
-	prom "github.com/prometheus/client_golang/prometheus"
-)
-
-// A CounterOption lets you add options to Counter metrics using With* funcs.
-type CounterOption func(*prom.CounterOpts)
-
-type counterOptions []CounterOption
-
-func (co counterOptions) apply(o prom.CounterOpts) prom.CounterOpts {
-	for _, f := range co {
-		f(&o)
-	}
-	return o
-}
-
-// WithConstLabels allows you to add ConstLabels to Counter metrics.
-func WithConstLabels(labels prom.Labels) CounterOption {
-	return func(o *prom.CounterOpts) {
-		o.ConstLabels = labels
-	}
-}
-
-// A HistogramOption lets you add options to Histogram metrics using With*
-// funcs.
-type HistogramOption func(*prom.HistogramOpts)
-
-// WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on.
-func WithHistogramBuckets(buckets []float64) HistogramOption {
-	return func(o *prom.HistogramOpts) { o.Buckets = buckets }
-}
-
-// WithHistogramConstLabels allows you to add custom ConstLabels to
-// histograms metrics.
-func WithHistogramConstLabels(labels prom.Labels) HistogramOption {
-	return func(o *prom.HistogramOpts) {
-		o.ConstLabels = labels
-	}
-}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go
deleted file mode 100644
index 322f990..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2016 Michal Witkowski. All Rights Reserved.
-// See LICENSE for licensing terms.
-
-// gRPC Prometheus monitoring interceptors for server-side gRPC.
-
-package grpc_prometheus
-
-import (
-	prom "github.com/prometheus/client_golang/prometheus"
-	"google.golang.org/grpc"
-)
-
-var (
-	// DefaultServerMetrics is the default instance of ServerMetrics. It is
-	// intended to be used in conjunction the default Prometheus metrics
-	// registry.
-	DefaultServerMetrics = NewServerMetrics()
-
-	// UnaryServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Unary RPCs.
-	UnaryServerInterceptor = DefaultServerMetrics.UnaryServerInterceptor()
-
-	// StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs.
-	StreamServerInterceptor = DefaultServerMetrics.StreamServerInterceptor()
-)
-
-func init() {
-	prom.MustRegister(DefaultServerMetrics.serverStartedCounter)
-	prom.MustRegister(DefaultServerMetrics.serverHandledCounter)
-	prom.MustRegister(DefaultServerMetrics.serverStreamMsgReceived)
-	prom.MustRegister(DefaultServerMetrics.serverStreamMsgSent)
-}
-
-// Register takes a gRPC server and pre-initializes all counters to 0. This
-// allows for easier monitoring in Prometheus (no missing metrics), and should
-// be called *after* all services have been registered with the server. This
-// function acts on the DefaultServerMetrics variable.
-func Register(server *grpc.Server) {
-	DefaultServerMetrics.InitializeMetrics(server)
-}
-
-// EnableHandlingTimeHistogram turns on recording of handling time
-// of RPCs. Histogram metrics can be very expensive for Prometheus
-// to retain and query. This function acts on the DefaultServerMetrics
-// variable and the default Prometheus metrics registry.
-func EnableHandlingTimeHistogram(opts ...HistogramOption) {
-	DefaultServerMetrics.EnableHandlingTimeHistogram(opts...)
-	prom.Register(DefaultServerMetrics.serverHandledHistogram)
-}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go
deleted file mode 100644
index 5b1467e..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go
+++ /dev/null
@@ -1,185 +0,0 @@
-package grpc_prometheus
-
-import (
-	prom "github.com/prometheus/client_golang/prometheus"
-	"golang.org/x/net/context"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/status"
-)
-
-// ServerMetrics represents a collection of metrics to be registered on a
-// Prometheus metrics registry for a gRPC server.
-type ServerMetrics struct {
-	serverStartedCounter          *prom.CounterVec
-	serverHandledCounter          *prom.CounterVec
-	serverStreamMsgReceived       *prom.CounterVec
-	serverStreamMsgSent           *prom.CounterVec
-	serverHandledHistogramEnabled bool
-	serverHandledHistogramOpts    prom.HistogramOpts
-	serverHandledHistogram        *prom.HistogramVec
-}
-
-// NewServerMetrics returns a ServerMetrics object. Use a new instance of
-// ServerMetrics when not using the default Prometheus metrics registry, for
-// example when wanting to control which metrics are added to a registry as
-// opposed to automatically adding metrics via init functions.
-func NewServerMetrics(counterOpts ...CounterOption) *ServerMetrics {
-	opts := counterOptions(counterOpts)
-	return &ServerMetrics{
-		serverStartedCounter: prom.NewCounterVec(
-			opts.apply(prom.CounterOpts{
-				Name: "grpc_server_started_total",
-				Help: "Total number of RPCs started on the server.",
-			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
-		serverHandledCounter: prom.NewCounterVec(
-			opts.apply(prom.CounterOpts{
-				Name: "grpc_server_handled_total",
-				Help: "Total number of RPCs completed on the server, regardless of success or failure.",
-			}), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}),
-		serverStreamMsgReceived: prom.NewCounterVec(
-			opts.apply(prom.CounterOpts{
-				Name: "grpc_server_msg_received_total",
-				Help: "Total number of RPC stream messages received on the server.",
-			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
-		serverStreamMsgSent: prom.NewCounterVec(
-			opts.apply(prom.CounterOpts{
-				Name: "grpc_server_msg_sent_total",
-				Help: "Total number of gRPC stream messages sent by the server.",
-			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
-		serverHandledHistogramEnabled: false,
-		serverHandledHistogramOpts: prom.HistogramOpts{
-			Name:    "grpc_server_handling_seconds",
-			Help:    "Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.",
-			Buckets: prom.DefBuckets,
-		},
-		serverHandledHistogram: nil,
-	}
-}
-
-// EnableHandlingTimeHistogram enables histograms being registered when
-// registering the ServerMetrics on a Prometheus registry. Histograms can be
-// expensive on Prometheus servers. It takes options to configure histogram
-// options such as the defined buckets.
-func (m *ServerMetrics) EnableHandlingTimeHistogram(opts ...HistogramOption) {
-	for _, o := range opts {
-		o(&m.serverHandledHistogramOpts)
-	}
-	if !m.serverHandledHistogramEnabled {
-		m.serverHandledHistogram = prom.NewHistogramVec(
-			m.serverHandledHistogramOpts,
-			[]string{"grpc_type", "grpc_service", "grpc_method"},
-		)
-	}
-	m.serverHandledHistogramEnabled = true
-}
-
-// Describe sends the super-set of all possible descriptors of metrics
-// collected by this Collector to the provided channel and returns once
-// the last descriptor has been sent.
-func (m *ServerMetrics) Describe(ch chan<- *prom.Desc) {
-	m.serverStartedCounter.Describe(ch)
-	m.serverHandledCounter.Describe(ch)
-	m.serverStreamMsgReceived.Describe(ch)
-	m.serverStreamMsgSent.Describe(ch)
-	if m.serverHandledHistogramEnabled {
-		m.serverHandledHistogram.Describe(ch)
-	}
-}
-
-// Collect is called by the Prometheus registry when collecting
-// metrics. The implementation sends each collected metric via the
-// provided channel and returns once the last metric has been sent.
-func (m *ServerMetrics) Collect(ch chan<- prom.Metric) {
-	m.serverStartedCounter.Collect(ch)
-	m.serverHandledCounter.Collect(ch)
-	m.serverStreamMsgReceived.Collect(ch)
-	m.serverStreamMsgSent.Collect(ch)
-	if m.serverHandledHistogramEnabled {
-		m.serverHandledHistogram.Collect(ch)
-	}
-}
-
-// UnaryServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Unary RPCs.
-func (m *ServerMetrics) UnaryServerInterceptor() func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-		monitor := newServerReporter(m, Unary, info.FullMethod)
-		monitor.ReceivedMessage()
-		resp, err := handler(ctx, req)
-		st, _ := status.FromError(err)
-		monitor.Handled(st.Code())
-		if err == nil {
-			monitor.SentMessage()
-		}
-		return resp, err
-	}
-}
-
-// StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs.
-func (m *ServerMetrics) StreamServerInterceptor() func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
-	return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
-		monitor := newServerReporter(m, streamRPCType(info), info.FullMethod)
-		err := handler(srv, &monitoredServerStream{ss, monitor})
-		st, _ := status.FromError(err)
-		monitor.Handled(st.Code())
-		return err
-	}
-}
-
-// InitializeMetrics initializes all metrics, with their appropriate null
-// value, for all gRPC methods registered on a gRPC server. This is useful, to
-// ensure that all metrics exist when collecting and querying.
-func (m *ServerMetrics) InitializeMetrics(server *grpc.Server) {
-	serviceInfo := server.GetServiceInfo()
-	for serviceName, info := range serviceInfo {
-		for _, mInfo := range info.Methods {
-			preRegisterMethod(m, serviceName, &mInfo)
-		}
-	}
-}
-
-func streamRPCType(info *grpc.StreamServerInfo) grpcType {
-	if info.IsClientStream && !info.IsServerStream {
-		return ClientStream
-	} else if !info.IsClientStream && info.IsServerStream {
-		return ServerStream
-	}
-	return BidiStream
-}
-
-// monitoredStream wraps grpc.ServerStream allowing each Sent/Recv of message to increment counters.
-type monitoredServerStream struct {
-	grpc.ServerStream
-	monitor *serverReporter
-}
-
-func (s *monitoredServerStream) SendMsg(m interface{}) error {
-	err := s.ServerStream.SendMsg(m)
-	if err == nil {
-		s.monitor.SentMessage()
-	}
-	return err
-}
-
-func (s *monitoredServerStream) RecvMsg(m interface{}) error {
-	err := s.ServerStream.RecvMsg(m)
-	if err == nil {
-		s.monitor.ReceivedMessage()
-	}
-	return err
-}
-
-// preRegisterMethod is invoked on Register of a Server, allowing all gRPC services labels to be pre-populated.
-func preRegisterMethod(metrics *ServerMetrics, serviceName string, mInfo *grpc.MethodInfo) {
-	methodName := mInfo.Name
-	methodType := string(typeFromMethodInfo(mInfo))
-	// These are just references (no increments), as just referencing will create the labels but not set values.
-	metrics.serverStartedCounter.GetMetricWithLabelValues(methodType, serviceName, methodName)
-	metrics.serverStreamMsgReceived.GetMetricWithLabelValues(methodType, serviceName, methodName)
-	metrics.serverStreamMsgSent.GetMetricWithLabelValues(methodType, serviceName, methodName)
-	if metrics.serverHandledHistogramEnabled {
-		metrics.serverHandledHistogram.GetMetricWithLabelValues(methodType, serviceName, methodName)
-	}
-	for _, code := range allCodes {
-		metrics.serverHandledCounter.GetMetricWithLabelValues(methodType, serviceName, methodName, code.String())
-	}
-}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go
deleted file mode 100644
index aa9db54..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 Michal Witkowski. All Rights Reserved.
-// See LICENSE for licensing terms.
-
-package grpc_prometheus
-
-import (
-	"time"
-
-	"google.golang.org/grpc/codes"
-)
-
-type serverReporter struct {
-	metrics     *ServerMetrics
-	rpcType     grpcType
-	serviceName string
-	methodName  string
-	startTime   time.Time
-}
-
-func newServerReporter(m *ServerMetrics, rpcType grpcType, fullMethod string) *serverReporter {
-	r := &serverReporter{
-		metrics: m,
-		rpcType: rpcType,
-	}
-	if r.metrics.serverHandledHistogramEnabled {
-		r.startTime = time.Now()
-	}
-	r.serviceName, r.methodName = splitMethodName(fullMethod)
-	r.metrics.serverStartedCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc()
-	return r
-}
-
-func (r *serverReporter) ReceivedMessage() {
-	r.metrics.serverStreamMsgReceived.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc()
-}
-
-func (r *serverReporter) SentMessage() {
-	r.metrics.serverStreamMsgSent.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc()
-}
-
-func (r *serverReporter) Handled(code codes.Code) {
-	r.metrics.serverHandledCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName, code.String()).Inc()
-	if r.metrics.serverHandledHistogramEnabled {
-		r.metrics.serverHandledHistogram.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Observe(time.Since(r.startTime).Seconds())
-	}
-}
diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go
deleted file mode 100644
index 7987de3..0000000
--- a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2016 Michal Witkowski. All Rights Reserved.
-// See LICENSE for licensing terms.
-
-package grpc_prometheus
-
-import (
-	"strings"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-)
-
-type grpcType string
-
-const (
-	Unary        grpcType = "unary"
-	ClientStream grpcType = "client_stream"
-	ServerStream grpcType = "server_stream"
-	BidiStream   grpcType = "bidi_stream"
-)
-
-var (
-	allCodes = []codes.Code{
-		codes.OK, codes.Canceled, codes.Unknown, codes.InvalidArgument, codes.DeadlineExceeded, codes.NotFound,
-		codes.AlreadyExists, codes.PermissionDenied, codes.Unauthenticated, codes.ResourceExhausted,
-		codes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.Unimplemented, codes.Internal,
-		codes.Unavailable, codes.DataLoss,
-	}
-)
-
-func splitMethodName(fullMethodName string) (string, string) {
-	fullMethodName = strings.TrimPrefix(fullMethodName, "/") // remove leading slash
-	if i := strings.Index(fullMethodName, "/"); i >= 0 {
-		return fullMethodName[:i], fullMethodName[i+1:]
-	}
-	return "unknown", "unknown"
-}
-
-func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType {
-	if !mInfo.IsClientStream && !mInfo.IsServerStream {
-		return Unary
-	}
-	if mInfo.IsClientStream && !mInfo.IsServerStream {
-		return ClientStream
-	}
-	if !mInfo.IsClientStream && mInfo.IsServerStream {
-		return ServerStream
-	}
-	return BidiStream
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt b/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt
deleted file mode 100644
index 3645162..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2015, Gengo, Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-
-    * Neither the name of Gengo, Inc. nor the names of its
-      contributors may be used to endorse or promote products derived from this
-      software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel
deleted file mode 100644
index 9fce044..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel
+++ /dev/null
@@ -1,83 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
-    name = "go_default_library",
-    srcs = [
-        "context.go",
-        "convert.go",
-        "doc.go",
-        "errors.go",
-        "handler.go",
-        "marshal_json.go",
-        "marshal_jsonpb.go",
-        "marshal_proto.go",
-        "marshaler.go",
-        "marshaler_registry.go",
-        "mux.go",
-        "pattern.go",
-        "proto2_convert.go",
-        "proto_errors.go",
-        "query.go",
-    ],
-    importpath = "github.com/grpc-ecosystem/grpc-gateway/runtime",
-    deps = [
-        "//runtime/internal:go_default_library",
-        "//utilities:go_default_library",
-        "@com_github_golang_protobuf//jsonpb:go_default_library",
-        "@com_github_golang_protobuf//proto:go_default_library",
-        "@com_github_golang_protobuf//ptypes:go_default_library",
-        "@com_github_golang_protobuf//ptypes/any:go_default_library",
-        "@com_github_golang_protobuf//ptypes/duration:go_default_library",
-        "@com_github_golang_protobuf//ptypes/timestamp:go_default_library",
-        "@org_golang_google_grpc//codes:go_default_library",
-        "@org_golang_google_grpc//grpclog:go_default_library",
-        "@org_golang_google_grpc//metadata:go_default_library",
-        "@org_golang_google_grpc//status:go_default_library",
-    ],
-)
-
-go_test(
-    name = "go_default_test",
-    size = "small",
-    srcs = ["pattern_test.go"],
-    embed = [":go_default_library"],
-    deps = ["//utilities:go_default_library"],
-)
-
-go_test(
-    name = "go_default_xtest",
-    size = "small",
-    srcs = [
-        "context_test.go",
-        "errors_test.go",
-        "handler_test.go",
-        "marshal_json_test.go",
-        "marshal_jsonpb_test.go",
-        "marshal_proto_test.go",
-        "marshaler_registry_test.go",
-        "mux_test.go",
-        "query_test.go",
-    ],
-    deps = [
-        ":go_default_library",
-        "//examples/proto/examplepb:go_default_library",
-        "//runtime/internal:go_default_library",
-        "//utilities:go_default_library",
-        "@com_github_golang_protobuf//jsonpb:go_default_library",
-        "@com_github_golang_protobuf//proto:go_default_library",
-        "@com_github_golang_protobuf//ptypes:go_default_library",
-        "@com_github_golang_protobuf//ptypes/duration:go_default_library",
-        "@com_github_golang_protobuf//ptypes/empty:go_default_library",
-        "@com_github_golang_protobuf//ptypes/struct:go_default_library",
-        "@com_github_golang_protobuf//ptypes/timestamp:go_default_library",
-        "@com_github_golang_protobuf//ptypes/wrappers:go_default_library",
-        "@org_golang_google_genproto//protobuf/field_mask:go_default_library",
-        "@org_golang_google_genproto//googleapis/rpc/errdetails:go_default_library",
-        "@org_golang_google_grpc//:go_default_library",
-        "@org_golang_google_grpc//codes:go_default_library",
-        "@org_golang_google_grpc//metadata:go_default_library",
-        "@org_golang_google_grpc//status:go_default_library",
-    ],
-)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go
deleted file mode 100644
index 896057e..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go
+++ /dev/null
@@ -1,210 +0,0 @@
-package runtime
-
-import (
-	"context"
-	"encoding/base64"
-	"fmt"
-	"net"
-	"net/http"
-	"net/textproto"
-	"strconv"
-	"strings"
-	"time"
-
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/grpclog"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/status"
-)
-
-// MetadataHeaderPrefix is the http prefix that represents custom metadata
-// parameters to or from a gRPC call.
-const MetadataHeaderPrefix = "Grpc-Metadata-"
-
-// MetadataPrefix is prepended to permanent HTTP header keys (as specified
-// by the IANA) when added to the gRPC context.
-const MetadataPrefix = "grpcgateway-"
-
-// MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to
-// HTTP headers in a response handled by grpc-gateway
-const MetadataTrailerPrefix = "Grpc-Trailer-"
-
-const metadataGrpcTimeout = "Grpc-Timeout"
-const metadataHeaderBinarySuffix = "-Bin"
-
-const xForwardedFor = "X-Forwarded-For"
-const xForwardedHost = "X-Forwarded-Host"
-
-var (
-	// DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound
-	// header isn't present. If the value is 0 the sent `context` will not have a timeout.
-	DefaultContextTimeout = 0 * time.Second
-)
-
-func decodeBinHeader(v string) ([]byte, error) {
-	if len(v)%4 == 0 {
-		// Input was padded, or padding was not necessary.
-		return base64.StdEncoding.DecodeString(v)
-	}
-	return base64.RawStdEncoding.DecodeString(v)
-}
-
-/*
-AnnotateContext adds context information such as metadata from the request.
-
-At a minimum, the RemoteAddr is included in the fashion of "X-Forwarded-For",
-except that the forwarded destination is not another HTTP service but rather
-a gRPC service.
-*/
-func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) {
-	var pairs []string
-	timeout := DefaultContextTimeout
-	if tm := req.Header.Get(metadataGrpcTimeout); tm != "" {
-		var err error
-		timeout, err = timeoutDecode(tm)
-		if err != nil {
-			return nil, status.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm)
-		}
-	}
-
-	for key, vals := range req.Header {
-		for _, val := range vals {
-			key = textproto.CanonicalMIMEHeaderKey(key)
-			// For backwards-compatibility, pass through 'authorization' header with no prefix.
-			if key == "Authorization" {
-				pairs = append(pairs, "authorization", val)
-			}
-			if h, ok := mux.incomingHeaderMatcher(key); ok {
-				// Handles "-bin" metadata in grpc, since grpc will do another base64
-				// encode before sending to server, we need to decode it first.
-				if strings.HasSuffix(key, metadataHeaderBinarySuffix) {
-					b, err := decodeBinHeader(val)
-					if err != nil {
-						return nil, status.Errorf(codes.InvalidArgument, "invalid binary header %s: %s", key, err)
-					}
-
-					val = string(b)
-				}
-				pairs = append(pairs, h, val)
-			}
-		}
-	}
-	if host := req.Header.Get(xForwardedHost); host != "" {
-		pairs = append(pairs, strings.ToLower(xForwardedHost), host)
-	} else if req.Host != "" {
-		pairs = append(pairs, strings.ToLower(xForwardedHost), req.Host)
-	}
-
-	if addr := req.RemoteAddr; addr != "" {
-		if remoteIP, _, err := net.SplitHostPort(addr); err == nil {
-			if fwd := req.Header.Get(xForwardedFor); fwd == "" {
-				pairs = append(pairs, strings.ToLower(xForwardedFor), remoteIP)
-			} else {
-				pairs = append(pairs, strings.ToLower(xForwardedFor), fmt.Sprintf("%s, %s", fwd, remoteIP))
-			}
-		} else {
-			grpclog.Infof("invalid remote addr: %s", addr)
-		}
-	}
-
-	if timeout != 0 {
-		ctx, _ = context.WithTimeout(ctx, timeout)
-	}
-	if len(pairs) == 0 {
-		return ctx, nil
-	}
-	md := metadata.Pairs(pairs...)
-	for _, mda := range mux.metadataAnnotators {
-		md = metadata.Join(md, mda(ctx, req))
-	}
-	return metadata.NewOutgoingContext(ctx, md), nil
-}
-
-// ServerMetadata consists of metadata sent from gRPC server.
-type ServerMetadata struct {
-	HeaderMD  metadata.MD
-	TrailerMD metadata.MD
-}
-
-type serverMetadataKey struct{}
-
-// NewServerMetadataContext creates a new context with ServerMetadata
-func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context {
-	return context.WithValue(ctx, serverMetadataKey{}, md)
-}
-
-// ServerMetadataFromContext returns the ServerMetadata in ctx
-func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) {
-	md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata)
-	return
-}
-
-func timeoutDecode(s string) (time.Duration, error) {
-	size := len(s)
-	if size < 2 {
-		return 0, fmt.Errorf("timeout string is too short: %q", s)
-	}
-	d, ok := timeoutUnitToDuration(s[size-1])
-	if !ok {
-		return 0, fmt.Errorf("timeout unit is not recognized: %q", s)
-	}
-	t, err := strconv.ParseInt(s[:size-1], 10, 64)
-	if err != nil {
-		return 0, err
-	}
-	return d * time.Duration(t), nil
-}
-
-func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) {
-	switch u {
-	case 'H':
-		return time.Hour, true
-	case 'M':
-		return time.Minute, true
-	case 'S':
-		return time.Second, true
-	case 'm':
-		return time.Millisecond, true
-	case 'u':
-		return time.Microsecond, true
-	case 'n':
-		return time.Nanosecond, true
-	default:
-	}
-	return
-}
-
-// isPermanentHTTPHeader checks whether hdr belongs to the list of
-// permenant request headers maintained by IANA.
-// http://www.iana.org/assignments/message-headers/message-headers.xml
-func isPermanentHTTPHeader(hdr string) bool {
-	switch hdr {
-	case
-		"Accept",
-		"Accept-Charset",
-		"Accept-Language",
-		"Accept-Ranges",
-		"Authorization",
-		"Cache-Control",
-		"Content-Type",
-		"Cookie",
-		"Date",
-		"Expect",
-		"From",
-		"Host",
-		"If-Match",
-		"If-Modified-Since",
-		"If-None-Match",
-		"If-Schedule-Tag-Match",
-		"If-Unmodified-Since",
-		"Max-Forwards",
-		"Origin",
-		"Pragma",
-		"Referer",
-		"User-Agent",
-		"Via",
-		"Warning":
-		return true
-	}
-	return false
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go
deleted file mode 100644
index bd54ba1..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go
+++ /dev/null
@@ -1,254 +0,0 @@
-package runtime
-
-import (
-	"encoding/base64"
-	"fmt"
-	"strconv"
-	"strings"
-
-	"github.com/golang/protobuf/jsonpb"
-	"github.com/golang/protobuf/ptypes/duration"
-	"github.com/golang/protobuf/ptypes/timestamp"
-)
-
-// String just returns the given string.
-// It is just for compatibility to other types.
-func String(val string) (string, error) {
-	return val, nil
-}
-
-// StringSlice converts 'val' where individual strings are separated by
-// 'sep' into a string slice.
-func StringSlice(val, sep string) ([]string, error) {
-	return strings.Split(val, sep), nil
-}
-
-// Bool converts the given string representation of a boolean value into bool.
-func Bool(val string) (bool, error) {
-	return strconv.ParseBool(val)
-}
-
-// BoolSlice converts 'val' where individual booleans are separated by
-// 'sep' into a bool slice.
-func BoolSlice(val, sep string) ([]bool, error) {
-	s := strings.Split(val, sep)
-	values := make([]bool, len(s))
-	for i, v := range s {
-		value, err := Bool(v)
-		if err != nil {
-			return values, err
-		}
-		values[i] = value
-	}
-	return values, nil
-}
-
-// Float64 converts the given string representation into representation of a floating point number into float64.
-func Float64(val string) (float64, error) {
-	return strconv.ParseFloat(val, 64)
-}
-
-// Float64Slice converts 'val' where individual floating point numbers are separated by
-// 'sep' into a float64 slice.
-func Float64Slice(val, sep string) ([]float64, error) {
-	s := strings.Split(val, sep)
-	values := make([]float64, len(s))
-	for i, v := range s {
-		value, err := Float64(v)
-		if err != nil {
-			return values, err
-		}
-		values[i] = value
-	}
-	return values, nil
-}
-
-// Float32 converts the given string representation of a floating point number into float32.
-func Float32(val string) (float32, error) {
-	f, err := strconv.ParseFloat(val, 32)
-	if err != nil {
-		return 0, err
-	}
-	return float32(f), nil
-}
-
-// Float32Slice converts 'val' where individual floating point numbers are separated by
-// 'sep' into a float32 slice.
-func Float32Slice(val, sep string) ([]float32, error) {
-	s := strings.Split(val, sep)
-	values := make([]float32, len(s))
-	for i, v := range s {
-		value, err := Float32(v)
-		if err != nil {
-			return values, err
-		}
-		values[i] = value
-	}
-	return values, nil
-}
-
-// Int64 converts the given string representation of an integer into int64.
-func Int64(val string) (int64, error) {
-	return strconv.ParseInt(val, 0, 64)
-}
-
-// Int64Slice converts 'val' where individual integers are separated by
-// 'sep' into a int64 slice.
-func Int64Slice(val, sep string) ([]int64, error) {
-	s := strings.Split(val, sep)
-	values := make([]int64, len(s))
-	for i, v := range s {
-		value, err := Int64(v)
-		if err != nil {
-			return values, err
-		}
-		values[i] = value
-	}
-	return values, nil
-}
-
-// Int32 converts the given string representation of an integer into int32.
-func Int32(val string) (int32, error) {
-	i, err := strconv.ParseInt(val, 0, 32)
-	if err != nil {
-		return 0, err
-	}
-	return int32(i), nil
-}
-
-// Int32Slice converts 'val' where individual integers are separated by
-// 'sep' into a int32 slice.
-func Int32Slice(val, sep string) ([]int32, error) {
-	s := strings.Split(val, sep)
-	values := make([]int32, len(s))
-	for i, v := range s {
-		value, err := Int32(v)
-		if err != nil {
-			return values, err
-		}
-		values[i] = value
-	}
-	return values, nil
-}
-
-// Uint64 converts the given string representation of an integer into uint64.
-func Uint64(val string) (uint64, error) {
-	return strconv.ParseUint(val, 0, 64)
-}
-
-// Uint64Slice converts 'val' where individual integers are separated by
-// 'sep' into a uint64 slice.
-func Uint64Slice(val, sep string) ([]uint64, error) {
-	s := strings.Split(val, sep)
-	values := make([]uint64, len(s))
-	for i, v := range s {
-		value, err := Uint64(v)
-		if err != nil {
-			return values, err
-		}
-		values[i] = value
-	}
-	return values, nil
-}
-
-// Uint32 converts the given string representation of an integer into uint32.
-func Uint32(val string) (uint32, error) {
-	i, err := strconv.ParseUint(val, 0, 32)
-	if err != nil {
-		return 0, err
-	}
-	return uint32(i), nil
-}
-
-// Uint32Slice converts 'val' where individual integers are separated by
-// 'sep' into a uint32 slice.
-func Uint32Slice(val, sep string) ([]uint32, error) {
-	s := strings.Split(val, sep)
-	values := make([]uint32, len(s))
-	for i, v := range s {
-		value, err := Uint32(v)
-		if err != nil {
-			return values, err
-		}
-		values[i] = value
-	}
-	return values, nil
-}
-
-// Bytes converts the given string representation of a byte sequence into a slice of bytes
-// A bytes sequence is encoded in URL-safe base64 without padding
-func Bytes(val string) ([]byte, error) {
-	b, err := base64.StdEncoding.DecodeString(val)
-	if err != nil {
-		b, err = base64.URLEncoding.DecodeString(val)
-		if err != nil {
-			return nil, err
-		}
-	}
-	return b, nil
-}
-
-// BytesSlice converts 'val' where individual bytes sequences, encoded in URL-safe
-// base64 without padding, are separated by 'sep' into a slice of bytes slices slice.
-func BytesSlice(val, sep string) ([][]byte, error) {
-	s := strings.Split(val, sep)
-	values := make([][]byte, len(s))
-	for i, v := range s {
-		value, err := Bytes(v)
-		if err != nil {
-			return values, err
-		}
-		values[i] = value
-	}
-	return values, nil
-}
-
-// Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp.
-func Timestamp(val string) (*timestamp.Timestamp, error) {
-	var r *timestamp.Timestamp
-	err := jsonpb.UnmarshalString(val, r)
-	return r, err
-}
-
-// Duration converts the given string into a timestamp.Duration.
-func Duration(val string) (*duration.Duration, error) {
-	var r *duration.Duration
-	err := jsonpb.UnmarshalString(val, r)
-	return r, err
-}
-
-// Enum converts the given string into an int32 that should be type casted into the
-// correct enum proto type.
-func Enum(val string, enumValMap map[string]int32) (int32, error) {
-	e, ok := enumValMap[val]
-	if ok {
-		return e, nil
-	}
-
-	i, err := Int32(val)
-	if err != nil {
-		return 0, fmt.Errorf("%s is not valid", val)
-	}
-	for _, v := range enumValMap {
-		if v == i {
-			return i, nil
-		}
-	}
-	return 0, fmt.Errorf("%s is not valid", val)
-}
-
-// EnumSlice converts 'val' where individual enums are separated by 'sep'
-// into a int32 slice. Each individual int32 should be type casted into the
-// correct enum proto type.
-func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) {
-	s := strings.Split(val, sep)
-	values := make([]int32, len(s))
-	for i, v := range s {
-		value, err := Enum(v, enumValMap)
-		if err != nil {
-			return values, err
-		}
-		values[i] = value
-	}
-	return values, nil
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go
deleted file mode 100644
index b6e5ddf..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
-Package runtime contains runtime helper functions used by
-servers which protoc-gen-grpc-gateway generates.
-*/
-package runtime
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go
deleted file mode 100644
index b39f55e..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go
+++ /dev/null
@@ -1,136 +0,0 @@
-package runtime
-
-import (
-	"context"
-	"io"
-	"net/http"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes/any"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/grpclog"
-	"google.golang.org/grpc/status"
-)
-
-// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status.
-// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
-func HTTPStatusFromCode(code codes.Code) int {
-	switch code {
-	case codes.OK:
-		return http.StatusOK
-	case codes.Canceled:
-		return http.StatusRequestTimeout
-	case codes.Unknown:
-		return http.StatusInternalServerError
-	case codes.InvalidArgument:
-		return http.StatusBadRequest
-	case codes.DeadlineExceeded:
-		return http.StatusGatewayTimeout
-	case codes.NotFound:
-		return http.StatusNotFound
-	case codes.AlreadyExists:
-		return http.StatusConflict
-	case codes.PermissionDenied:
-		return http.StatusForbidden
-	case codes.Unauthenticated:
-		return http.StatusUnauthorized
-	case codes.ResourceExhausted:
-		return http.StatusTooManyRequests
-	case codes.FailedPrecondition:
-		return http.StatusPreconditionFailed
-	case codes.Aborted:
-		return http.StatusConflict
-	case codes.OutOfRange:
-		return http.StatusBadRequest
-	case codes.Unimplemented:
-		return http.StatusNotImplemented
-	case codes.Internal:
-		return http.StatusInternalServerError
-	case codes.Unavailable:
-		return http.StatusServiceUnavailable
-	case codes.DataLoss:
-		return http.StatusInternalServerError
-	}
-
-	grpclog.Infof("Unknown gRPC error code: %v", code)
-	return http.StatusInternalServerError
-}
-
-var (
-	// HTTPError replies to the request with the error.
-	// You can set a custom function to this variable to customize error format.
-	HTTPError = DefaultHTTPError
-	// OtherErrorHandler handles the following error used by the gateway: StatusMethodNotAllowed StatusNotFound and StatusBadRequest
-	OtherErrorHandler = DefaultOtherErrorHandler
-)
-
-type errorBody struct {
-	Error   string     `protobuf:"bytes,1,name=error" json:"error"`
-	// This is to make the error more compatible with users that expect errors to be Status objects:
-	// https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto
-	// It should be the exact same message as the Error field.
-	Message string     `protobuf:"bytes,1,name=message" json:"message"`
-	Code    int32      `protobuf:"varint,2,name=code" json:"code"`
-	Details []*any.Any `protobuf:"bytes,3,rep,name=details" json:"details,omitempty"`
-}
-
-// Make this also conform to proto.Message for builtin JSONPb Marshaler
-func (e *errorBody) Reset()         { *e = errorBody{} }
-func (e *errorBody) String() string { return proto.CompactTextString(e) }
-func (*errorBody) ProtoMessage()    {}
-
-// DefaultHTTPError is the default implementation of HTTPError.
-// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode.
-// If otherwise, it replies with http.StatusInternalServerError.
-//
-// The response body returned by this function is a JSON object,
-// which contains a member whose key is "error" and whose value is err.Error().
-func DefaultHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
-	const fallback = `{"error": "failed to marshal error message"}`
-
-	w.Header().Del("Trailer")
-	w.Header().Set("Content-Type", marshaler.ContentType())
-
-	s, ok := status.FromError(err)
-	if !ok {
-		s = status.New(codes.Unknown, err.Error())
-	}
-
-	body := &errorBody{
-		Error:   s.Message(),
-		Message: s.Message(),
-		Code:    int32(s.Code()),
-		Details: s.Proto().GetDetails(),
-	}
-
-	buf, merr := marshaler.Marshal(body)
-	if merr != nil {
-		grpclog.Infof("Failed to marshal error message %q: %v", body, merr)
-		w.WriteHeader(http.StatusInternalServerError)
-		if _, err := io.WriteString(w, fallback); err != nil {
-			grpclog.Infof("Failed to write response: %v", err)
-		}
-		return
-	}
-
-	md, ok := ServerMetadataFromContext(ctx)
-	if !ok {
-		grpclog.Infof("Failed to extract ServerMetadata from context")
-	}
-
-	handleForwardResponseServerMetadata(w, mux, md)
-	handleForwardResponseTrailerHeader(w, md)
-	st := HTTPStatusFromCode(s.Code())
-	w.WriteHeader(st)
-	if _, err := w.Write(buf); err != nil {
-		grpclog.Infof("Failed to write response: %v", err)
-	}
-
-	handleForwardResponseTrailer(w, md)
-}
-
-// DefaultOtherErrorHandler is the default implementation of OtherErrorHandler.
-// It simply writes a string representation of the given error into "w".
-func DefaultOtherErrorHandler(w http.ResponseWriter, _ *http.Request, msg string, code int) {
-	http.Error(w, msg, code)
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go
deleted file mode 100644
index 8ad9d76..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go
+++ /dev/null
@@ -1,206 +0,0 @@
-package runtime
-
-import (
-	"fmt"
-	"io"
-	"net/http"
-	"net/textproto"
-
-	"context"
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes/any"
-	"github.com/grpc-ecosystem/grpc-gateway/runtime/internal"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/grpclog"
-	"google.golang.org/grpc/status"
-)
-
-// ForwardResponseStream forwards the stream from gRPC server to REST client.
-func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {
-	f, ok := w.(http.Flusher)
-	if !ok {
-		grpclog.Infof("Flush not supported in %T", w)
-		http.Error(w, "unexpected type of web server", http.StatusInternalServerError)
-		return
-	}
-
-	md, ok := ServerMetadataFromContext(ctx)
-	if !ok {
-		grpclog.Infof("Failed to extract ServerMetadata from context")
-		http.Error(w, "unexpected error", http.StatusInternalServerError)
-		return
-	}
-	handleForwardResponseServerMetadata(w, mux, md)
-
-	w.Header().Set("Transfer-Encoding", "chunked")
-	w.Header().Set("Content-Type", marshaler.ContentType())
-	if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil {
-		HTTPError(ctx, mux, marshaler, w, req, err)
-		return
-	}
-
-	var delimiter []byte
-	if d, ok := marshaler.(Delimited); ok {
-		delimiter = d.Delimiter()
-	} else {
-		delimiter = []byte("\n")
-	}
-
-	var wroteHeader bool
-	for {
-		resp, err := recv()
-		if err == io.EOF {
-			return
-		}
-		if err != nil {
-			handleForwardResponseStreamError(wroteHeader, marshaler, w, err)
-			return
-		}
-		if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil {
-			handleForwardResponseStreamError(wroteHeader, marshaler, w, err)
-			return
-		}
-
-		buf, err := marshaler.Marshal(streamChunk(resp, nil))
-		if err != nil {
-			grpclog.Infof("Failed to marshal response chunk: %v", err)
-			handleForwardResponseStreamError(wroteHeader, marshaler, w, err)
-			return
-		}
-		if _, err = w.Write(buf); err != nil {
-			grpclog.Infof("Failed to send response chunk: %v", err)
-			return
-		}
-		wroteHeader = true
-		if _, err = w.Write(delimiter); err != nil {
-			grpclog.Infof("Failed to send delimiter chunk: %v", err)
-			return
-		}
-		f.Flush()
-	}
-}
-
-func handleForwardResponseServerMetadata(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) {
-	for k, vs := range md.HeaderMD {
-		if h, ok := mux.outgoingHeaderMatcher(k); ok {
-			for _, v := range vs {
-				w.Header().Add(h, v)
-			}
-		}
-	}
-}
-
-func handleForwardResponseTrailerHeader(w http.ResponseWriter, md ServerMetadata) {
-	for k := range md.TrailerMD {
-		tKey := textproto.CanonicalMIMEHeaderKey(fmt.Sprintf("%s%s", MetadataTrailerPrefix, k))
-		w.Header().Add("Trailer", tKey)
-	}
-}
-
-func handleForwardResponseTrailer(w http.ResponseWriter, md ServerMetadata) {
-	for k, vs := range md.TrailerMD {
-		tKey := fmt.Sprintf("%s%s", MetadataTrailerPrefix, k)
-		for _, v := range vs {
-			w.Header().Add(tKey, v)
-		}
-	}
-}
-
-// responseBody interface contains method for getting field for marshaling to the response body
-// this method is generated for response struct from the value of `response_body` in the `google.api.HttpRule`
-type responseBody interface {
-	XXX_ResponseBody() interface{}
-}
-
-// ForwardResponseMessage forwards the message "resp" from gRPC server to REST client.
-func ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {
-	md, ok := ServerMetadataFromContext(ctx)
-	if !ok {
-		grpclog.Infof("Failed to extract ServerMetadata from context")
-	}
-
-	handleForwardResponseServerMetadata(w, mux, md)
-	handleForwardResponseTrailerHeader(w, md)
-	w.Header().Set("Content-Type", marshaler.ContentType())
-	if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil {
-		HTTPError(ctx, mux, marshaler, w, req, err)
-		return
-	}
-	var buf []byte
-	var err error
-	if rb, ok := resp.(responseBody); ok {
-		buf, err = marshaler.Marshal(rb.XXX_ResponseBody())
-	} else {
-		buf, err = marshaler.Marshal(resp)
-	}
-	if err != nil {
-		grpclog.Infof("Marshal error: %v", err)
-		HTTPError(ctx, mux, marshaler, w, req, err)
-		return
-	}
-
-	if _, err = w.Write(buf); err != nil {
-		grpclog.Infof("Failed to write response: %v", err)
-	}
-
-	handleForwardResponseTrailer(w, md)
-}
-
-func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error {
-	if len(opts) == 0 {
-		return nil
-	}
-	for _, opt := range opts {
-		if err := opt(ctx, w, resp); err != nil {
-			grpclog.Infof("Error handling ForwardResponseOptions: %v", err)
-			return err
-		}
-	}
-	return nil
-}
-
-func handleForwardResponseStreamError(wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, err error) {
-	buf, merr := marshaler.Marshal(streamChunk(nil, err))
-	if merr != nil {
-		grpclog.Infof("Failed to marshal an error: %v", merr)
-		return
-	}
-	if !wroteHeader {
-		s, ok := status.FromError(err)
-		if !ok {
-			s = status.New(codes.Unknown, err.Error())
-		}
-		w.WriteHeader(HTTPStatusFromCode(s.Code()))
-	}
-	if _, werr := w.Write(buf); werr != nil {
-		grpclog.Infof("Failed to notify error to client: %v", werr)
-		return
-	}
-}
-
-func streamChunk(result proto.Message, err error) map[string]proto.Message {
-	if err != nil {
-		grpcCode := codes.Unknown
-		grpcMessage := err.Error()
-		var grpcDetails []*any.Any
-		if s, ok := status.FromError(err); ok {
-			grpcCode = s.Code()
-			grpcMessage = s.Message()
-			grpcDetails = s.Proto().GetDetails()
-		}
-		httpCode := HTTPStatusFromCode(grpcCode)
-		return map[string]proto.Message{
-			"error": &internal.StreamError{
-				GrpcCode:   int32(grpcCode),
-				HttpCode:   int32(httpCode),
-				Message:    grpcMessage,
-				HttpStatus: http.StatusText(httpCode),
-				Details:    grpcDetails,
-			},
-		}
-	}
-	if result == nil {
-		return streamChunk(nil, fmt.Errorf("empty response"))
-	}
-	return map[string]proto.Message{"result": result}
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/BUILD.bazel
deleted file mode 100644
index 937e660..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/BUILD.bazel
+++ /dev/null
@@ -1,23 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-
-package(default_visibility = ["//runtime:__subpackages__"])
-
-proto_library(
-    name = "internal_proto",
-    srcs = ["stream_chunk.proto"],
-    deps = ["@com_google_protobuf//:any_proto"],
-)
-
-go_proto_library(
-    name = "internal_go_proto",
-    importpath = "github.com/grpc-ecosystem/grpc-gateway/runtime/internal",
-    proto = ":internal_proto",
-    deps = ["@com_github_golang_protobuf//ptypes/any:go_default_library"],
-)
-
-go_library(
-    name = "go_default_library",
-    embed = [":internal_go_proto"],
-    importpath = "github.com/grpc-ecosystem/grpc-gateway/runtime/internal",
-)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.proto b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.proto
deleted file mode 100644
index 55f42ce..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/internal/stream_chunk.proto
+++ /dev/null
@@ -1,15 +0,0 @@
-syntax = "proto3";
-package grpc.gateway.runtime;
-option go_package = "internal";
-
-import "google/protobuf/any.proto";
-
-// StreamError is a response type which is returned when
-// streaming rpc returns an error.
-message StreamError {
-	int32 grpc_code = 1;
-	int32 http_code = 2;
-	string message = 3;
-	string http_status = 4;
-	repeated google.protobuf.Any details = 5;
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go
deleted file mode 100644
index f9d3a58..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package runtime
-
-import (
-	"encoding/json"
-	"io"
-)
-
-// JSONBuiltin is a Marshaler which marshals/unmarshals into/from JSON
-// with the standard "encoding/json" package of Golang.
-// Although it is generally faster for simple proto messages than JSONPb,
-// it does not support advanced features of protobuf, e.g. map, oneof, ....
-//
-// The NewEncoder and NewDecoder types return *json.Encoder and
-// *json.Decoder respectively.
-type JSONBuiltin struct{}
-
-// ContentType always Returns "application/json".
-func (*JSONBuiltin) ContentType() string {
-	return "application/json"
-}
-
-// Marshal marshals "v" into JSON
-func (j *JSONBuiltin) Marshal(v interface{}) ([]byte, error) {
-	return json.Marshal(v)
-}
-
-// Unmarshal unmarshals JSON data into "v".
-func (j *JSONBuiltin) Unmarshal(data []byte, v interface{}) error {
-	return json.Unmarshal(data, v)
-}
-
-// NewDecoder returns a Decoder which reads JSON stream from "r".
-func (j *JSONBuiltin) NewDecoder(r io.Reader) Decoder {
-	return json.NewDecoder(r)
-}
-
-// NewEncoder returns an Encoder which writes JSON stream into "w".
-func (j *JSONBuiltin) NewEncoder(w io.Writer) Encoder {
-	return json.NewEncoder(w)
-}
-
-// Delimiter for newline encoded JSON streams.
-func (j *JSONBuiltin) Delimiter() []byte {
-	return []byte("\n")
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go
deleted file mode 100644
index f56072a..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go
+++ /dev/null
@@ -1,203 +0,0 @@
-package runtime
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"io"
-	"reflect"
-
-	"github.com/golang/protobuf/jsonpb"
-	"github.com/golang/protobuf/proto"
-)
-
-// JSONPb is a Marshaler which marshals/unmarshals into/from JSON
-// with the "github.com/golang/protobuf/jsonpb".
-// It supports fully functionality of protobuf unlike JSONBuiltin.
-//
-// The NewDecoder method returns a DecoderWrapper, so the underlying
-// *json.Decoder methods can be used.
-type JSONPb jsonpb.Marshaler
-
-// ContentType always returns "application/json".
-func (*JSONPb) ContentType() string {
-	return "application/json"
-}
-
-// Marshal marshals "v" into JSON.
-func (j *JSONPb) Marshal(v interface{}) ([]byte, error) {
-	if _, ok := v.(proto.Message); !ok {
-		return j.marshalNonProtoField(v)
-	}
-
-	var buf bytes.Buffer
-	if err := j.marshalTo(&buf, v); err != nil {
-		return nil, err
-	}
-	return buf.Bytes(), nil
-}
-
-func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error {
-	p, ok := v.(proto.Message)
-	if !ok {
-		buf, err := j.marshalNonProtoField(v)
-		if err != nil {
-			return err
-		}
-		_, err = w.Write(buf)
-		return err
-	}
-	return (*jsonpb.Marshaler)(j).Marshal(w, p)
-}
-
-// marshalNonProto marshals a non-message field of a protobuf message.
-// This function does not correctly marshals arbitrary data structure into JSON,
-// but it is only capable of marshaling non-message field values of protobuf,
-// i.e. primitive types, enums; pointers to primitives or enums; maps from
-// integer/string types to primitives/enums/pointers to messages.
-func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
-	if v == nil {
-		return []byte("null"), nil
-	}
-	rv := reflect.ValueOf(v)
-	for rv.Kind() == reflect.Ptr {
-		if rv.IsNil() {
-			return []byte("null"), nil
-		}
-		rv = rv.Elem()
-	}
-
-	if rv.Kind() == reflect.Map {
-		m := make(map[string]*json.RawMessage)
-		for _, k := range rv.MapKeys() {
-			buf, err := j.Marshal(rv.MapIndex(k).Interface())
-			if err != nil {
-				return nil, err
-			}
-			m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf)
-		}
-		if j.Indent != "" {
-			return json.MarshalIndent(m, "", j.Indent)
-		}
-		return json.Marshal(m)
-	}
-	if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts {
-		return json.Marshal(enum.String())
-	}
-	return json.Marshal(rv.Interface())
-}
-
-// Unmarshal unmarshals JSON "data" into "v"
-func (j *JSONPb) Unmarshal(data []byte, v interface{}) error {
-	return unmarshalJSONPb(data, v)
-}
-
-// NewDecoder returns a Decoder which reads JSON stream from "r".
-func (j *JSONPb) NewDecoder(r io.Reader) Decoder {
-	d := json.NewDecoder(r)
-	return DecoderWrapper{Decoder: d}
-}
-
-// DecoderWrapper is a wrapper around a *json.Decoder that adds
-// support for protos to the Decode method.
-type DecoderWrapper struct {
-	*json.Decoder
-}
-
-// Decode wraps the embedded decoder's Decode method to support
-// protos using a jsonpb.Unmarshaler.
-func (d DecoderWrapper) Decode(v interface{}) error {
-	return decodeJSONPb(d.Decoder, v)
-}
-
-// NewEncoder returns an Encoder which writes JSON stream into "w".
-func (j *JSONPb) NewEncoder(w io.Writer) Encoder {
-	return EncoderFunc(func(v interface{}) error { return j.marshalTo(w, v) })
-}
-
-func unmarshalJSONPb(data []byte, v interface{}) error {
-	d := json.NewDecoder(bytes.NewReader(data))
-	return decodeJSONPb(d, v)
-}
-
-func decodeJSONPb(d *json.Decoder, v interface{}) error {
-	p, ok := v.(proto.Message)
-	if !ok {
-		return decodeNonProtoField(d, v)
-	}
-	unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true}
-	return unmarshaler.UnmarshalNext(d, p)
-}
-
-func decodeNonProtoField(d *json.Decoder, v interface{}) error {
-	rv := reflect.ValueOf(v)
-	if rv.Kind() != reflect.Ptr {
-		return fmt.Errorf("%T is not a pointer", v)
-	}
-	for rv.Kind() == reflect.Ptr {
-		if rv.IsNil() {
-			rv.Set(reflect.New(rv.Type().Elem()))
-		}
-		if rv.Type().ConvertibleTo(typeProtoMessage) {
-			unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true}
-			return unmarshaler.UnmarshalNext(d, rv.Interface().(proto.Message))
-		}
-		rv = rv.Elem()
-	}
-	if rv.Kind() == reflect.Map {
-		if rv.IsNil() {
-			rv.Set(reflect.MakeMap(rv.Type()))
-		}
-		conv, ok := convFromType[rv.Type().Key().Kind()]
-		if !ok {
-			return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key())
-		}
-
-		m := make(map[string]*json.RawMessage)
-		if err := d.Decode(&m); err != nil {
-			return err
-		}
-		for k, v := range m {
-			result := conv.Call([]reflect.Value{reflect.ValueOf(k)})
-			if err := result[1].Interface(); err != nil {
-				return err.(error)
-			}
-			bk := result[0]
-			bv := reflect.New(rv.Type().Elem())
-			if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil {
-				return err
-			}
-			rv.SetMapIndex(bk, bv.Elem())
-		}
-		return nil
-	}
-	if _, ok := rv.Interface().(protoEnum); ok {
-		var repr interface{}
-		if err := d.Decode(&repr); err != nil {
-			return err
-		}
-		switch repr.(type) {
-		case string:
-			// TODO(yugui) Should use proto.StructProperties?
-			return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface())
-		case float64:
-			rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type()))
-			return nil
-		default:
-			return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface())
-		}
-	}
-	return d.Decode(v)
-}
-
-type protoEnum interface {
-	fmt.Stringer
-	EnumDescriptor() ([]byte, []int)
-}
-
-var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
-
-// Delimiter for newline encoded JSON streams.
-func (j *JSONPb) Delimiter() []byte {
-	return []byte("\n")
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go
deleted file mode 100644
index f65d1a2..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package runtime
-
-import (
-	"io"
-
-	"errors"
-	"github.com/golang/protobuf/proto"
-	"io/ioutil"
-)
-
-// ProtoMarshaller is a Marshaller which marshals/unmarshals into/from serialize proto bytes
-type ProtoMarshaller struct{}
-
-// ContentType always returns "application/octet-stream".
-func (*ProtoMarshaller) ContentType() string {
-	return "application/octet-stream"
-}
-
-// Marshal marshals "value" into Proto
-func (*ProtoMarshaller) Marshal(value interface{}) ([]byte, error) {
-	message, ok := value.(proto.Message)
-	if !ok {
-		return nil, errors.New("unable to marshal non proto field")
-	}
-	return proto.Marshal(message)
-}
-
-// Unmarshal unmarshals proto "data" into "value"
-func (*ProtoMarshaller) Unmarshal(data []byte, value interface{}) error {
-	message, ok := value.(proto.Message)
-	if !ok {
-		return errors.New("unable to unmarshal non proto field")
-	}
-	return proto.Unmarshal(data, message)
-}
-
-// NewDecoder returns a Decoder which reads proto stream from "reader".
-func (marshaller *ProtoMarshaller) NewDecoder(reader io.Reader) Decoder {
-	return DecoderFunc(func(value interface{}) error {
-		buffer, err := ioutil.ReadAll(reader)
-		if err != nil {
-			return err
-		}
-		return marshaller.Unmarshal(buffer, value)
-	})
-}
-
-// NewEncoder returns an Encoder which writes proto stream into "writer".
-func (marshaller *ProtoMarshaller) NewEncoder(writer io.Writer) Encoder {
-	return EncoderFunc(func(value interface{}) error {
-		buffer, err := marshaller.Marshal(value)
-		if err != nil {
-			return err
-		}
-		_, err = writer.Write(buffer)
-		if err != nil {
-			return err
-		}
-
-		return nil
-	})
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go
deleted file mode 100644
index 98fe6e8..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package runtime
-
-import (
-	"io"
-)
-
-// Marshaler defines a conversion between byte sequence and gRPC payloads / fields.
-type Marshaler interface {
-	// Marshal marshals "v" into byte sequence.
-	Marshal(v interface{}) ([]byte, error)
-	// Unmarshal unmarshals "data" into "v".
-	// "v" must be a pointer value.
-	Unmarshal(data []byte, v interface{}) error
-	// NewDecoder returns a Decoder which reads byte sequence from "r".
-	NewDecoder(r io.Reader) Decoder
-	// NewEncoder returns an Encoder which writes bytes sequence into "w".
-	NewEncoder(w io.Writer) Encoder
-	// ContentType returns the Content-Type which this marshaler is responsible for.
-	ContentType() string
-}
-
-// Decoder decodes a byte sequence
-type Decoder interface {
-	Decode(v interface{}) error
-}
-
-// Encoder encodes gRPC payloads / fields into byte sequence.
-type Encoder interface {
-	Encode(v interface{}) error
-}
-
-// DecoderFunc adapts an decoder function into Decoder.
-type DecoderFunc func(v interface{}) error
-
-// Decode delegates invocations to the underlying function itself.
-func (f DecoderFunc) Decode(v interface{}) error { return f(v) }
-
-// EncoderFunc adapts an encoder function into Encoder
-type EncoderFunc func(v interface{}) error
-
-// Encode delegates invocations to the underlying function itself.
-func (f EncoderFunc) Encode(v interface{}) error { return f(v) }
-
-// Delimited defines the streaming delimiter.
-type Delimited interface {
-	// Delimiter returns the record seperator for the stream.
-	Delimiter() []byte
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go
deleted file mode 100644
index 5cc53ae..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package runtime
-
-import (
-	"errors"
-	"net/http"
-)
-
-// MIMEWildcard is the fallback MIME type used for requests which do not match
-// a registered MIME type.
-const MIMEWildcard = "*"
-
-var (
-	acceptHeader      = http.CanonicalHeaderKey("Accept")
-	contentTypeHeader = http.CanonicalHeaderKey("Content-Type")
-
-	defaultMarshaler = &JSONPb{OrigName: true}
-)
-
-// MarshalerForRequest returns the inbound/outbound marshalers for this request.
-// It checks the registry on the ServeMux for the MIME type set by the Content-Type header.
-// If it isn't set (or the request Content-Type is empty), checks for "*".
-// If there are multiple Content-Type headers set, choose the first one that it can
-// exactly match in the registry.
-// Otherwise, it follows the above logic for "*"/InboundMarshaler/OutboundMarshaler.
-func MarshalerForRequest(mux *ServeMux, r *http.Request) (inbound Marshaler, outbound Marshaler) {
-	for _, acceptVal := range r.Header[acceptHeader] {
-		if m, ok := mux.marshalers.mimeMap[acceptVal]; ok {
-			outbound = m
-			break
-		}
-	}
-
-	for _, contentTypeVal := range r.Header[contentTypeHeader] {
-		if m, ok := mux.marshalers.mimeMap[contentTypeVal]; ok {
-			inbound = m
-			break
-		}
-	}
-
-	if inbound == nil {
-		inbound = mux.marshalers.mimeMap[MIMEWildcard]
-	}
-	if outbound == nil {
-		outbound = inbound
-	}
-
-	return inbound, outbound
-}
-
-// marshalerRegistry is a mapping from MIME types to Marshalers.
-type marshalerRegistry struct {
-	mimeMap map[string]Marshaler
-}
-
-// add adds a marshaler for a case-sensitive MIME type string ("*" to match any
-// MIME type).
-func (m marshalerRegistry) add(mime string, marshaler Marshaler) error {
-	if len(mime) == 0 {
-		return errors.New("empty MIME type")
-	}
-
-	m.mimeMap[mime] = marshaler
-
-	return nil
-}
-
-// makeMarshalerMIMERegistry returns a new registry of marshalers.
-// It allows for a mapping of case-sensitive Content-Type MIME type string to runtime.Marshaler interfaces.
-//
-// For example, you could allow the client to specify the use of the runtime.JSONPb marshaler
-// with a "application/jsonpb" Content-Type and the use of the runtime.JSONBuiltin marshaler
-// with a "application/json" Content-Type.
-// "*" can be used to match any Content-Type.
-// This can be attached to a ServerMux with the marshaler option.
-func makeMarshalerMIMERegistry() marshalerRegistry {
-	return marshalerRegistry{
-		mimeMap: map[string]Marshaler{
-			MIMEWildcard: defaultMarshaler,
-		},
-	}
-}
-
-// WithMarshalerOption returns a ServeMuxOption which associates inbound and outbound
-// Marshalers to a MIME type in mux.
-func WithMarshalerOption(mime string, marshaler Marshaler) ServeMuxOption {
-	return func(mux *ServeMux) {
-		if err := mux.marshalers.add(mime, marshaler); err != nil {
-			panic(err)
-		}
-	}
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go
deleted file mode 100644
index 463084a..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go
+++ /dev/null
@@ -1,258 +0,0 @@
-package runtime
-
-import (
-	"context"
-	"fmt"
-	"net/http"
-	"strings"
-
-	"github.com/golang/protobuf/proto"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/status"
-)
-
-// A HandlerFunc handles a specific pair of path pattern and HTTP method.
-type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string)
-
-// ServeMux is a request multiplexer for grpc-gateway.
-// It matches http requests to patterns and invokes the corresponding handler.
-type ServeMux struct {
-	// handlers maps HTTP method to a list of handlers.
-	handlers               map[string][]handler
-	forwardResponseOptions []func(context.Context, http.ResponseWriter, proto.Message) error
-	marshalers             marshalerRegistry
-	incomingHeaderMatcher  HeaderMatcherFunc
-	outgoingHeaderMatcher  HeaderMatcherFunc
-	metadataAnnotators     []func(context.Context, *http.Request) metadata.MD
-	protoErrorHandler      ProtoErrorHandlerFunc
-}
-
-// ServeMuxOption is an option that can be given to a ServeMux on construction.
-type ServeMuxOption func(*ServeMux)
-
-// WithForwardResponseOption returns a ServeMuxOption representing the forwardResponseOption.
-//
-// forwardResponseOption is an option that will be called on the relevant context.Context,
-// http.ResponseWriter, and proto.Message before every forwarded response.
-//
-// The message may be nil in the case where just a header is being sent.
-func WithForwardResponseOption(forwardResponseOption func(context.Context, http.ResponseWriter, proto.Message) error) ServeMuxOption {
-	return func(serveMux *ServeMux) {
-		serveMux.forwardResponseOptions = append(serveMux.forwardResponseOptions, forwardResponseOption)
-	}
-}
-
-// HeaderMatcherFunc checks whether a header key should be forwarded to/from gRPC context.
-type HeaderMatcherFunc func(string) (string, bool)
-
-// DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header
-// keys (as specified by the IANA) to gRPC context with grpcgateway- prefix. HTTP headers that start with
-// 'Grpc-Metadata-' are mapped to gRPC metadata after removing prefix 'Grpc-Metadata-'.
-func DefaultHeaderMatcher(key string) (string, bool) {
-	if isPermanentHTTPHeader(key) {
-		return MetadataPrefix + key, true
-	} else if strings.HasPrefix(key, MetadataHeaderPrefix) {
-		return key[len(MetadataHeaderPrefix):], true
-	}
-	return "", false
-}
-
-// WithIncomingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for incoming request to gateway.
-//
-// This matcher will be called with each header in http.Request. If matcher returns true, that header will be
-// passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header.
-func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption {
-	return func(mux *ServeMux) {
-		mux.incomingHeaderMatcher = fn
-	}
-}
-
-// WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway.
-//
-// This matcher will be called with each header in response header metadata. If matcher returns true, that header will be
-// passed to http response returned from gateway. To transform the header before passing to response,
-// matcher should return modified header.
-func WithOutgoingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption {
-	return func(mux *ServeMux) {
-		mux.outgoingHeaderMatcher = fn
-	}
-}
-
-// WithMetadata returns a ServeMuxOption for passing metadata to a gRPC context.
-//
-// This can be used by services that need to read from http.Request and modify gRPC context. A common use case
-// is reading token from cookie and adding it in gRPC context.
-func WithMetadata(annotator func(context.Context, *http.Request) metadata.MD) ServeMuxOption {
-	return func(serveMux *ServeMux) {
-		serveMux.metadataAnnotators = append(serveMux.metadataAnnotators, annotator)
-	}
-}
-
-// WithProtoErrorHandler returns a ServeMuxOption for passing metadata to a gRPC context.
-//
-// This can be used to handle an error as general proto message defined by gRPC.
-// The response including body and status is not backward compatible with the default error handler.
-// When this option is used, HTTPError and OtherErrorHandler are overwritten on initialization.
-func WithProtoErrorHandler(fn ProtoErrorHandlerFunc) ServeMuxOption {
-	return func(serveMux *ServeMux) {
-		serveMux.protoErrorHandler = fn
-	}
-}
-
-// NewServeMux returns a new ServeMux whose internal mapping is empty.
-func NewServeMux(opts ...ServeMuxOption) *ServeMux {
-	serveMux := &ServeMux{
-		handlers:               make(map[string][]handler),
-		forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0),
-		marshalers:             makeMarshalerMIMERegistry(),
-	}
-
-	for _, opt := range opts {
-		opt(serveMux)
-	}
-
-	if serveMux.protoErrorHandler != nil {
-		HTTPError = serveMux.protoErrorHandler
-		// OtherErrorHandler is no longer used when protoErrorHandler is set.
-		// Overwritten by a special error handler to return Unknown.
-		OtherErrorHandler = func(w http.ResponseWriter, r *http.Request, _ string, _ int) {
-			ctx := context.Background()
-			_, outboundMarshaler := MarshalerForRequest(serveMux, r)
-			sterr := status.Error(codes.Unknown, "unexpected use of OtherErrorHandler")
-			serveMux.protoErrorHandler(ctx, serveMux, outboundMarshaler, w, r, sterr)
-		}
-	}
-
-	if serveMux.incomingHeaderMatcher == nil {
-		serveMux.incomingHeaderMatcher = DefaultHeaderMatcher
-	}
-
-	if serveMux.outgoingHeaderMatcher == nil {
-		serveMux.outgoingHeaderMatcher = func(key string) (string, bool) {
-			return fmt.Sprintf("%s%s", MetadataHeaderPrefix, key), true
-		}
-	}
-
-	return serveMux
-}
-
-// Handle associates "h" to the pair of HTTP method and path pattern.
-func (s *ServeMux) Handle(meth string, pat Pattern, h HandlerFunc) {
-	s.handlers[meth] = append(s.handlers[meth], handler{pat: pat, h: h})
-}
-
-// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path.
-func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	ctx := r.Context()
-
-	path := r.URL.Path
-	if !strings.HasPrefix(path, "/") {
-		if s.protoErrorHandler != nil {
-			_, outboundMarshaler := MarshalerForRequest(s, r)
-			sterr := status.Error(codes.InvalidArgument, http.StatusText(http.StatusBadRequest))
-			s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
-		} else {
-			OtherErrorHandler(w, r, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
-		}
-		return
-	}
-
-	components := strings.Split(path[1:], "/")
-	l := len(components)
-	var verb string
-	if idx := strings.LastIndex(components[l-1], ":"); idx == 0 {
-		if s.protoErrorHandler != nil {
-			_, outboundMarshaler := MarshalerForRequest(s, r)
-			sterr := status.Error(codes.Unimplemented, http.StatusText(http.StatusNotImplemented))
-			s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
-		} else {
-			OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound)
-		}
-		return
-	} else if idx > 0 {
-		c := components[l-1]
-		components[l-1], verb = c[:idx], c[idx+1:]
-	}
-
-	if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && isPathLengthFallback(r) {
-		r.Method = strings.ToUpper(override)
-		if err := r.ParseForm(); err != nil {
-			if s.protoErrorHandler != nil {
-				_, outboundMarshaler := MarshalerForRequest(s, r)
-				sterr := status.Error(codes.InvalidArgument, err.Error())
-				s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
-			} else {
-				OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest)
-			}
-			return
-		}
-	}
-	for _, h := range s.handlers[r.Method] {
-		pathParams, err := h.pat.Match(components, verb)
-		if err != nil {
-			continue
-		}
-		h.h(w, r, pathParams)
-		return
-	}
-
-	// lookup other methods to handle fallback from GET to POST and
-	// to determine if it is MethodNotAllowed or NotFound.
-	for m, handlers := range s.handlers {
-		if m == r.Method {
-			continue
-		}
-		for _, h := range handlers {
-			pathParams, err := h.pat.Match(components, verb)
-			if err != nil {
-				continue
-			}
-			// X-HTTP-Method-Override is optional. Always allow fallback to POST.
-			if isPathLengthFallback(r) {
-				if err := r.ParseForm(); err != nil {
-					if s.protoErrorHandler != nil {
-						_, outboundMarshaler := MarshalerForRequest(s, r)
-						sterr := status.Error(codes.InvalidArgument, err.Error())
-						s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
-					} else {
-						OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest)
-					}
-					return
-				}
-				h.h(w, r, pathParams)
-				return
-			}
-			if s.protoErrorHandler != nil {
-				_, outboundMarshaler := MarshalerForRequest(s, r)
-				sterr := status.Error(codes.Unimplemented, http.StatusText(http.StatusMethodNotAllowed))
-				s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
-			} else {
-				OtherErrorHandler(w, r, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
-			}
-			return
-		}
-	}
-
-	if s.protoErrorHandler != nil {
-		_, outboundMarshaler := MarshalerForRequest(s, r)
-		sterr := status.Error(codes.Unimplemented, http.StatusText(http.StatusNotImplemented))
-		s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
-	} else {
-		OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound)
-	}
-}
-
-// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux.
-func (s *ServeMux) GetForwardResponseOptions() []func(context.Context, http.ResponseWriter, proto.Message) error {
-	return s.forwardResponseOptions
-}
-
-func isPathLengthFallback(r *http.Request) bool {
-	return r.Method == "POST" && r.Header.Get("Content-Type") == "application/x-www-form-urlencoded"
-}
-
-type handler struct {
-	pat Pattern
-	h   HandlerFunc
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go
deleted file mode 100644
index f16a84a..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go
+++ /dev/null
@@ -1,227 +0,0 @@
-package runtime
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-
-	"github.com/grpc-ecosystem/grpc-gateway/utilities"
-	"google.golang.org/grpc/grpclog"
-)
-
-var (
-	// ErrNotMatch indicates that the given HTTP request path does not match to the pattern.
-	ErrNotMatch = errors.New("not match to the path pattern")
-	// ErrInvalidPattern indicates that the given definition of Pattern is not valid.
-	ErrInvalidPattern = errors.New("invalid pattern")
-)
-
-type op struct {
-	code    utilities.OpCode
-	operand int
-}
-
-// Pattern is a template pattern of http request paths defined in github.com/googleapis/googleapis/google/api/http.proto.
-type Pattern struct {
-	// ops is a list of operations
-	ops []op
-	// pool is a constant pool indexed by the operands or vars.
-	pool []string
-	// vars is a list of variables names to be bound by this pattern
-	vars []string
-	// stacksize is the max depth of the stack
-	stacksize int
-	// tailLen is the length of the fixed-size segments after a deep wildcard
-	tailLen int
-	// verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part.
-	verb string
-}
-
-// NewPattern returns a new Pattern from the given definition values.
-// "ops" is a sequence of op codes. "pool" is a constant pool.
-// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part.
-// "version" must be 1 for now.
-// It returns an error if the given definition is invalid.
-func NewPattern(version int, ops []int, pool []string, verb string) (Pattern, error) {
-	if version != 1 {
-		grpclog.Infof("unsupported version: %d", version)
-		return Pattern{}, ErrInvalidPattern
-	}
-
-	l := len(ops)
-	if l%2 != 0 {
-		grpclog.Infof("odd number of ops codes: %d", l)
-		return Pattern{}, ErrInvalidPattern
-	}
-
-	var (
-		typedOps        []op
-		stack, maxstack int
-		tailLen         int
-		pushMSeen       bool
-		vars            []string
-	)
-	for i := 0; i < l; i += 2 {
-		op := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]}
-		switch op.code {
-		case utilities.OpNop:
-			continue
-		case utilities.OpPush:
-			if pushMSeen {
-				tailLen++
-			}
-			stack++
-		case utilities.OpPushM:
-			if pushMSeen {
-				grpclog.Infof("pushM appears twice")
-				return Pattern{}, ErrInvalidPattern
-			}
-			pushMSeen = true
-			stack++
-		case utilities.OpLitPush:
-			if op.operand < 0 || len(pool) <= op.operand {
-				grpclog.Infof("negative literal index: %d", op.operand)
-				return Pattern{}, ErrInvalidPattern
-			}
-			if pushMSeen {
-				tailLen++
-			}
-			stack++
-		case utilities.OpConcatN:
-			if op.operand <= 0 {
-				grpclog.Infof("negative concat size: %d", op.operand)
-				return Pattern{}, ErrInvalidPattern
-			}
-			stack -= op.operand
-			if stack < 0 {
-				grpclog.Print("stack underflow")
-				return Pattern{}, ErrInvalidPattern
-			}
-			stack++
-		case utilities.OpCapture:
-			if op.operand < 0 || len(pool) <= op.operand {
-				grpclog.Infof("variable name index out of bound: %d", op.operand)
-				return Pattern{}, ErrInvalidPattern
-			}
-			v := pool[op.operand]
-			op.operand = len(vars)
-			vars = append(vars, v)
-			stack--
-			if stack < 0 {
-				grpclog.Infof("stack underflow")
-				return Pattern{}, ErrInvalidPattern
-			}
-		default:
-			grpclog.Infof("invalid opcode: %d", op.code)
-			return Pattern{}, ErrInvalidPattern
-		}
-
-		if maxstack < stack {
-			maxstack = stack
-		}
-		typedOps = append(typedOps, op)
-	}
-	return Pattern{
-		ops:       typedOps,
-		pool:      pool,
-		vars:      vars,
-		stacksize: maxstack,
-		tailLen:   tailLen,
-		verb:      verb,
-	}, nil
-}
-
-// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization.
-func MustPattern(p Pattern, err error) Pattern {
-	if err != nil {
-		grpclog.Fatalf("Pattern initialization failed: %v", err)
-	}
-	return p
-}
-
-// Match examines components if it matches to the Pattern.
-// If it matches, the function returns a mapping from field paths to their captured values.
-// If otherwise, the function returns an error.
-func (p Pattern) Match(components []string, verb string) (map[string]string, error) {
-	if p.verb != verb {
-		return nil, ErrNotMatch
-	}
-
-	var pos int
-	stack := make([]string, 0, p.stacksize)
-	captured := make([]string, len(p.vars))
-	l := len(components)
-	for _, op := range p.ops {
-		switch op.code {
-		case utilities.OpNop:
-			continue
-		case utilities.OpPush, utilities.OpLitPush:
-			if pos >= l {
-				return nil, ErrNotMatch
-			}
-			c := components[pos]
-			if op.code == utilities.OpLitPush {
-				if lit := p.pool[op.operand]; c != lit {
-					return nil, ErrNotMatch
-				}
-			}
-			stack = append(stack, c)
-			pos++
-		case utilities.OpPushM:
-			end := len(components)
-			if end < pos+p.tailLen {
-				return nil, ErrNotMatch
-			}
-			end -= p.tailLen
-			stack = append(stack, strings.Join(components[pos:end], "/"))
-			pos = end
-		case utilities.OpConcatN:
-			n := op.operand
-			l := len(stack) - n
-			stack = append(stack[:l], strings.Join(stack[l:], "/"))
-		case utilities.OpCapture:
-			n := len(stack) - 1
-			captured[op.operand] = stack[n]
-			stack = stack[:n]
-		}
-	}
-	if pos < l {
-		return nil, ErrNotMatch
-	}
-	bindings := make(map[string]string)
-	for i, val := range captured {
-		bindings[p.vars[i]] = val
-	}
-	return bindings, nil
-}
-
-// Verb returns the verb part of the Pattern.
-func (p Pattern) Verb() string { return p.verb }
-
-func (p Pattern) String() string {
-	var stack []string
-	for _, op := range p.ops {
-		switch op.code {
-		case utilities.OpNop:
-			continue
-		case utilities.OpPush:
-			stack = append(stack, "*")
-		case utilities.OpLitPush:
-			stack = append(stack, p.pool[op.operand])
-		case utilities.OpPushM:
-			stack = append(stack, "**")
-		case utilities.OpConcatN:
-			n := op.operand
-			l := len(stack) - n
-			stack = append(stack[:l], strings.Join(stack[l:], "/"))
-		case utilities.OpCapture:
-			n := len(stack) - 1
-			stack[n] = fmt.Sprintf("{%s=%s}", p.vars[op.operand], stack[n])
-		}
-	}
-	segs := strings.Join(stack, "/")
-	if p.verb != "" {
-		return fmt.Sprintf("/%s:%s", segs, p.verb)
-	}
-	return "/" + segs
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go
deleted file mode 100644
index a3151e2..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package runtime
-
-import (
-	"github.com/golang/protobuf/proto"
-)
-
-// StringP returns a pointer to a string whose pointee is same as the given string value.
-func StringP(val string) (*string, error) {
-	return proto.String(val), nil
-}
-
-// BoolP parses the given string representation of a boolean value,
-// and returns a pointer to a bool whose value is same as the parsed value.
-func BoolP(val string) (*bool, error) {
-	b, err := Bool(val)
-	if err != nil {
-		return nil, err
-	}
-	return proto.Bool(b), nil
-}
-
-// Float64P parses the given string representation of a floating point number,
-// and returns a pointer to a float64 whose value is same as the parsed number.
-func Float64P(val string) (*float64, error) {
-	f, err := Float64(val)
-	if err != nil {
-		return nil, err
-	}
-	return proto.Float64(f), nil
-}
-
-// Float32P parses the given string representation of a floating point number,
-// and returns a pointer to a float32 whose value is same as the parsed number.
-func Float32P(val string) (*float32, error) {
-	f, err := Float32(val)
-	if err != nil {
-		return nil, err
-	}
-	return proto.Float32(f), nil
-}
-
-// Int64P parses the given string representation of an integer
-// and returns a pointer to a int64 whose value is same as the parsed integer.
-func Int64P(val string) (*int64, error) {
-	i, err := Int64(val)
-	if err != nil {
-		return nil, err
-	}
-	return proto.Int64(i), nil
-}
-
-// Int32P parses the given string representation of an integer
-// and returns a pointer to a int32 whose value is same as the parsed integer.
-func Int32P(val string) (*int32, error) {
-	i, err := Int32(val)
-	if err != nil {
-		return nil, err
-	}
-	return proto.Int32(i), err
-}
-
-// Uint64P parses the given string representation of an integer
-// and returns a pointer to a uint64 whose value is same as the parsed integer.
-func Uint64P(val string) (*uint64, error) {
-	i, err := Uint64(val)
-	if err != nil {
-		return nil, err
-	}
-	return proto.Uint64(i), err
-}
-
-// Uint32P parses the given string representation of an integer
-// and returns a pointer to a uint32 whose value is same as the parsed integer.
-func Uint32P(val string) (*uint32, error) {
-	i, err := Uint32(val)
-	if err != nil {
-		return nil, err
-	}
-	return proto.Uint32(i), err
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go
deleted file mode 100644
index 43fafca..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package runtime
-
-import (
-	"io"
-	"net/http"
-
-	"context"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/grpclog"
-	"google.golang.org/grpc/status"
-)
-
-// ProtoErrorHandlerFunc handles the error as a gRPC error generated via status package and replies to the request.
-type ProtoErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error)
-
-var _ ProtoErrorHandlerFunc = DefaultHTTPProtoErrorHandler
-
-// DefaultHTTPProtoErrorHandler is an implementation of HTTPError.
-// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode.
-// If otherwise, it replies with http.StatusInternalServerError.
-//
-// The response body returned by this function is a Status message marshaled by a Marshaler.
-//
-// Do not set this function to HTTPError variable directly, use WithProtoErrorHandler option instead.
-func DefaultHTTPProtoErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
-	// return Internal when Marshal failed
-	const fallback = `{"code": 13, "message": "failed to marshal error message"}`
-
-	w.Header().Del("Trailer")
-	w.Header().Set("Content-Type", marshaler.ContentType())
-
-	s, ok := status.FromError(err)
-	if !ok {
-		s = status.New(codes.Unknown, err.Error())
-	}
-
-	buf, merr := marshaler.Marshal(s.Proto())
-	if merr != nil {
-		grpclog.Infof("Failed to marshal error message %q: %v", s.Proto(), merr)
-		w.WriteHeader(http.StatusInternalServerError)
-		if _, err := io.WriteString(w, fallback); err != nil {
-			grpclog.Infof("Failed to write response: %v", err)
-		}
-		return
-	}
-
-	md, ok := ServerMetadataFromContext(ctx)
-	if !ok {
-		grpclog.Infof("Failed to extract ServerMetadata from context")
-	}
-
-	handleForwardResponseServerMetadata(w, mux, md)
-	handleForwardResponseTrailerHeader(w, md)
-	st := HTTPStatusFromCode(s.Code())
-	w.WriteHeader(st)
-	if _, err := w.Write(buf); err != nil {
-		grpclog.Infof("Failed to write response: %v", err)
-	}
-
-	handleForwardResponseTrailer(w, md)
-}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go
deleted file mode 100644
index bb9359f..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go
+++ /dev/null
@@ -1,392 +0,0 @@
-package runtime
-
-import (
-	"encoding/base64"
-	"fmt"
-	"net/url"
-	"reflect"
-	"regexp"
-	"strconv"
-	"strings"
-	"time"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/grpc-ecosystem/grpc-gateway/utilities"
-	"google.golang.org/grpc/grpclog"
-)
-
-// PopulateQueryParameters populates "values" into "msg".
-// A value is ignored if its key starts with one of the elements in "filter".
-func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error {
-	for key, values := range values {
-		re, err := regexp.Compile("^(.*)\\[(.*)\\]$")
-		if err != nil {
-			return err
-		}
-		match := re.FindStringSubmatch(key)
-		if len(match) == 3 {
-			key = match[1]
-			values = append([]string{match[2]}, values...)
-		}
-		fieldPath := strings.Split(key, ".")
-		if filter.HasCommonPrefix(fieldPath) {
-			continue
-		}
-		if err := populateFieldValueFromPath(msg, fieldPath, values); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-// PopulateFieldFromPath sets a value in a nested Protobuf structure.
-// It instantiates missing protobuf fields as it goes.
-func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error {
-	fieldPath := strings.Split(fieldPathString, ".")
-	return populateFieldValueFromPath(msg, fieldPath, []string{value})
-}
-
-func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values []string) error {
-	m := reflect.ValueOf(msg)
-	if m.Kind() != reflect.Ptr {
-		return fmt.Errorf("unexpected type %T: %v", msg, msg)
-	}
-	var props *proto.Properties
-	m = m.Elem()
-	for i, fieldName := range fieldPath {
-		isLast := i == len(fieldPath)-1
-		if !isLast && m.Kind() != reflect.Struct {
-			return fmt.Errorf("non-aggregate type in the mid of path: %s", strings.Join(fieldPath, "."))
-		}
-		var f reflect.Value
-		var err error
-		f, props, err = fieldByProtoName(m, fieldName)
-		if err != nil {
-			return err
-		} else if !f.IsValid() {
-			grpclog.Infof("field not found in %T: %s", msg, strings.Join(fieldPath, "."))
-			return nil
-		}
-
-		switch f.Kind() {
-		case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64:
-			if !isLast {
-				return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], "."))
-			}
-			m = f
-		case reflect.Slice:
-			if !isLast {
-				return fmt.Errorf("unexpected repeated field in %s", strings.Join(fieldPath, "."))
-			}
-			// Handle []byte
-			if f.Type().Elem().Kind() == reflect.Uint8 {
-				m = f
-				break
-			}
-			return populateRepeatedField(f, values, props)
-		case reflect.Ptr:
-			if f.IsNil() {
-				m = reflect.New(f.Type().Elem())
-				f.Set(m.Convert(f.Type()))
-			}
-			m = f.Elem()
-			continue
-		case reflect.Struct:
-			m = f
-			continue
-		case reflect.Map:
-			if !isLast {
-				return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], "."))
-			}
-			return populateMapField(f, values, props)
-		default:
-			return fmt.Errorf("unexpected type %s in %T", f.Type(), msg)
-		}
-	}
-	switch len(values) {
-	case 0:
-		return fmt.Errorf("no value of field: %s", strings.Join(fieldPath, "."))
-	case 1:
-	default:
-		grpclog.Infof("too many field values: %s", strings.Join(fieldPath, "."))
-	}
-	return populateField(m, values[0], props)
-}
-
-// fieldByProtoName looks up a field whose corresponding protobuf field name is "name".
-// "m" must be a struct value. It returns zero reflect.Value if no such field found.
-func fieldByProtoName(m reflect.Value, name string) (reflect.Value, *proto.Properties, error) {
-	props := proto.GetProperties(m.Type())
-
-	// look up field name in oneof map
-	if op, ok := props.OneofTypes[name]; ok {
-		v := reflect.New(op.Type.Elem())
-		field := m.Field(op.Field)
-		if !field.IsNil() {
-			return reflect.Value{}, nil, fmt.Errorf("field already set for %s oneof", props.Prop[op.Field].OrigName)
-		}
-		field.Set(v)
-		return v.Elem().Field(0), op.Prop, nil
-	}
-
-	for _, p := range props.Prop {
-		if p.OrigName == name {
-			return m.FieldByName(p.Name), p, nil
-		}
-		if p.JSONName == name {
-			return m.FieldByName(p.Name), p, nil
-		}
-	}
-	return reflect.Value{}, nil, nil
-}
-
-func populateMapField(f reflect.Value, values []string, props *proto.Properties) error {
-	if len(values) != 2 {
-		return fmt.Errorf("more than one value provided for key %s in map %s", values[0], props.Name)
-	}
-
-	key, value := values[0], values[1]
-	keyType := f.Type().Key()
-	valueType := f.Type().Elem()
-	if f.IsNil() {
-		f.Set(reflect.MakeMap(f.Type()))
-	}
-
-	keyConv, ok := convFromType[keyType.Kind()]
-	if !ok {
-		return fmt.Errorf("unsupported key type %s in map %s", keyType, props.Name)
-	}
-	valueConv, ok := convFromType[valueType.Kind()]
-	if !ok {
-		return fmt.Errorf("unsupported value type %s in map %s", valueType, props.Name)
-	}
-
-	keyV := keyConv.Call([]reflect.Value{reflect.ValueOf(key)})
-	if err := keyV[1].Interface(); err != nil {
-		return err.(error)
-	}
-	valueV := valueConv.Call([]reflect.Value{reflect.ValueOf(value)})
-	if err := valueV[1].Interface(); err != nil {
-		return err.(error)
-	}
-
-	f.SetMapIndex(keyV[0].Convert(keyType), valueV[0].Convert(valueType))
-
-	return nil
-}
-
-func populateRepeatedField(f reflect.Value, values []string, props *proto.Properties) error {
-	elemType := f.Type().Elem()
-
-	// is the destination field a slice of an enumeration type?
-	if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil {
-		return populateFieldEnumRepeated(f, values, enumValMap)
-	}
-
-	conv, ok := convFromType[elemType.Kind()]
-	if !ok {
-		return fmt.Errorf("unsupported field type %s", elemType)
-	}
-	f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type()))
-	for i, v := range values {
-		result := conv.Call([]reflect.Value{reflect.ValueOf(v)})
-		if err := result[1].Interface(); err != nil {
-			return err.(error)
-		}
-		f.Index(i).Set(result[0].Convert(f.Index(i).Type()))
-	}
-	return nil
-}
-
-func populateField(f reflect.Value, value string, props *proto.Properties) error {
-	i := f.Addr().Interface()
-
-	// Handle protobuf well known types
-	type wkt interface {
-		XXX_WellKnownType() string
-	}
-	if wkt, ok := i.(wkt); ok {
-		switch wkt.XXX_WellKnownType() {
-		case "Timestamp":
-			if value == "null" {
-				f.Field(0).SetInt(0)
-				f.Field(1).SetInt(0)
-				return nil
-			}
-
-			t, err := time.Parse(time.RFC3339Nano, value)
-			if err != nil {
-				return fmt.Errorf("bad Timestamp: %v", err)
-			}
-			f.Field(0).SetInt(int64(t.Unix()))
-			f.Field(1).SetInt(int64(t.Nanosecond()))
-			return nil
-		case "Duration":
-			if value == "null" {
-				f.Field(0).SetInt(0)
-				f.Field(1).SetInt(0)
-				return nil
-			}
-			d, err := time.ParseDuration(value)
-			if err != nil {
-				return fmt.Errorf("bad Duration: %v", err)
-			}
-
-			ns := d.Nanoseconds()
-			s := ns / 1e9
-			ns %= 1e9
-			f.Field(0).SetInt(s)
-			f.Field(1).SetInt(ns)
-			return nil
-		case "DoubleValue":
-			fallthrough
-		case "FloatValue":
-			float64Val, err := strconv.ParseFloat(value, 64)
-			if err != nil {
-				return fmt.Errorf("bad DoubleValue: %s", value)
-			}
-			f.Field(0).SetFloat(float64Val)
-			return nil
-		case "Int64Value":
-			fallthrough
-		case "Int32Value":
-			int64Val, err := strconv.ParseInt(value, 10, 64)
-			if err != nil {
-				return fmt.Errorf("bad DoubleValue: %s", value)
-			}
-			f.Field(0).SetInt(int64Val)
-			return nil
-		case "UInt64Value":
-			fallthrough
-		case "UInt32Value":
-			uint64Val, err := strconv.ParseUint(value, 10, 64)
-			if err != nil {
-				return fmt.Errorf("bad DoubleValue: %s", value)
-			}
-			f.Field(0).SetUint(uint64Val)
-			return nil
-		case "BoolValue":
-			if value == "true" {
-				f.Field(0).SetBool(true)
-			} else if value == "false" {
-				f.Field(0).SetBool(false)
-			} else {
-				return fmt.Errorf("bad BoolValue: %s", value)
-			}
-			return nil
-		case "StringValue":
-			f.Field(0).SetString(value)
-			return nil
-		case "BytesValue":
-			bytesVal, err := base64.StdEncoding.DecodeString(value)
-			if err != nil {
-				return fmt.Errorf("bad BytesValue: %s", value)
-			}
-			f.Field(0).SetBytes(bytesVal)
-			return nil
-		}
-	}
-
-	// Handle google well known types
-	if gwkt, ok := i.(proto.Message); ok {
-		switch proto.MessageName(gwkt) {
-		case "google.protobuf.FieldMask":
-			p := f.Field(0)
-			for _, v := range strings.Split(value, ",") {
-				if v != "" {
-					p.Set(reflect.Append(p, reflect.ValueOf(v)))
-				}
-			}
-			return nil
-		}
-	}
-
-	// Handle Time and Duration stdlib types
-	switch t := i.(type) {
-	case *time.Time:
-		pt, err := time.Parse(time.RFC3339Nano, value)
-		if err != nil {
-			return fmt.Errorf("bad Timestamp: %v", err)
-		}
-		*t = pt
-		return nil
-	case *time.Duration:
-		d, err := time.ParseDuration(value)
-		if err != nil {
-			return fmt.Errorf("bad Duration: %v", err)
-		}
-		*t = d
-		return nil
-	}
-
-	// is the destination field an enumeration type?
-	if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil {
-		return populateFieldEnum(f, value, enumValMap)
-	}
-
-	conv, ok := convFromType[f.Kind()]
-	if !ok {
-		return fmt.Errorf("field type %T is not supported in query parameters", i)
-	}
-	result := conv.Call([]reflect.Value{reflect.ValueOf(value)})
-	if err := result[1].Interface(); err != nil {
-		return err.(error)
-	}
-	f.Set(result[0].Convert(f.Type()))
-	return nil
-}
-
-func convertEnum(value string, t reflect.Type, enumValMap map[string]int32) (reflect.Value, error) {
-	// see if it's an enumeration string
-	if enumVal, ok := enumValMap[value]; ok {
-		return reflect.ValueOf(enumVal).Convert(t), nil
-	}
-
-	// check for an integer that matches an enumeration value
-	eVal, err := strconv.Atoi(value)
-	if err != nil {
-		return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t)
-	}
-	for _, v := range enumValMap {
-		if v == int32(eVal) {
-			return reflect.ValueOf(eVal).Convert(t), nil
-		}
-	}
-	return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t)
-}
-
-func populateFieldEnum(f reflect.Value, value string, enumValMap map[string]int32) error {
-	cval, err := convertEnum(value, f.Type(), enumValMap)
-	if err != nil {
-		return err
-	}
-	f.Set(cval)
-	return nil
-}
-
-func populateFieldEnumRepeated(f reflect.Value, values []string, enumValMap map[string]int32) error {
-	elemType := f.Type().Elem()
-	f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type()))
-	for i, v := range values {
-		result, err := convertEnum(v, elemType, enumValMap)
-		if err != nil {
-			return err
-		}
-		f.Index(i).Set(result)
-	}
-	return nil
-}
-
-var (
-	convFromType = map[reflect.Kind]reflect.Value{
-		reflect.String:  reflect.ValueOf(String),
-		reflect.Bool:    reflect.ValueOf(Bool),
-		reflect.Float64: reflect.ValueOf(Float64),
-		reflect.Float32: reflect.ValueOf(Float32),
-		reflect.Int64:   reflect.ValueOf(Int64),
-		reflect.Int32:   reflect.ValueOf(Int32),
-		reflect.Uint64:  reflect.ValueOf(Uint64),
-		reflect.Uint32:  reflect.ValueOf(Uint32),
-		reflect.Slice:   reflect.ValueOf(Bytes),
-	}
-)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/LICENSE b/vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/LICENSE
deleted file mode 100644
index 261eeb9..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel
deleted file mode 100644
index 58d291c..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel
+++ /dev/null
@@ -1,20 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
-    name = "go_default_library",
-    srcs = [
-        "doc.go",
-        "pattern.go",
-        "trie.go",
-    ],
-    importpath = "github.com/grpc-ecosystem/grpc-gateway/utilities",
-)
-
-go_test(
-    name = "go_default_xtest",
-    size = "small",
-    srcs = ["trie_test.go"],
-    deps = [":go_default_library"],
-)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go
deleted file mode 100644
index cf79a4d..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go
+++ /dev/null
@@ -1,2 +0,0 @@
-// Package utilities provides members for internal use in grpc-gateway.
-package utilities
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go
deleted file mode 100644
index dfe7de4..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package utilities
-
-// An OpCode is a opcode of compiled path patterns.
-type OpCode int
-
-// These constants are the valid values of OpCode.
-const (
-	// OpNop does nothing
-	OpNop = OpCode(iota)
-	// OpPush pushes a component to stack
-	OpPush
-	// OpLitPush pushes a component to stack if it matches to the literal
-	OpLitPush
-	// OpPushM concatenates the remaining components and pushes it to stack
-	OpPushM
-	// OpConcatN pops N items from stack, concatenates them and pushes it back to stack
-	OpConcatN
-	// OpCapture pops an item and binds it to the variable
-	OpCapture
-	// OpEnd is the least positive invalid opcode.
-	OpEnd
-)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go
deleted file mode 100644
index c2b7b30..0000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go
+++ /dev/null
@@ -1,177 +0,0 @@
-package utilities
-
-import (
-	"sort"
-)
-
-// DoubleArray is a Double Array implementation of trie on sequences of strings.
-type DoubleArray struct {
-	// Encoding keeps an encoding from string to int
-	Encoding map[string]int
-	// Base is the base array of Double Array
-	Base []int
-	// Check is the check array of Double Array
-	Check []int
-}
-
-// NewDoubleArray builds a DoubleArray from a set of sequences of strings.
-func NewDoubleArray(seqs [][]string) *DoubleArray {
-	da := &DoubleArray{Encoding: make(map[string]int)}
-	if len(seqs) == 0 {
-		return da
-	}
-
-	encoded := registerTokens(da, seqs)
-	sort.Sort(byLex(encoded))
-
-	root := node{row: -1, col: -1, left: 0, right: len(encoded)}
-	addSeqs(da, encoded, 0, root)
-
-	for i := len(da.Base); i > 0; i-- {
-		if da.Check[i-1] != 0 {
-			da.Base = da.Base[:i]
-			da.Check = da.Check[:i]
-			break
-		}
-	}
-	return da
-}
-
-func registerTokens(da *DoubleArray, seqs [][]string) [][]int {
-	var result [][]int
-	for _, seq := range seqs {
-		var encoded []int
-		for _, token := range seq {
-			if _, ok := da.Encoding[token]; !ok {
-				da.Encoding[token] = len(da.Encoding)
-			}
-			encoded = append(encoded, da.Encoding[token])
-		}
-		result = append(result, encoded)
-	}
-	for i := range result {
-		result[i] = append(result[i], len(da.Encoding))
-	}
-	return result
-}
-
-type node struct {
-	row, col    int
-	left, right int
-}
-
-func (n node) value(seqs [][]int) int {
-	return seqs[n.row][n.col]
-}
-
-func (n node) children(seqs [][]int) []*node {
-	var result []*node
-	lastVal := int(-1)
-	last := new(node)
-	for i := n.left; i < n.right; i++ {
-		if lastVal == seqs[i][n.col+1] {
-			continue
-		}
-		last.right = i
-		last = &node{
-			row:  i,
-			col:  n.col + 1,
-			left: i,
-		}
-		result = append(result, last)
-	}
-	last.right = n.right
-	return result
-}
-
-func addSeqs(da *DoubleArray, seqs [][]int, pos int, n node) {
-	ensureSize(da, pos)
-
-	children := n.children(seqs)
-	var i int
-	for i = 1; ; i++ {
-		ok := func() bool {
-			for _, child := range children {
-				code := child.value(seqs)
-				j := i + code
-				ensureSize(da, j)
-				if da.Check[j] != 0 {
-					return false
-				}
-			}
-			return true
-		}()
-		if ok {
-			break
-		}
-	}
-	da.Base[pos] = i
-	for _, child := range children {
-		code := child.value(seqs)
-		j := i + code
-		da.Check[j] = pos + 1
-	}
-	terminator := len(da.Encoding)
-	for _, child := range children {
-		code := child.value(seqs)
-		if code == terminator {
-			continue
-		}
-		j := i + code
-		addSeqs(da, seqs, j, *child)
-	}
-}
-
-func ensureSize(da *DoubleArray, i int) {
-	for i >= len(da.Base) {
-		da.Base = append(da.Base, make([]int, len(da.Base)+1)...)
-		da.Check = append(da.Check, make([]int, len(da.Check)+1)...)
-	}
-}
-
-type byLex [][]int
-
-func (l byLex) Len() int      { return len(l) }
-func (l byLex) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
-func (l byLex) Less(i, j int) bool {
-	si := l[i]
-	sj := l[j]
-	var k int
-	for k = 0; k < len(si) && k < len(sj); k++ {
-		if si[k] < sj[k] {
-			return true
-		}
-		if si[k] > sj[k] {
-			return false
-		}
-	}
-	if k < len(sj) {
-		return true
-	}
-	return false
-}
-
-// HasCommonPrefix determines if any sequence in the DoubleArray is a prefix of the given sequence.
-func (da *DoubleArray) HasCommonPrefix(seq []string) bool {
-	if len(da.Base) == 0 {
-		return false
-	}
-
-	var i int
-	for _, t := range seq {
-		code, ok := da.Encoding[t]
-		if !ok {
-			break
-		}
-		j := da.Base[i] + code
-		if len(da.Check) <= j || da.Check[j] != i+1 {
-			break
-		}
-		i = j
-	}
-	j := da.Base[i] + len(da.Encoding)
-	if len(da.Check) <= j || da.Check[j] != i+1 {
-		return false
-	}
-	return true
-}
diff --git a/vendor/github.com/inconshreveable/mousetrap/LICENSE b/vendor/github.com/inconshreveable/mousetrap/LICENSE
deleted file mode 100644
index 5f0d1fb..0000000
--- a/vendor/github.com/inconshreveable/mousetrap/LICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright 2014 Alan Shreve
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/github.com/inconshreveable/mousetrap/README.md b/vendor/github.com/inconshreveable/mousetrap/README.md
deleted file mode 100644
index 7a950d1..0000000
--- a/vendor/github.com/inconshreveable/mousetrap/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# mousetrap
-
-mousetrap is a tiny library that answers a single question.
-
-On a Windows machine, was the process invoked by someone double clicking on
-the executable file while browsing in explorer?
-
-### Motivation
-
-Windows developers unfamiliar with command line tools will often "double-click"
-the executable for a tool. Because most CLI tools print the help and then exit
-when invoked without arguments, this is often very frustrating for those users.
-
-mousetrap provides a way to detect these invocations so that you can provide
-more helpful behavior and instructions on how to run the CLI tool. To see what
-this looks like, both from an organizational and a technical perspective, see
-https://inconshreveable.com/09-09-2014/sweat-the-small-stuff/
-
-### The interface
-
-The library exposes a single interface:
-
-    func StartedByExplorer() (bool)
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_others.go b/vendor/github.com/inconshreveable/mousetrap/trap_others.go
deleted file mode 100644
index 9d2d8a4..0000000
--- a/vendor/github.com/inconshreveable/mousetrap/trap_others.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// +build !windows
-
-package mousetrap
-
-// StartedByExplorer returns true if the program was invoked by the user
-// double-clicking on the executable from explorer.exe
-//
-// It is conservative and returns false if any of the internal calls fail.
-// It does not guarantee that the program was run from a terminal. It only can tell you
-// whether it was launched from explorer.exe
-//
-// On non-Windows platforms, it always returns false.
-func StartedByExplorer() bool {
-	return false
-}
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go
deleted file mode 100644
index 336142a..0000000
--- a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// +build windows
-// +build !go1.4
-
-package mousetrap
-
-import (
-	"fmt"
-	"os"
-	"syscall"
-	"unsafe"
-)
-
-const (
-	// defined by the Win32 API
-	th32cs_snapprocess uintptr = 0x2
-)
-
-var (
-	kernel                   = syscall.MustLoadDLL("kernel32.dll")
-	CreateToolhelp32Snapshot = kernel.MustFindProc("CreateToolhelp32Snapshot")
-	Process32First           = kernel.MustFindProc("Process32FirstW")
-	Process32Next            = kernel.MustFindProc("Process32NextW")
-)
-
-// ProcessEntry32 structure defined by the Win32 API
-type processEntry32 struct {
-	dwSize              uint32
-	cntUsage            uint32
-	th32ProcessID       uint32
-	th32DefaultHeapID   int
-	th32ModuleID        uint32
-	cntThreads          uint32
-	th32ParentProcessID uint32
-	pcPriClassBase      int32
-	dwFlags             uint32
-	szExeFile           [syscall.MAX_PATH]uint16
-}
-
-func getProcessEntry(pid int) (pe *processEntry32, err error) {
-	snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0))
-	if snapshot == uintptr(syscall.InvalidHandle) {
-		err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1)
-		return
-	}
-	defer syscall.CloseHandle(syscall.Handle(snapshot))
-
-	var processEntry processEntry32
-	processEntry.dwSize = uint32(unsafe.Sizeof(processEntry))
-	ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
-	if ok == 0 {
-		err = fmt.Errorf("Process32First: %v", e1)
-		return
-	}
-
-	for {
-		if processEntry.th32ProcessID == uint32(pid) {
-			pe = &processEntry
-			return
-		}
-
-		ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
-		if ok == 0 {
-			err = fmt.Errorf("Process32Next: %v", e1)
-			return
-		}
-	}
-}
-
-func getppid() (pid int, err error) {
-	pe, err := getProcessEntry(os.Getpid())
-	if err != nil {
-		return
-	}
-
-	pid = int(pe.th32ParentProcessID)
-	return
-}
-
-// StartedByExplorer returns true if the program was invoked by the user double-clicking
-// on the executable from explorer.exe
-//
-// It is conservative and returns false if any of the internal calls fail.
-// It does not guarantee that the program was run from a terminal. It only can tell you
-// whether it was launched from explorer.exe
-func StartedByExplorer() bool {
-	ppid, err := getppid()
-	if err != nil {
-		return false
-	}
-
-	pe, err := getProcessEntry(ppid)
-	if err != nil {
-		return false
-	}
-
-	name := syscall.UTF16ToString(pe.szExeFile[:])
-	return name == "explorer.exe"
-}
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go
deleted file mode 100644
index 9a28e57..0000000
--- a/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// +build windows
-// +build go1.4
-
-package mousetrap
-
-import (
-	"os"
-	"syscall"
-	"unsafe"
-)
-
-func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {
-	snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
-	if err != nil {
-		return nil, err
-	}
-	defer syscall.CloseHandle(snapshot)
-	var procEntry syscall.ProcessEntry32
-	procEntry.Size = uint32(unsafe.Sizeof(procEntry))
-	if err = syscall.Process32First(snapshot, &procEntry); err != nil {
-		return nil, err
-	}
-	for {
-		if procEntry.ProcessID == uint32(pid) {
-			return &procEntry, nil
-		}
-		err = syscall.Process32Next(snapshot, &procEntry)
-		if err != nil {
-			return nil, err
-		}
-	}
-}
-
-// StartedByExplorer returns true if the program was invoked by the user double-clicking
-// on the executable from explorer.exe
-//
-// It is conservative and returns false if any of the internal calls fail.
-// It does not guarantee that the program was run from a terminal. It only can tell you
-// whether it was launched from explorer.exe
-func StartedByExplorer() bool {
-	pe, err := getProcessEntry(os.Getppid())
-	if err != nil {
-		return false
-	}
-	return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:])
-}
diff --git a/vendor/github.com/jonboulle/clockwork/.gitignore b/vendor/github.com/jonboulle/clockwork/.gitignore
deleted file mode 100644
index 010c242..0000000
--- a/vendor/github.com/jonboulle/clockwork/.gitignore
+++ /dev/null
@@ -1,25 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
-
-*.swp
diff --git a/vendor/github.com/jonboulle/clockwork/.travis.yml b/vendor/github.com/jonboulle/clockwork/.travis.yml
deleted file mode 100644
index aefda90..0000000
--- a/vendor/github.com/jonboulle/clockwork/.travis.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-language: go
-go:
-  - 1.3
-
-sudo: false
diff --git a/vendor/github.com/jonboulle/clockwork/LICENSE b/vendor/github.com/jonboulle/clockwork/LICENSE
deleted file mode 100644
index 5c304d1..0000000
--- a/vendor/github.com/jonboulle/clockwork/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "{}"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright {yyyy} {name of copyright owner}
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/jonboulle/clockwork/README.md b/vendor/github.com/jonboulle/clockwork/README.md
deleted file mode 100644
index d43a6c7..0000000
--- a/vendor/github.com/jonboulle/clockwork/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-clockwork
-=========
-
-[![Build Status](https://travis-ci.org/jonboulle/clockwork.png?branch=master)](https://travis-ci.org/jonboulle/clockwork)
-[![godoc](https://godoc.org/github.com/jonboulle/clockwork?status.svg)](http://godoc.org/github.com/jonboulle/clockwork) 
-
-a simple fake clock for golang
-
-# Usage
-
-Replace uses of the `time` package with the `clockwork.Clock` interface instead.
-
-For example, instead of using `time.Sleep` directly:
-
-```
-func my_func() {
-	time.Sleep(3 * time.Second)
-	do_something()
-}
-```
-
-inject a clock and use its `Sleep` method instead:
-
-```
-func my_func(clock clockwork.Clock) {
-	clock.Sleep(3 * time.Second)
-	do_something()
-}
-```
-
-Now you can easily test `my_func` with a `FakeClock`:
-
-```
-func TestMyFunc(t *testing.T) {
-	c := clockwork.NewFakeClock()
-
-	// Start our sleepy function
-	my_func(c)
-
-	// Ensure we wait until my_func is sleeping
-	c.BlockUntil(1)
-
-	assert_state()
-
-	// Advance the FakeClock forward in time
-	c.Advance(3)
-
-	assert_state()
-}
-```
-
-and in production builds, simply inject the real clock instead:
-```
-my_func(clockwork.NewRealClock())
-```
-
-See [example_test.go](example_test.go) for a full example.
-
-# Credits
-
-clockwork is inspired by @wickman's [threaded fake clock](https://gist.github.com/wickman/3840816), and the [Golang playground](http://blog.golang.org/playground#Faking time)
diff --git a/vendor/github.com/jonboulle/clockwork/clockwork.go b/vendor/github.com/jonboulle/clockwork/clockwork.go
deleted file mode 100644
index 9ec96ed..0000000
--- a/vendor/github.com/jonboulle/clockwork/clockwork.go
+++ /dev/null
@@ -1,169 +0,0 @@
-package clockwork
-
-import (
-	"sync"
-	"time"
-)
-
-// Clock provides an interface that packages can use instead of directly
-// using the time module, so that chronology-related behavior can be tested
-type Clock interface {
-	After(d time.Duration) <-chan time.Time
-	Sleep(d time.Duration)
-	Now() time.Time
-}
-
-// FakeClock provides an interface for a clock which can be
-// manually advanced through time
-type FakeClock interface {
-	Clock
-	// Advance advances the FakeClock to a new point in time, ensuring any existing
-	// sleepers are notified appropriately before returning
-	Advance(d time.Duration)
-	// BlockUntil will block until the FakeClock has the given number of
-	// sleepers (callers of Sleep or After)
-	BlockUntil(n int)
-}
-
-// NewRealClock returns a Clock which simply delegates calls to the actual time
-// package; it should be used by packages in production.
-func NewRealClock() Clock {
-	return &realClock{}
-}
-
-// NewFakeClock returns a FakeClock implementation which can be
-// manually advanced through time for testing. The initial time of the
-// FakeClock will be an arbitrary non-zero time.
-func NewFakeClock() FakeClock {
-	// use a fixture that does not fulfill Time.IsZero()
-	return NewFakeClockAt(time.Date(1984, time.April, 4, 0, 0, 0, 0, time.UTC))
-}
-
-// NewFakeClockAt returns a FakeClock initialised at the given time.Time.
-func NewFakeClockAt(t time.Time) FakeClock {
-	return &fakeClock{
-		time: t,
-	}
-}
-
-type realClock struct{}
-
-func (rc *realClock) After(d time.Duration) <-chan time.Time {
-	return time.After(d)
-}
-
-func (rc *realClock) Sleep(d time.Duration) {
-	time.Sleep(d)
-}
-
-func (rc *realClock) Now() time.Time {
-	return time.Now()
-}
-
-type fakeClock struct {
-	sleepers []*sleeper
-	blockers []*blocker
-	time     time.Time
-
-	l sync.RWMutex
-}
-
-// sleeper represents a caller of After or Sleep
-type sleeper struct {
-	until time.Time
-	done  chan time.Time
-}
-
-// blocker represents a caller of BlockUntil
-type blocker struct {
-	count int
-	ch    chan struct{}
-}
-
-// After mimics time.After; it waits for the given duration to elapse on the
-// fakeClock, then sends the current time on the returned channel.
-func (fc *fakeClock) After(d time.Duration) <-chan time.Time {
-	fc.l.Lock()
-	defer fc.l.Unlock()
-	now := fc.time
-	done := make(chan time.Time, 1)
-	if d.Nanoseconds() == 0 {
-		// special case - trigger immediately
-		done <- now
-	} else {
-		// otherwise, add to the set of sleepers
-		s := &sleeper{
-			until: now.Add(d),
-			done:  done,
-		}
-		fc.sleepers = append(fc.sleepers, s)
-		// and notify any blockers
-		fc.blockers = notifyBlockers(fc.blockers, len(fc.sleepers))
-	}
-	return done
-}
-
-// notifyBlockers notifies all the blockers waiting until the
-// given number of sleepers are waiting on the fakeClock. It
-// returns an updated slice of blockers (i.e. those still waiting)
-func notifyBlockers(blockers []*blocker, count int) (newBlockers []*blocker) {
-	for _, b := range blockers {
-		if b.count == count {
-			close(b.ch)
-		} else {
-			newBlockers = append(newBlockers, b)
-		}
-	}
-	return
-}
-
-// Sleep blocks until the given duration has passed on the fakeClock
-func (fc *fakeClock) Sleep(d time.Duration) {
-	<-fc.After(d)
-}
-
-// Time returns the current time of the fakeClock
-func (fc *fakeClock) Now() time.Time {
-	fc.l.RLock()
-	t := fc.time
-	fc.l.RUnlock()
-	return t
-}
-
-// Advance advances fakeClock to a new point in time, ensuring channels from any
-// previous invocations of After are notified appropriately before returning
-func (fc *fakeClock) Advance(d time.Duration) {
-	fc.l.Lock()
-	defer fc.l.Unlock()
-	end := fc.time.Add(d)
-	var newSleepers []*sleeper
-	for _, s := range fc.sleepers {
-		if end.Sub(s.until) >= 0 {
-			s.done <- end
-		} else {
-			newSleepers = append(newSleepers, s)
-		}
-	}
-	fc.sleepers = newSleepers
-	fc.blockers = notifyBlockers(fc.blockers, len(fc.sleepers))
-	fc.time = end
-}
-
-// BlockUntil will block until the fakeClock has the given number of sleepers
-// (callers of Sleep or After)
-func (fc *fakeClock) BlockUntil(n int) {
-	fc.l.Lock()
-	// Fast path: current number of sleepers is what we're looking for
-	if len(fc.sleepers) == n {
-		fc.l.Unlock()
-		return
-	}
-	// Otherwise, set up a new blocker
-	b := &blocker{
-		count: n,
-		ch:    make(chan struct{}),
-	}
-	fc.blockers = append(fc.blockers, b)
-	fc.l.Unlock()
-	<-b.ch
-}
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE b/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE
deleted file mode 100644
index 14127cd..0000000
--- a/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE
+++ /dev/null
@@ -1,9 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md b/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md
deleted file mode 100644
index 949b77e..0000000
--- a/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Windows Terminal Sequences
-
-This library allow for enabling Windows terminal color support for Go.
-
-See [Console Virtual Terminal Sequences](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) for details.
-
-## Usage
-
-```go
-import (
-	"syscall"
-	
-	sequences "github.com/konsorten/go-windows-terminal-sequences"
-)
-
-func main() {
-	sequences.EnableVirtualTerminalProcessing(syscall.Stdout, true)
-}
-
-```
-
-## Authors
-
-The tool is sponsored by the [marvin + konsorten GmbH](http://www.konsorten.de).
-
-We thank all the authors who provided code to this library:
-
-* Felix Kollmann
-
-## License
-
-(The MIT License)
-
-Copyright (c) 2018 marvin + konsorten GmbH (open-source@konsorten.de)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod b/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod
deleted file mode 100644
index 716c613..0000000
--- a/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod
+++ /dev/null
@@ -1 +0,0 @@
-module github.com/konsorten/go-windows-terminal-sequences
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go
deleted file mode 100644
index ef18d8f..0000000
--- a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// +build windows
-
-package sequences
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-var (
-	kernel32Dll    *syscall.LazyDLL  = syscall.NewLazyDLL("Kernel32.dll")
-	setConsoleMode *syscall.LazyProc = kernel32Dll.NewProc("SetConsoleMode")
-)
-
-func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error {
-	const ENABLE_VIRTUAL_TERMINAL_PROCESSING uint32 = 0x4
-
-	var mode uint32
-	err := syscall.GetConsoleMode(syscall.Stdout, &mode)
-	if err != nil {
-		return err
-	}
-
-	if enable {
-		mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING
-	} else {
-		mode &^= ENABLE_VIRTUAL_TERMINAL_PROCESSING
-	}
-
-	ret, _, err := setConsoleMode.Call(uintptr(unsafe.Pointer(stream)), uintptr(mode))
-	if ret == 0 {
-		return err
-	}
-
-	return nil
-}
diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE b/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE
deleted file mode 100644
index 8dada3e..0000000
--- a/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "{}"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright {yyyy} {name of copyright owner}
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE b/vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE
deleted file mode 100644
index 5d8cb5b..0000000
--- a/vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE
+++ /dev/null
@@ -1 +0,0 @@
-Copyright 2012 Matt T. Proud (matt.proud@gmail.com)
diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/.gitignore b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/.gitignore
deleted file mode 100644
index e16fb94..0000000
--- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-cover.dat
diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/Makefile b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/Makefile
deleted file mode 100644
index 81be214..0000000
--- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-all:
-
-cover:
-	go test -cover -v -coverprofile=cover.dat ./...
-	go tool cover -func cover.dat
-
-.PHONY: cover
diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go
deleted file mode 100644
index 258c063..0000000
--- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2013 Matt T. Proud
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package pbutil
-
-import (
-	"encoding/binary"
-	"errors"
-	"io"
-
-	"github.com/golang/protobuf/proto"
-)
-
-var errInvalidVarint = errors.New("invalid varint32 encountered")
-
-// ReadDelimited decodes a message from the provided length-delimited stream,
-// where the length is encoded as 32-bit varint prefix to the message body.
-// It returns the total number of bytes read and any applicable error.  This is
-// roughly equivalent to the companion Java API's
-// MessageLite#parseDelimitedFrom.  As per the reader contract, this function
-// calls r.Read repeatedly as required until exactly one message including its
-// prefix is read and decoded (or an error has occurred).  The function never
-// reads more bytes from the stream than required.  The function never returns
-// an error if a message has been read and decoded correctly, even if the end
-// of the stream has been reached in doing so.  In that case, any subsequent
-// calls return (0, io.EOF).
-func ReadDelimited(r io.Reader, m proto.Message) (n int, err error) {
-	// Per AbstractParser#parsePartialDelimitedFrom with
-	// CodedInputStream#readRawVarint32.
-	var headerBuf [binary.MaxVarintLen32]byte
-	var bytesRead, varIntBytes int
-	var messageLength uint64
-	for varIntBytes == 0 { // i.e. no varint has been decoded yet.
-		if bytesRead >= len(headerBuf) {
-			return bytesRead, errInvalidVarint
-		}
-		// We have to read byte by byte here to avoid reading more bytes
-		// than required. Each read byte is appended to what we have
-		// read before.
-		newBytesRead, err := r.Read(headerBuf[bytesRead : bytesRead+1])
-		if newBytesRead == 0 {
-			if err != nil {
-				return bytesRead, err
-			}
-			// A Reader should not return (0, nil), but if it does,
-			// it should be treated as no-op (according to the
-			// Reader contract). So let's go on...
-			continue
-		}
-		bytesRead += newBytesRead
-		// Now present everything read so far to the varint decoder and
-		// see if a varint can be decoded already.
-		messageLength, varIntBytes = proto.DecodeVarint(headerBuf[:bytesRead])
-	}
-
-	messageBuf := make([]byte, messageLength)
-	newBytesRead, err := io.ReadFull(r, messageBuf)
-	bytesRead += newBytesRead
-	if err != nil {
-		return bytesRead, err
-	}
-
-	return bytesRead, proto.Unmarshal(messageBuf, m)
-}
diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/doc.go b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/doc.go
deleted file mode 100644
index c318385..0000000
--- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2013 Matt T. Proud
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package pbutil provides record length-delimited Protocol Buffer streaming.
-package pbutil
diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go
deleted file mode 100644
index 8fb59ad..0000000
--- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013 Matt T. Proud
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package pbutil
-
-import (
-	"encoding/binary"
-	"io"
-
-	"github.com/golang/protobuf/proto"
-)
-
-// WriteDelimited encodes and dumps a message to the provided writer prefixed
-// with a 32-bit varint indicating the length of the encoded message, producing
-// a length-delimited record stream, which can be used to chain together
-// encoded messages of the same type together in a file.  It returns the total
-// number of bytes written and any applicable error.  This is roughly
-// equivalent to the companion Java API's MessageLite#writeDelimitedTo.
-func WriteDelimited(w io.Writer, m proto.Message) (n int, err error) {
-	buffer, err := proto.Marshal(m)
-	if err != nil {
-		return 0, err
-	}
-
-	var buf [binary.MaxVarintLen32]byte
-	encodedLength := binary.PutUvarint(buf[:], uint64(len(buffer)))
-
-	sync, err := w.Write(buf[:encodedLength])
-	if err != nil {
-		return sync, err
-	}
-
-	n, err = w.Write(buffer)
-	return n + sync, err
-}
diff --git a/vendor/github.com/prometheus/client_golang/LICENSE b/vendor/github.com/prometheus/client_golang/LICENSE
deleted file mode 100644
index 261eeb9..0000000
--- a/vendor/github.com/prometheus/client_golang/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/prometheus/client_golang/NOTICE b/vendor/github.com/prometheus/client_golang/NOTICE
deleted file mode 100644
index dd878a3..0000000
--- a/vendor/github.com/prometheus/client_golang/NOTICE
+++ /dev/null
@@ -1,23 +0,0 @@
-Prometheus instrumentation library for Go applications
-Copyright 2012-2015 The Prometheus Authors
-
-This product includes software developed at
-SoundCloud Ltd. (http://soundcloud.com/).
-
-
-The following components are included in this product:
-
-perks - a fork of https://github.com/bmizerany/perks
-https://github.com/beorn7/perks
-Copyright 2013-2015 Blake Mizerany, Björn Rabenstein
-See https://github.com/beorn7/perks/blob/master/README.md for license details.
-
-Go support for Protocol Buffers - Google's data interchange format
-http://github.com/golang/protobuf/
-Copyright 2010 The Go Authors
-See source code for license details.
-
-Support for streaming Protocol Buffer messages for the Go language (golang).
-https://github.com/matttproud/golang_protobuf_extensions
-Copyright 2013 Matt T. Proud
-Licensed under the Apache License, Version 2.0
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/.gitignore b/vendor/github.com/prometheus/client_golang/prometheus/.gitignore
deleted file mode 100644
index 3460f03..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-command-line-arguments.test
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/README.md b/vendor/github.com/prometheus/client_golang/prometheus/README.md
deleted file mode 100644
index 44986bf..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/README.md
+++ /dev/null
@@ -1 +0,0 @@
-See [![go-doc](https://godoc.org/github.com/prometheus/client_golang/prometheus?status.svg)](https://godoc.org/github.com/prometheus/client_golang/prometheus).
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collector.go b/vendor/github.com/prometheus/client_golang/prometheus/collector.go
deleted file mode 100644
index c0d70b2..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/collector.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-// Collector is the interface implemented by anything that can be used by
-// Prometheus to collect metrics. A Collector has to be registered for
-// collection. See Registerer.Register.
-//
-// The stock metrics provided by this package (Gauge, Counter, Summary,
-// Histogram, Untyped) are also Collectors (which only ever collect one metric,
-// namely itself). An implementer of Collector may, however, collect multiple
-// metrics in a coordinated fashion and/or create metrics on the fly. Examples
-// for collectors already implemented in this library are the metric vectors
-// (i.e. collection of multiple instances of the same Metric but with different
-// label values) like GaugeVec or SummaryVec, and the ExpvarCollector.
-type Collector interface {
-	// Describe sends the super-set of all possible descriptors of metrics
-	// collected by this Collector to the provided channel and returns once
-	// the last descriptor has been sent. The sent descriptors fulfill the
-	// consistency and uniqueness requirements described in the Desc
-	// documentation.
-	//
-	// It is valid if one and the same Collector sends duplicate
-	// descriptors. Those duplicates are simply ignored. However, two
-	// different Collectors must not send duplicate descriptors.
-	//
-	// Sending no descriptor at all marks the Collector as “unchecked”,
-	// i.e. no checks will be performed at registration time, and the
-	// Collector may yield any Metric it sees fit in its Collect method.
-	//
-	// This method idempotently sends the same descriptors throughout the
-	// lifetime of the Collector. It may be called concurrently and
-	// therefore must be implemented in a concurrency safe way.
-	//
-	// If a Collector encounters an error while executing this method, it
-	// must send an invalid descriptor (created with NewInvalidDesc) to
-	// signal the error to the registry.
-	Describe(chan<- *Desc)
-	// Collect is called by the Prometheus registry when collecting
-	// metrics. The implementation sends each collected metric via the
-	// provided channel and returns once the last metric has been sent. The
-	// descriptor of each sent metric is one of those returned by Describe
-	// (unless the Collector is unchecked, see above). Returned metrics that
-	// share the same descriptor must differ in their variable label
-	// values.
-	//
-	// This method may be called concurrently and must therefore be
-	// implemented in a concurrency safe way. Blocking occurs at the expense
-	// of total performance of rendering all registered metrics. Ideally,
-	// Collector implementations support concurrent readers.
-	Collect(chan<- Metric)
-}
-
-// DescribeByCollect is a helper to implement the Describe method of a custom
-// Collector. It collects the metrics from the provided Collector and sends
-// their descriptors to the provided channel.
-//
-// If a Collector collects the same metrics throughout its lifetime, its
-// Describe method can simply be implemented as:
-//
-//   func (c customCollector) Describe(ch chan<- *Desc) {
-//   	DescribeByCollect(c, ch)
-//   }
-//
-// However, this will not work if the metrics collected change dynamically over
-// the lifetime of the Collector in a way that their combined set of descriptors
-// changes as well. The shortcut implementation will then violate the contract
-// of the Describe method. If a Collector sometimes collects no metrics at all
-// (for example vectors like CounterVec, GaugeVec, etc., which only collect
-// metrics after a metric with a fully specified label set has been accessed),
-// it might even get registered as an unchecked Collecter (cf. the Register
-// method of the Registerer interface). Hence, only use this shortcut
-// implementation of Describe if you are certain to fulfill the contract.
-//
-// The Collector example demonstrates a use of DescribeByCollect.
-func DescribeByCollect(c Collector, descs chan<- *Desc) {
-	metrics := make(chan Metric)
-	go func() {
-		c.Collect(metrics)
-		close(metrics)
-	}()
-	for m := range metrics {
-		descs <- m.Desc()
-	}
-}
-
-// selfCollector implements Collector for a single Metric so that the Metric
-// collects itself. Add it as an anonymous field to a struct that implements
-// Metric, and call init with the Metric itself as an argument.
-type selfCollector struct {
-	self Metric
-}
-
-// init provides the selfCollector with a reference to the metric it is supposed
-// to collect. It is usually called within the factory function to create a
-// metric. See example.
-func (c *selfCollector) init(self Metric) {
-	c.self = self
-}
-
-// Describe implements Collector.
-func (c *selfCollector) Describe(ch chan<- *Desc) {
-	ch <- c.self.Desc()
-}
-
-// Collect implements Collector.
-func (c *selfCollector) Collect(ch chan<- Metric) {
-	ch <- c.self
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/counter.go b/vendor/github.com/prometheus/client_golang/prometheus/counter.go
deleted file mode 100644
index d463e36..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/counter.go
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"errors"
-	"math"
-	"sync/atomic"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-// Counter is a Metric that represents a single numerical value that only ever
-// goes up. That implies that it cannot be used to count items whose number can
-// also go down, e.g. the number of currently running goroutines. Those
-// "counters" are represented by Gauges.
-//
-// A Counter is typically used to count requests served, tasks completed, errors
-// occurred, etc.
-//
-// To create Counter instances, use NewCounter.
-type Counter interface {
-	Metric
-	Collector
-
-	// Inc increments the counter by 1. Use Add to increment it by arbitrary
-	// non-negative values.
-	Inc()
-	// Add adds the given value to the counter. It panics if the value is <
-	// 0.
-	Add(float64)
-}
-
-// CounterOpts is an alias for Opts. See there for doc comments.
-type CounterOpts Opts
-
-// NewCounter creates a new Counter based on the provided CounterOpts.
-//
-// The returned implementation tracks the counter value in two separate
-// variables, a float64 and a uint64. The latter is used to track calls of the
-// Inc method and calls of the Add method with a value that can be represented
-// as a uint64. This allows atomic increments of the counter with optimal
-// performance. (It is common to have an Inc call in very hot execution paths.)
-// Both internal tracking values are added up in the Write method. This has to
-// be taken into account when it comes to precision and overflow behavior.
-func NewCounter(opts CounterOpts) Counter {
-	desc := NewDesc(
-		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-		opts.Help,
-		nil,
-		opts.ConstLabels,
-	)
-	result := &counter{desc: desc, labelPairs: desc.constLabelPairs}
-	result.init(result) // Init self-collection.
-	return result
-}
-
-type counter struct {
-	// valBits contains the bits of the represented float64 value, while
-	// valInt stores values that are exact integers. Both have to go first
-	// in the struct to guarantee alignment for atomic operations.
-	// http://golang.org/pkg/sync/atomic/#pkg-note-BUG
-	valBits uint64
-	valInt  uint64
-
-	selfCollector
-	desc *Desc
-
-	labelPairs []*dto.LabelPair
-}
-
-func (c *counter) Desc() *Desc {
-	return c.desc
-}
-
-func (c *counter) Add(v float64) {
-	if v < 0 {
-		panic(errors.New("counter cannot decrease in value"))
-	}
-	ival := uint64(v)
-	if float64(ival) == v {
-		atomic.AddUint64(&c.valInt, ival)
-		return
-	}
-
-	for {
-		oldBits := atomic.LoadUint64(&c.valBits)
-		newBits := math.Float64bits(math.Float64frombits(oldBits) + v)
-		if atomic.CompareAndSwapUint64(&c.valBits, oldBits, newBits) {
-			return
-		}
-	}
-}
-
-func (c *counter) Inc() {
-	atomic.AddUint64(&c.valInt, 1)
-}
-
-func (c *counter) Write(out *dto.Metric) error {
-	fval := math.Float64frombits(atomic.LoadUint64(&c.valBits))
-	ival := atomic.LoadUint64(&c.valInt)
-	val := fval + float64(ival)
-
-	return populateMetric(CounterValue, val, c.labelPairs, out)
-}
-
-// CounterVec is a Collector that bundles a set of Counters that all share the
-// same Desc, but have different values for their variable labels. This is used
-// if you want to count the same thing partitioned by various dimensions
-// (e.g. number of HTTP requests, partitioned by response code and
-// method). Create instances with NewCounterVec.
-type CounterVec struct {
-	*metricVec
-}
-
-// NewCounterVec creates a new CounterVec based on the provided CounterOpts and
-// partitioned by the given label names.
-func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
-	desc := NewDesc(
-		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-		opts.Help,
-		labelNames,
-		opts.ConstLabels,
-	)
-	return &CounterVec{
-		metricVec: newMetricVec(desc, func(lvs ...string) Metric {
-			if len(lvs) != len(desc.variableLabels) {
-				panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, lvs))
-			}
-			result := &counter{desc: desc, labelPairs: makeLabelPairs(desc, lvs)}
-			result.init(result) // Init self-collection.
-			return result
-		}),
-	}
-}
-
-// GetMetricWithLabelValues returns the Counter for the given slice of label
-// values (same order as the VariableLabels in Desc). If that combination of
-// label values is accessed for the first time, a new Counter is created.
-//
-// It is possible to call this method without using the returned Counter to only
-// create the new Counter but leave it at its starting value 0. See also the
-// SummaryVec example.
-//
-// Keeping the Counter for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Counter from the CounterVec. In that case,
-// the Counter will still exist, but it will not be exported anymore, even if a
-// Counter with the same label values is created later.
-//
-// An error is returned if the number of label values is not the same as the
-// number of VariableLabels in Desc (minus any curried labels).
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the GaugeVec example.
-func (v *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) {
-	metric, err := v.metricVec.getMetricWithLabelValues(lvs...)
-	if metric != nil {
-		return metric.(Counter), err
-	}
-	return nil, err
-}
-
-// GetMetricWith returns the Counter for the given Labels map (the label names
-// must match those of the VariableLabels in Desc). If that label map is
-// accessed for the first time, a new Counter is created. Implications of
-// creating a Counter without using it and keeping the Counter for later use are
-// the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc (minus any curried labels).
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (v *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
-	metric, err := v.metricVec.getMetricWith(labels)
-	if metric != nil {
-		return metric.(Counter), err
-	}
-	return nil, err
-}
-
-// WithLabelValues works as GetMetricWithLabelValues, but panics where
-// GetMetricWithLabelValues would have returned an error. Not returning an
-// error allows shortcuts like
-//     myVec.WithLabelValues("404", "GET").Add(42)
-func (v *CounterVec) WithLabelValues(lvs ...string) Counter {
-	c, err := v.GetMetricWithLabelValues(lvs...)
-	if err != nil {
-		panic(err)
-	}
-	return c
-}
-
-// With works as GetMetricWith, but panics where GetMetricWithLabels would have
-// returned an error. Not returning an error allows shortcuts like
-//     myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42)
-func (v *CounterVec) With(labels Labels) Counter {
-	c, err := v.GetMetricWith(labels)
-	if err != nil {
-		panic(err)
-	}
-	return c
-}
-
-// CurryWith returns a vector curried with the provided labels, i.e. the
-// returned vector has those labels pre-set for all labeled operations performed
-// on it. The cardinality of the curried vector is reduced accordingly. The
-// order of the remaining labels stays the same (just with the curried labels
-// taken out of the sequence – which is relevant for the
-// (GetMetric)WithLabelValues methods). It is possible to curry a curried
-// vector, but only with labels not yet used for currying before.
-//
-// The metrics contained in the CounterVec are shared between the curried and
-// uncurried vectors. They are just accessed differently. Curried and uncurried
-// vectors behave identically in terms of collection. Only one must be
-// registered with a given registry (usually the uncurried version). The Reset
-// method deletes all metrics, even if called on a curried vector.
-func (v *CounterVec) CurryWith(labels Labels) (*CounterVec, error) {
-	vec, err := v.curryWith(labels)
-	if vec != nil {
-		return &CounterVec{vec}, err
-	}
-	return nil, err
-}
-
-// MustCurryWith works as CurryWith but panics where CurryWith would have
-// returned an error.
-func (v *CounterVec) MustCurryWith(labels Labels) *CounterVec {
-	vec, err := v.CurryWith(labels)
-	if err != nil {
-		panic(err)
-	}
-	return vec
-}
-
-// CounterFunc is a Counter whose value is determined at collect time by calling a
-// provided function.
-//
-// To create CounterFunc instances, use NewCounterFunc.
-type CounterFunc interface {
-	Metric
-	Collector
-}
-
-// NewCounterFunc creates a new CounterFunc based on the provided
-// CounterOpts. The value reported is determined by calling the given function
-// from within the Write method. Take into account that metric collection may
-// happen concurrently. If that results in concurrent calls to Write, like in
-// the case where a CounterFunc is directly registered with Prometheus, the
-// provided function must be concurrency-safe. The function should also honor
-// the contract for a Counter (values only go up, not down), but compliance will
-// not be checked.
-func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc {
-	return newValueFunc(NewDesc(
-		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-		opts.Help,
-		nil,
-		opts.ConstLabels,
-	), CounterValue, function)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/desc.go b/vendor/github.com/prometheus/client_golang/prometheus/desc.go
deleted file mode 100644
index 1d034f8..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/desc.go
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2016 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"errors"
-	"fmt"
-	"sort"
-	"strings"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/prometheus/common/model"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-// Desc is the descriptor used by every Prometheus Metric. It is essentially
-// the immutable meta-data of a Metric. The normal Metric implementations
-// included in this package manage their Desc under the hood. Users only have to
-// deal with Desc if they use advanced features like the ExpvarCollector or
-// custom Collectors and Metrics.
-//
-// Descriptors registered with the same registry have to fulfill certain
-// consistency and uniqueness criteria if they share the same fully-qualified
-// name: They must have the same help string and the same label names (aka label
-// dimensions) in each, constLabels and variableLabels, but they must differ in
-// the values of the constLabels.
-//
-// Descriptors that share the same fully-qualified names and the same label
-// values of their constLabels are considered equal.
-//
-// Use NewDesc to create new Desc instances.
-type Desc struct {
-	// fqName has been built from Namespace, Subsystem, and Name.
-	fqName string
-	// help provides some helpful information about this metric.
-	help string
-	// constLabelPairs contains precalculated DTO label pairs based on
-	// the constant labels.
-	constLabelPairs []*dto.LabelPair
-	// VariableLabels contains names of labels for which the metric
-	// maintains variable values.
-	variableLabels []string
-	// id is a hash of the values of the ConstLabels and fqName. This
-	// must be unique among all registered descriptors and can therefore be
-	// used as an identifier of the descriptor.
-	id uint64
-	// dimHash is a hash of the label names (preset and variable) and the
-	// Help string. Each Desc with the same fqName must have the same
-	// dimHash.
-	dimHash uint64
-	// err is an error that occurred during construction. It is reported on
-	// registration time.
-	err error
-}
-
-// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc
-// and will be reported on registration time. variableLabels and constLabels can
-// be nil if no such labels should be set. fqName must not be empty.
-//
-// variableLabels only contain the label names. Their label values are variable
-// and therefore not part of the Desc. (They are managed within the Metric.)
-//
-// For constLabels, the label values are constant. Therefore, they are fully
-// specified in the Desc. See the Collector example for a usage pattern.
-func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *Desc {
-	d := &Desc{
-		fqName:         fqName,
-		help:           help,
-		variableLabels: variableLabels,
-	}
-	if !model.IsValidMetricName(model.LabelValue(fqName)) {
-		d.err = fmt.Errorf("%q is not a valid metric name", fqName)
-		return d
-	}
-	// labelValues contains the label values of const labels (in order of
-	// their sorted label names) plus the fqName (at position 0).
-	labelValues := make([]string, 1, len(constLabels)+1)
-	labelValues[0] = fqName
-	labelNames := make([]string, 0, len(constLabels)+len(variableLabels))
-	labelNameSet := map[string]struct{}{}
-	// First add only the const label names and sort them...
-	for labelName := range constLabels {
-		if !checkLabelName(labelName) {
-			d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName)
-			return d
-		}
-		labelNames = append(labelNames, labelName)
-		labelNameSet[labelName] = struct{}{}
-	}
-	sort.Strings(labelNames)
-	// ... so that we can now add const label values in the order of their names.
-	for _, labelName := range labelNames {
-		labelValues = append(labelValues, constLabels[labelName])
-	}
-	// Validate the const label values. They can't have a wrong cardinality, so
-	// use in len(labelValues) as expectedNumberOfValues.
-	if err := validateLabelValues(labelValues, len(labelValues)); err != nil {
-		d.err = err
-		return d
-	}
-	// Now add the variable label names, but prefix them with something that
-	// cannot be in a regular label name. That prevents matching the label
-	// dimension with a different mix between preset and variable labels.
-	for _, labelName := range variableLabels {
-		if !checkLabelName(labelName) {
-			d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName)
-			return d
-		}
-		labelNames = append(labelNames, "$"+labelName)
-		labelNameSet[labelName] = struct{}{}
-	}
-	if len(labelNames) != len(labelNameSet) {
-		d.err = errors.New("duplicate label names")
-		return d
-	}
-
-	vh := hashNew()
-	for _, val := range labelValues {
-		vh = hashAdd(vh, val)
-		vh = hashAddByte(vh, separatorByte)
-	}
-	d.id = vh
-	// Sort labelNames so that order doesn't matter for the hash.
-	sort.Strings(labelNames)
-	// Now hash together (in this order) the help string and the sorted
-	// label names.
-	lh := hashNew()
-	lh = hashAdd(lh, help)
-	lh = hashAddByte(lh, separatorByte)
-	for _, labelName := range labelNames {
-		lh = hashAdd(lh, labelName)
-		lh = hashAddByte(lh, separatorByte)
-	}
-	d.dimHash = lh
-
-	d.constLabelPairs = make([]*dto.LabelPair, 0, len(constLabels))
-	for n, v := range constLabels {
-		d.constLabelPairs = append(d.constLabelPairs, &dto.LabelPair{
-			Name:  proto.String(n),
-			Value: proto.String(v),
-		})
-	}
-	sort.Sort(labelPairSorter(d.constLabelPairs))
-	return d
-}
-
-// NewInvalidDesc returns an invalid descriptor, i.e. a descriptor with the
-// provided error set. If a collector returning such a descriptor is registered,
-// registration will fail with the provided error. NewInvalidDesc can be used by
-// a Collector to signal inability to describe itself.
-func NewInvalidDesc(err error) *Desc {
-	return &Desc{
-		err: err,
-	}
-}
-
-func (d *Desc) String() string {
-	lpStrings := make([]string, 0, len(d.constLabelPairs))
-	for _, lp := range d.constLabelPairs {
-		lpStrings = append(
-			lpStrings,
-			fmt.Sprintf("%s=%q", lp.GetName(), lp.GetValue()),
-		)
-	}
-	return fmt.Sprintf(
-		"Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: %v}",
-		d.fqName,
-		d.help,
-		strings.Join(lpStrings, ","),
-		d.variableLabels,
-	)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/doc.go b/vendor/github.com/prometheus/client_golang/prometheus/doc.go
deleted file mode 100644
index 5d9525d..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/doc.go
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package prometheus is the core instrumentation package. It provides metrics
-// primitives to instrument code for monitoring. It also offers a registry for
-// metrics. Sub-packages allow to expose the registered metrics via HTTP
-// (package promhttp) or push them to a Pushgateway (package push). There is
-// also a sub-package promauto, which provides metrics constructors with
-// automatic registration.
-//
-// All exported functions and methods are safe to be used concurrently unless
-// specified otherwise.
-//
-// A Basic Example
-//
-// As a starting point, a very basic usage example:
-//
-//    package main
-//
-//    import (
-//    	"log"
-//    	"net/http"
-//
-//    	"github.com/prometheus/client_golang/prometheus"
-//    	"github.com/prometheus/client_golang/prometheus/promhttp"
-//    )
-//
-//    var (
-//    	cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{
-//    		Name: "cpu_temperature_celsius",
-//    		Help: "Current temperature of the CPU.",
-//    	})
-//    	hdFailures = prometheus.NewCounterVec(
-//    		prometheus.CounterOpts{
-//    			Name: "hd_errors_total",
-//    			Help: "Number of hard-disk errors.",
-//    		},
-//    		[]string{"device"},
-//    	)
-//    )
-//
-//    func init() {
-//    	// Metrics have to be registered to be exposed:
-//    	prometheus.MustRegister(cpuTemp)
-//    	prometheus.MustRegister(hdFailures)
-//    }
-//
-//    func main() {
-//    	cpuTemp.Set(65.3)
-//    	hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc()
-//
-//    	// The Handler function provides a default handler to expose metrics
-//    	// via an HTTP server. "/metrics" is the usual endpoint for that.
-//    	http.Handle("/metrics", promhttp.Handler())
-//    	log.Fatal(http.ListenAndServe(":8080", nil))
-//    }
-//
-//
-// This is a complete program that exports two metrics, a Gauge and a Counter,
-// the latter with a label attached to turn it into a (one-dimensional) vector.
-//
-// Metrics
-//
-// The number of exported identifiers in this package might appear a bit
-// overwhelming. However, in addition to the basic plumbing shown in the example
-// above, you only need to understand the different metric types and their
-// vector versions for basic usage. Furthermore, if you are not concerned with
-// fine-grained control of when and how to register metrics with the registry,
-// have a look at the promauto package, which will effectively allow you to
-// ignore registration altogether in simple cases.
-//
-// Above, you have already touched the Counter and the Gauge. There are two more
-// advanced metric types: the Summary and Histogram. A more thorough description
-// of those four metric types can be found in the Prometheus docs:
-// https://prometheus.io/docs/concepts/metric_types/
-//
-// A fifth "type" of metric is Untyped. It behaves like a Gauge, but signals the
-// Prometheus server not to assume anything about its type.
-//
-// In addition to the fundamental metric types Gauge, Counter, Summary,
-// Histogram, and Untyped, a very important part of the Prometheus data model is
-// the partitioning of samples along dimensions called labels, which results in
-// metric vectors. The fundamental types are GaugeVec, CounterVec, SummaryVec,
-// HistogramVec, and UntypedVec.
-//
-// While only the fundamental metric types implement the Metric interface, both
-// the metrics and their vector versions implement the Collector interface. A
-// Collector manages the collection of a number of Metrics, but for convenience,
-// a Metric can also “collect itself”. Note that Gauge, Counter, Summary,
-// Histogram, and Untyped are interfaces themselves while GaugeVec, CounterVec,
-// SummaryVec, HistogramVec, and UntypedVec are not.
-//
-// To create instances of Metrics and their vector versions, you need a suitable
-// …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, HistogramOpts, or
-// UntypedOpts.
-//
-// Custom Collectors and constant Metrics
-//
-// While you could create your own implementations of Metric, most likely you
-// will only ever implement the Collector interface on your own. At a first
-// glance, a custom Collector seems handy to bundle Metrics for common
-// registration (with the prime example of the different metric vectors above,
-// which bundle all the metrics of the same name but with different labels).
-//
-// There is a more involved use case, too: If you already have metrics
-// available, created outside of the Prometheus context, you don't need the
-// interface of the various Metric types. You essentially want to mirror the
-// existing numbers into Prometheus Metrics during collection. An own
-// implementation of the Collector interface is perfect for that. You can create
-// Metric instances “on the fly” using NewConstMetric, NewConstHistogram, and
-// NewConstSummary (and their respective Must… versions). That will happen in
-// the Collect method. The Describe method has to return separate Desc
-// instances, representative of the “throw-away” metrics to be created later.
-// NewDesc comes in handy to create those Desc instances. Alternatively, you
-// could return no Desc at all, which will marke the Collector “unchecked”.  No
-// checks are porformed at registration time, but metric consistency will still
-// be ensured at scrape time, i.e. any inconsistencies will lead to scrape
-// errors. Thus, with unchecked Collectors, the responsibility to not collect
-// metrics that lead to inconsistencies in the total scrape result lies with the
-// implementer of the Collector. While this is not a desirable state, it is
-// sometimes necessary. The typical use case is a situatios where the exact
-// metrics to be returned by a Collector cannot be predicted at registration
-// time, but the implementer has sufficient knowledge of the whole system to
-// guarantee metric consistency.
-//
-// The Collector example illustrates the use case. You can also look at the
-// source code of the processCollector (mirroring process metrics), the
-// goCollector (mirroring Go metrics), or the expvarCollector (mirroring expvar
-// metrics) as examples that are used in this package itself.
-//
-// If you just need to call a function to get a single float value to collect as
-// a metric, GaugeFunc, CounterFunc, or UntypedFunc might be interesting
-// shortcuts.
-//
-// Advanced Uses of the Registry
-//
-// While MustRegister is the by far most common way of registering a Collector,
-// sometimes you might want to handle the errors the registration might cause.
-// As suggested by the name, MustRegister panics if an error occurs. With the
-// Register function, the error is returned and can be handled.
-//
-// An error is returned if the registered Collector is incompatible or
-// inconsistent with already registered metrics. The registry aims for
-// consistency of the collected metrics according to the Prometheus data model.
-// Inconsistencies are ideally detected at registration time, not at collect
-// time. The former will usually be detected at start-up time of a program,
-// while the latter will only happen at scrape time, possibly not even on the
-// first scrape if the inconsistency only becomes relevant later. That is the
-// main reason why a Collector and a Metric have to describe themselves to the
-// registry.
-//
-// So far, everything we did operated on the so-called default registry, as it
-// can be found in the global DefaultRegisterer variable. With NewRegistry, you
-// can create a custom registry, or you can even implement the Registerer or
-// Gatherer interfaces yourself. The methods Register and Unregister work in the
-// same way on a custom registry as the global functions Register and Unregister
-// on the default registry.
-//
-// There are a number of uses for custom registries: You can use registries with
-// special properties, see NewPedanticRegistry. You can avoid global state, as
-// it is imposed by the DefaultRegisterer. You can use multiple registries at
-// the same time to expose different metrics in different ways.  You can use
-// separate registries for testing purposes.
-//
-// Also note that the DefaultRegisterer comes registered with a Collector for Go
-// runtime metrics (via NewGoCollector) and a Collector for process metrics (via
-// NewProcessCollector). With a custom registry, you are in control and decide
-// yourself about the Collectors to register.
-//
-// HTTP Exposition
-//
-// The Registry implements the Gatherer interface. The caller of the Gather
-// method can then expose the gathered metrics in some way. Usually, the metrics
-// are served via HTTP on the /metrics endpoint. That's happening in the example
-// above. The tools to expose metrics via HTTP are in the promhttp sub-package.
-// (The top-level functions in the prometheus package are deprecated.)
-//
-// Pushing to the Pushgateway
-//
-// Function for pushing to the Pushgateway can be found in the push sub-package.
-//
-// Graphite Bridge
-//
-// Functions and examples to push metrics from a Gatherer to Graphite can be
-// found in the graphite sub-package.
-//
-// Other Means of Exposition
-//
-// More ways of exposing metrics can easily be added by following the approaches
-// of the existing implementations.
-package prometheus
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go
deleted file mode 100644
index 18a99d5..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"encoding/json"
-	"expvar"
-)
-
-type expvarCollector struct {
-	exports map[string]*Desc
-}
-
-// NewExpvarCollector returns a newly allocated expvar Collector that still has
-// to be registered with a Prometheus registry.
-//
-// An expvar Collector collects metrics from the expvar interface. It provides a
-// quick way to expose numeric values that are already exported via expvar as
-// Prometheus metrics. Note that the data models of expvar and Prometheus are
-// fundamentally different, and that the expvar Collector is inherently slower
-// than native Prometheus metrics. Thus, the expvar Collector is probably great
-// for experiments and prototying, but you should seriously consider a more
-// direct implementation of Prometheus metrics for monitoring production
-// systems.
-//
-// The exports map has the following meaning:
-//
-// The keys in the map correspond to expvar keys, i.e. for every expvar key you
-// want to export as Prometheus metric, you need an entry in the exports
-// map. The descriptor mapped to each key describes how to export the expvar
-// value. It defines the name and the help string of the Prometheus metric
-// proxying the expvar value. The type will always be Untyped.
-//
-// For descriptors without variable labels, the expvar value must be a number or
-// a bool. The number is then directly exported as the Prometheus sample
-// value. (For a bool, 'false' translates to 0 and 'true' to 1). Expvar values
-// that are not numbers or bools are silently ignored.
-//
-// If the descriptor has one variable label, the expvar value must be an expvar
-// map. The keys in the expvar map become the various values of the one
-// Prometheus label. The values in the expvar map must be numbers or bools again
-// as above.
-//
-// For descriptors with more than one variable label, the expvar must be a
-// nested expvar map, i.e. where the values of the topmost map are maps again
-// etc. until a depth is reached that corresponds to the number of labels. The
-// leaves of that structure must be numbers or bools as above to serve as the
-// sample values.
-//
-// Anything that does not fit into the scheme above is silently ignored.
-func NewExpvarCollector(exports map[string]*Desc) Collector {
-	return &expvarCollector{
-		exports: exports,
-	}
-}
-
-// Describe implements Collector.
-func (e *expvarCollector) Describe(ch chan<- *Desc) {
-	for _, desc := range e.exports {
-		ch <- desc
-	}
-}
-
-// Collect implements Collector.
-func (e *expvarCollector) Collect(ch chan<- Metric) {
-	for name, desc := range e.exports {
-		var m Metric
-		expVar := expvar.Get(name)
-		if expVar == nil {
-			continue
-		}
-		var v interface{}
-		labels := make([]string, len(desc.variableLabels))
-		if err := json.Unmarshal([]byte(expVar.String()), &v); err != nil {
-			ch <- NewInvalidMetric(desc, err)
-			continue
-		}
-		var processValue func(v interface{}, i int)
-		processValue = func(v interface{}, i int) {
-			if i >= len(labels) {
-				copiedLabels := append(make([]string, 0, len(labels)), labels...)
-				switch v := v.(type) {
-				case float64:
-					m = MustNewConstMetric(desc, UntypedValue, v, copiedLabels...)
-				case bool:
-					if v {
-						m = MustNewConstMetric(desc, UntypedValue, 1, copiedLabels...)
-					} else {
-						m = MustNewConstMetric(desc, UntypedValue, 0, copiedLabels...)
-					}
-				default:
-					return
-				}
-				ch <- m
-				return
-			}
-			vm, ok := v.(map[string]interface{})
-			if !ok {
-				return
-			}
-			for lv, val := range vm {
-				labels[i] = lv
-				processValue(val, i+1)
-			}
-		}
-		processValue(v, 0)
-	}
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/fnv.go b/vendor/github.com/prometheus/client_golang/prometheus/fnv.go
deleted file mode 100644
index 3d383a7..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/fnv.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-// Inline and byte-free variant of hash/fnv's fnv64a.
-
-const (
-	offset64 = 14695981039346656037
-	prime64  = 1099511628211
-)
-
-// hashNew initializies a new fnv64a hash value.
-func hashNew() uint64 {
-	return offset64
-}
-
-// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
-func hashAdd(h uint64, s string) uint64 {
-	for i := 0; i < len(s); i++ {
-		h ^= uint64(s[i])
-		h *= prime64
-	}
-	return h
-}
-
-// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.
-func hashAddByte(h uint64, b byte) uint64 {
-	h ^= uint64(b)
-	h *= prime64
-	return h
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go
deleted file mode 100644
index 71d406b..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"math"
-	"sync/atomic"
-	"time"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-// Gauge is a Metric that represents a single numerical value that can
-// arbitrarily go up and down.
-//
-// A Gauge is typically used for measured values like temperatures or current
-// memory usage, but also "counts" that can go up and down, like the number of
-// running goroutines.
-//
-// To create Gauge instances, use NewGauge.
-type Gauge interface {
-	Metric
-	Collector
-
-	// Set sets the Gauge to an arbitrary value.
-	Set(float64)
-	// Inc increments the Gauge by 1. Use Add to increment it by arbitrary
-	// values.
-	Inc()
-	// Dec decrements the Gauge by 1. Use Sub to decrement it by arbitrary
-	// values.
-	Dec()
-	// Add adds the given value to the Gauge. (The value can be negative,
-	// resulting in a decrease of the Gauge.)
-	Add(float64)
-	// Sub subtracts the given value from the Gauge. (The value can be
-	// negative, resulting in an increase of the Gauge.)
-	Sub(float64)
-
-	// SetToCurrentTime sets the Gauge to the current Unix time in seconds.
-	SetToCurrentTime()
-}
-
-// GaugeOpts is an alias for Opts. See there for doc comments.
-type GaugeOpts Opts
-
-// NewGauge creates a new Gauge based on the provided GaugeOpts.
-//
-// The returned implementation is optimized for a fast Set method. If you have a
-// choice for managing the value of a Gauge via Set vs. Inc/Dec/Add/Sub, pick
-// the former. For example, the Inc method of the returned Gauge is slower than
-// the Inc method of a Counter returned by NewCounter. This matches the typical
-// scenarios for Gauges and Counters, where the former tends to be Set-heavy and
-// the latter Inc-heavy.
-func NewGauge(opts GaugeOpts) Gauge {
-	desc := NewDesc(
-		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-		opts.Help,
-		nil,
-		opts.ConstLabels,
-	)
-	result := &gauge{desc: desc, labelPairs: desc.constLabelPairs}
-	result.init(result) // Init self-collection.
-	return result
-}
-
-type gauge struct {
-	// valBits contains the bits of the represented float64 value. It has
-	// to go first in the struct to guarantee alignment for atomic
-	// operations.  http://golang.org/pkg/sync/atomic/#pkg-note-BUG
-	valBits uint64
-
-	selfCollector
-
-	desc       *Desc
-	labelPairs []*dto.LabelPair
-}
-
-func (g *gauge) Desc() *Desc {
-	return g.desc
-}
-
-func (g *gauge) Set(val float64) {
-	atomic.StoreUint64(&g.valBits, math.Float64bits(val))
-}
-
-func (g *gauge) SetToCurrentTime() {
-	g.Set(float64(time.Now().UnixNano()) / 1e9)
-}
-
-func (g *gauge) Inc() {
-	g.Add(1)
-}
-
-func (g *gauge) Dec() {
-	g.Add(-1)
-}
-
-func (g *gauge) Add(val float64) {
-	for {
-		oldBits := atomic.LoadUint64(&g.valBits)
-		newBits := math.Float64bits(math.Float64frombits(oldBits) + val)
-		if atomic.CompareAndSwapUint64(&g.valBits, oldBits, newBits) {
-			return
-		}
-	}
-}
-
-func (g *gauge) Sub(val float64) {
-	g.Add(val * -1)
-}
-
-func (g *gauge) Write(out *dto.Metric) error {
-	val := math.Float64frombits(atomic.LoadUint64(&g.valBits))
-	return populateMetric(GaugeValue, val, g.labelPairs, out)
-}
-
-// GaugeVec is a Collector that bundles a set of Gauges that all share the same
-// Desc, but have different values for their variable labels. This is used if
-// you want to count the same thing partitioned by various dimensions
-// (e.g. number of operations queued, partitioned by user and operation
-// type). Create instances with NewGaugeVec.
-type GaugeVec struct {
-	*metricVec
-}
-
-// NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and
-// partitioned by the given label names.
-func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
-	desc := NewDesc(
-		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-		opts.Help,
-		labelNames,
-		opts.ConstLabels,
-	)
-	return &GaugeVec{
-		metricVec: newMetricVec(desc, func(lvs ...string) Metric {
-			if len(lvs) != len(desc.variableLabels) {
-				panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, lvs))
-			}
-			result := &gauge{desc: desc, labelPairs: makeLabelPairs(desc, lvs)}
-			result.init(result) // Init self-collection.
-			return result
-		}),
-	}
-}
-
-// GetMetricWithLabelValues returns the Gauge for the given slice of label
-// values (same order as the VariableLabels in Desc). If that combination of
-// label values is accessed for the first time, a new Gauge is created.
-//
-// It is possible to call this method without using the returned Gauge to only
-// create the new Gauge but leave it at its starting value 0. See also the
-// SummaryVec example.
-//
-// Keeping the Gauge for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Gauge from the GaugeVec. In that case, the
-// Gauge will still exist, but it will not be exported anymore, even if a
-// Gauge with the same label values is created later. See also the CounterVec
-// example.
-//
-// An error is returned if the number of label values is not the same as the
-// number of VariableLabels in Desc (minus any curried labels).
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-func (v *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) {
-	metric, err := v.metricVec.getMetricWithLabelValues(lvs...)
-	if metric != nil {
-		return metric.(Gauge), err
-	}
-	return nil, err
-}
-
-// GetMetricWith returns the Gauge for the given Labels map (the label names
-// must match those of the VariableLabels in Desc). If that label map is
-// accessed for the first time, a new Gauge is created. Implications of
-// creating a Gauge without using it and keeping the Gauge for later use are
-// the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc (minus any curried labels).
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (v *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {
-	metric, err := v.metricVec.getMetricWith(labels)
-	if metric != nil {
-		return metric.(Gauge), err
-	}
-	return nil, err
-}
-
-// WithLabelValues works as GetMetricWithLabelValues, but panics where
-// GetMetricWithLabelValues would have returned an error. Not returning an
-// error allows shortcuts like
-//     myVec.WithLabelValues("404", "GET").Add(42)
-func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge {
-	g, err := v.GetMetricWithLabelValues(lvs...)
-	if err != nil {
-		panic(err)
-	}
-	return g
-}
-
-// With works as GetMetricWith, but panics where GetMetricWithLabels would have
-// returned an error. Not returning an error allows shortcuts like
-//     myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42)
-func (v *GaugeVec) With(labels Labels) Gauge {
-	g, err := v.GetMetricWith(labels)
-	if err != nil {
-		panic(err)
-	}
-	return g
-}
-
-// CurryWith returns a vector curried with the provided labels, i.e. the
-// returned vector has those labels pre-set for all labeled operations performed
-// on it. The cardinality of the curried vector is reduced accordingly. The
-// order of the remaining labels stays the same (just with the curried labels
-// taken out of the sequence – which is relevant for the
-// (GetMetric)WithLabelValues methods). It is possible to curry a curried
-// vector, but only with labels not yet used for currying before.
-//
-// The metrics contained in the GaugeVec are shared between the curried and
-// uncurried vectors. They are just accessed differently. Curried and uncurried
-// vectors behave identically in terms of collection. Only one must be
-// registered with a given registry (usually the uncurried version). The Reset
-// method deletes all metrics, even if called on a curried vector.
-func (v *GaugeVec) CurryWith(labels Labels) (*GaugeVec, error) {
-	vec, err := v.curryWith(labels)
-	if vec != nil {
-		return &GaugeVec{vec}, err
-	}
-	return nil, err
-}
-
-// MustCurryWith works as CurryWith but panics where CurryWith would have
-// returned an error.
-func (v *GaugeVec) MustCurryWith(labels Labels) *GaugeVec {
-	vec, err := v.CurryWith(labels)
-	if err != nil {
-		panic(err)
-	}
-	return vec
-}
-
-// GaugeFunc is a Gauge whose value is determined at collect time by calling a
-// provided function.
-//
-// To create GaugeFunc instances, use NewGaugeFunc.
-type GaugeFunc interface {
-	Metric
-	Collector
-}
-
-// NewGaugeFunc creates a new GaugeFunc based on the provided GaugeOpts. The
-// value reported is determined by calling the given function from within the
-// Write method. Take into account that metric collection may happen
-// concurrently. If that results in concurrent calls to Write, like in the case
-// where a GaugeFunc is directly registered with Prometheus, the provided
-// function must be concurrency-safe.
-func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc {
-	return newValueFunc(NewDesc(
-		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-		opts.Help,
-		nil,
-		opts.ConstLabels,
-	), GaugeValue, function)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
deleted file mode 100644
index ba3b933..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"fmt"
-	"runtime"
-	"runtime/debug"
-	"time"
-)
-
-type goCollector struct {
-	goroutinesDesc *Desc
-	threadsDesc    *Desc
-	gcDesc         *Desc
-	goInfoDesc     *Desc
-
-	// metrics to describe and collect
-	metrics memStatsMetrics
-}
-
-// NewGoCollector returns a collector which exports metrics about the current Go
-// process. This includes memory stats. To collect those, runtime.ReadMemStats
-// is called. This causes a stop-the-world, which is very short with Go1.9+
-// (~25µs). However, with older Go versions, the stop-the-world duration depends
-// on the heap size and can be quite significant (~1.7 ms/GiB as per
-// https://go-review.googlesource.com/c/go/+/34937).
-func NewGoCollector() Collector {
-	return &goCollector{
-		goroutinesDesc: NewDesc(
-			"go_goroutines",
-			"Number of goroutines that currently exist.",
-			nil, nil),
-		threadsDesc: NewDesc(
-			"go_threads",
-			"Number of OS threads created.",
-			nil, nil),
-		gcDesc: NewDesc(
-			"go_gc_duration_seconds",
-			"A summary of the GC invocation durations.",
-			nil, nil),
-		goInfoDesc: NewDesc(
-			"go_info",
-			"Information about the Go environment.",
-			nil, Labels{"version": runtime.Version()}),
-		metrics: memStatsMetrics{
-			{
-				desc: NewDesc(
-					memstatNamespace("alloc_bytes"),
-					"Number of bytes allocated and still in use.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.Alloc) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("alloc_bytes_total"),
-					"Total number of bytes allocated, even if freed.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.TotalAlloc) },
-				valType: CounterValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("sys_bytes"),
-					"Number of bytes obtained from system.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.Sys) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("lookups_total"),
-					"Total number of pointer lookups.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.Lookups) },
-				valType: CounterValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("mallocs_total"),
-					"Total number of mallocs.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.Mallocs) },
-				valType: CounterValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("frees_total"),
-					"Total number of frees.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.Frees) },
-				valType: CounterValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("heap_alloc_bytes"),
-					"Number of heap bytes allocated and still in use.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapAlloc) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("heap_sys_bytes"),
-					"Number of heap bytes obtained from system.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapSys) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("heap_idle_bytes"),
-					"Number of heap bytes waiting to be used.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapIdle) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("heap_inuse_bytes"),
-					"Number of heap bytes that are in use.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapInuse) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("heap_released_bytes"),
-					"Number of heap bytes released to OS.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("heap_objects"),
-					"Number of allocated objects.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapObjects) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("stack_inuse_bytes"),
-					"Number of bytes in use by the stack allocator.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.StackInuse) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("stack_sys_bytes"),
-					"Number of bytes obtained from system for stack allocator.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.StackSys) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("mspan_inuse_bytes"),
-					"Number of bytes in use by mspan structures.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.MSpanInuse) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("mspan_sys_bytes"),
-					"Number of bytes used for mspan structures obtained from system.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.MSpanSys) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("mcache_inuse_bytes"),
-					"Number of bytes in use by mcache structures.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.MCacheInuse) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("mcache_sys_bytes"),
-					"Number of bytes used for mcache structures obtained from system.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.MCacheSys) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("buck_hash_sys_bytes"),
-					"Number of bytes used by the profiling bucket hash table.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.BuckHashSys) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("gc_sys_bytes"),
-					"Number of bytes used for garbage collection system metadata.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.GCSys) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("other_sys_bytes"),
-					"Number of bytes used for other system allocations.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.OtherSys) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("next_gc_bytes"),
-					"Number of heap bytes when next garbage collection will take place.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("last_gc_time_seconds"),
-					"Number of seconds since 1970 of last garbage collection.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.LastGC) / 1e9 },
-				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("gc_cpu_fraction"),
-					"The fraction of this program's available CPU time used by the GC since the program started.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction },
-				valType: GaugeValue,
-			},
-		},
-	}
-}
-
-func memstatNamespace(s string) string {
-	return fmt.Sprintf("go_memstats_%s", s)
-}
-
-// Describe returns all descriptions of the collector.
-func (c *goCollector) Describe(ch chan<- *Desc) {
-	ch <- c.goroutinesDesc
-	ch <- c.threadsDesc
-	ch <- c.gcDesc
-	ch <- c.goInfoDesc
-	for _, i := range c.metrics {
-		ch <- i.desc
-	}
-}
-
-// Collect returns the current state of all metrics of the collector.
-func (c *goCollector) Collect(ch chan<- Metric) {
-	ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine()))
-	n, _ := runtime.ThreadCreateProfile(nil)
-	ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, float64(n))
-
-	var stats debug.GCStats
-	stats.PauseQuantiles = make([]time.Duration, 5)
-	debug.ReadGCStats(&stats)
-
-	quantiles := make(map[float64]float64)
-	for idx, pq := range stats.PauseQuantiles[1:] {
-		quantiles[float64(idx+1)/float64(len(stats.PauseQuantiles)-1)] = pq.Seconds()
-	}
-	quantiles[0.0] = stats.PauseQuantiles[0].Seconds()
-	ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), stats.PauseTotal.Seconds(), quantiles)
-
-	ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1)
-
-	ms := &runtime.MemStats{}
-	runtime.ReadMemStats(ms)
-	for _, i := range c.metrics {
-		ch <- MustNewConstMetric(i.desc, i.valType, i.eval(ms))
-	}
-}
-
-// memStatsMetrics provide description, value, and value type for memstat metrics.
-type memStatsMetrics []struct {
-	desc    *Desc
-	eval    func(*runtime.MemStats) float64
-	valType ValueType
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
deleted file mode 100644
index f88da70..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
+++ /dev/null
@@ -1,614 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"fmt"
-	"math"
-	"runtime"
-	"sort"
-	"sync"
-	"sync/atomic"
-
-	"github.com/golang/protobuf/proto"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-// A Histogram counts individual observations from an event or sample stream in
-// configurable buckets. Similar to a summary, it also provides a sum of
-// observations and an observation count.
-//
-// On the Prometheus server, quantiles can be calculated from a Histogram using
-// the histogram_quantile function in the query language.
-//
-// Note that Histograms, in contrast to Summaries, can be aggregated with the
-// Prometheus query language (see the documentation for detailed
-// procedures). However, Histograms require the user to pre-define suitable
-// buckets, and they are in general less accurate. The Observe method of a
-// Histogram has a very low performance overhead in comparison with the Observe
-// method of a Summary.
-//
-// To create Histogram instances, use NewHistogram.
-type Histogram interface {
-	Metric
-	Collector
-
-	// Observe adds a single observation to the histogram.
-	Observe(float64)
-}
-
-// bucketLabel is used for the label that defines the upper bound of a
-// bucket of a histogram ("le" -> "less or equal").
-const bucketLabel = "le"
-
-// DefBuckets are the default Histogram buckets. The default buckets are
-// tailored to broadly measure the response time (in seconds) of a network
-// service. Most likely, however, you will be required to define buckets
-// customized to your use case.
-var (
-	DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}
-
-	errBucketLabelNotAllowed = fmt.Errorf(
-		"%q is not allowed as label name in histograms", bucketLabel,
-	)
-)
-
-// LinearBuckets creates 'count' buckets, each 'width' wide, where the lowest
-// bucket has an upper bound of 'start'. The final +Inf bucket is not counted
-// and not included in the returned slice. The returned slice is meant to be
-// used for the Buckets field of HistogramOpts.
-//
-// The function panics if 'count' is zero or negative.
-func LinearBuckets(start, width float64, count int) []float64 {
-	if count < 1 {
-		panic("LinearBuckets needs a positive count")
-	}
-	buckets := make([]float64, count)
-	for i := range buckets {
-		buckets[i] = start
-		start += width
-	}
-	return buckets
-}
-
-// ExponentialBuckets creates 'count' buckets, where the lowest bucket has an
-// upper bound of 'start' and each following bucket's upper bound is 'factor'
-// times the previous bucket's upper bound. The final +Inf bucket is not counted
-// and not included in the returned slice. The returned slice is meant to be
-// used for the Buckets field of HistogramOpts.
-//
-// The function panics if 'count' is 0 or negative, if 'start' is 0 or negative,
-// or if 'factor' is less than or equal 1.
-func ExponentialBuckets(start, factor float64, count int) []float64 {
-	if count < 1 {
-		panic("ExponentialBuckets needs a positive count")
-	}
-	if start <= 0 {
-		panic("ExponentialBuckets needs a positive start value")
-	}
-	if factor <= 1 {
-		panic("ExponentialBuckets needs a factor greater than 1")
-	}
-	buckets := make([]float64, count)
-	for i := range buckets {
-		buckets[i] = start
-		start *= factor
-	}
-	return buckets
-}
-
-// HistogramOpts bundles the options for creating a Histogram metric. It is
-// mandatory to set Name to a non-empty string. All other fields are optional
-// and can safely be left at their zero value, although it is strongly
-// encouraged to set a Help string.
-type HistogramOpts struct {
-	// Namespace, Subsystem, and Name are components of the fully-qualified
-	// name of the Histogram (created by joining these components with
-	// "_"). Only Name is mandatory, the others merely help structuring the
-	// name. Note that the fully-qualified name of the Histogram must be a
-	// valid Prometheus metric name.
-	Namespace string
-	Subsystem string
-	Name      string
-
-	// Help provides information about this Histogram.
-	//
-	// Metrics with the same fully-qualified name must have the same Help
-	// string.
-	Help string
-
-	// ConstLabels are used to attach fixed labels to this metric. Metrics
-	// with the same fully-qualified name must have the same label names in
-	// their ConstLabels.
-	//
-	// ConstLabels are only used rarely. In particular, do not use them to
-	// attach the same labels to all your metrics. Those use cases are
-	// better covered by target labels set by the scraping Prometheus
-	// server, or by one specific metric (e.g. a build_info or a
-	// machine_role metric). See also
-	// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels,-not-static-scraped-labels
-	ConstLabels Labels
-
-	// Buckets defines the buckets into which observations are counted. Each
-	// element in the slice is the upper inclusive bound of a bucket. The
-	// values must be sorted in strictly increasing order. There is no need
-	// to add a highest bucket with +Inf bound, it will be added
-	// implicitly. The default value is DefBuckets.
-	Buckets []float64
-}
-
-// NewHistogram creates a new Histogram based on the provided HistogramOpts. It
-// panics if the buckets in HistogramOpts are not in strictly increasing order.
-func NewHistogram(opts HistogramOpts) Histogram {
-	return newHistogram(
-		NewDesc(
-			BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-			opts.Help,
-			nil,
-			opts.ConstLabels,
-		),
-		opts,
-	)
-}
-
-func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogram {
-	if len(desc.variableLabels) != len(labelValues) {
-		panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, labelValues))
-	}
-
-	for _, n := range desc.variableLabels {
-		if n == bucketLabel {
-			panic(errBucketLabelNotAllowed)
-		}
-	}
-	for _, lp := range desc.constLabelPairs {
-		if lp.GetName() == bucketLabel {
-			panic(errBucketLabelNotAllowed)
-		}
-	}
-
-	if len(opts.Buckets) == 0 {
-		opts.Buckets = DefBuckets
-	}
-
-	h := &histogram{
-		desc:        desc,
-		upperBounds: opts.Buckets,
-		labelPairs:  makeLabelPairs(desc, labelValues),
-		counts:      [2]*histogramCounts{&histogramCounts{}, &histogramCounts{}},
-	}
-	for i, upperBound := range h.upperBounds {
-		if i < len(h.upperBounds)-1 {
-			if upperBound >= h.upperBounds[i+1] {
-				panic(fmt.Errorf(
-					"histogram buckets must be in increasing order: %f >= %f",
-					upperBound, h.upperBounds[i+1],
-				))
-			}
-		} else {
-			if math.IsInf(upperBound, +1) {
-				// The +Inf bucket is implicit. Remove it here.
-				h.upperBounds = h.upperBounds[:i]
-			}
-		}
-	}
-	// Finally we know the final length of h.upperBounds and can make counts
-	// for both states:
-	h.counts[0].buckets = make([]uint64, len(h.upperBounds))
-	h.counts[1].buckets = make([]uint64, len(h.upperBounds))
-
-	h.init(h) // Init self-collection.
-	return h
-}
-
-type histogramCounts struct {
-	// sumBits contains the bits of the float64 representing the sum of all
-	// observations. sumBits and count have to go first in the struct to
-	// guarantee alignment for atomic operations.
-	// http://golang.org/pkg/sync/atomic/#pkg-note-BUG
-	sumBits uint64
-	count   uint64
-	buckets []uint64
-}
-
-type histogram struct {
-	// countAndHotIdx is a complicated one. For lock-free yet atomic
-	// observations, we need to save the total count of observations again,
-	// combined with the index of the currently-hot counts struct, so that
-	// we can perform the operation on both values atomically. The least
-	// significant bit defines the hot counts struct. The remaining 63 bits
-	// represent the total count of observations. This happens under the
-	// assumption that the 63bit count will never overflow. Rationale: An
-	// observations takes about 30ns. Let's assume it could happen in
-	// 10ns. Overflowing the counter will then take at least (2^63)*10ns,
-	// which is about 3000 years.
-	//
-	// This has to be first in the struct for 64bit alignment. See
-	// http://golang.org/pkg/sync/atomic/#pkg-note-BUG
-	countAndHotIdx uint64
-
-	selfCollector
-	desc     *Desc
-	writeMtx sync.Mutex // Only used in the Write method.
-
-	upperBounds []float64
-
-	// Two counts, one is "hot" for lock-free observations, the other is
-	// "cold" for writing out a dto.Metric. It has to be an array of
-	// pointers to guarantee 64bit alignment of the histogramCounts, see
-	// http://golang.org/pkg/sync/atomic/#pkg-note-BUG.
-	counts [2]*histogramCounts
-	hotIdx int // Index of currently-hot counts. Only used within Write.
-
-	labelPairs []*dto.LabelPair
-}
-
-func (h *histogram) Desc() *Desc {
-	return h.desc
-}
-
-func (h *histogram) Observe(v float64) {
-	// TODO(beorn7): For small numbers of buckets (<30), a linear search is
-	// slightly faster than the binary search. If we really care, we could
-	// switch from one search strategy to the other depending on the number
-	// of buckets.
-	//
-	// Microbenchmarks (BenchmarkHistogramNoLabels):
-	// 11 buckets: 38.3 ns/op linear - binary 48.7 ns/op
-	// 100 buckets: 78.1 ns/op linear - binary 54.9 ns/op
-	// 300 buckets: 154 ns/op linear - binary 61.6 ns/op
-	i := sort.SearchFloat64s(h.upperBounds, v)
-
-	// We increment h.countAndHotIdx by 2 so that the counter in the upper
-	// 63 bits gets incremented by 1. At the same time, we get the new value
-	// back, which we can use to find the currently-hot counts.
-	n := atomic.AddUint64(&h.countAndHotIdx, 2)
-	hotCounts := h.counts[n%2]
-
-	if i < len(h.upperBounds) {
-		atomic.AddUint64(&hotCounts.buckets[i], 1)
-	}
-	for {
-		oldBits := atomic.LoadUint64(&hotCounts.sumBits)
-		newBits := math.Float64bits(math.Float64frombits(oldBits) + v)
-		if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
-			break
-		}
-	}
-	// Increment count last as we take it as a signal that the observation
-	// is complete.
-	atomic.AddUint64(&hotCounts.count, 1)
-}
-
-func (h *histogram) Write(out *dto.Metric) error {
-	var (
-		his                   = &dto.Histogram{}
-		buckets               = make([]*dto.Bucket, len(h.upperBounds))
-		hotCounts, coldCounts *histogramCounts
-		count                 uint64
-	)
-
-	// For simplicity, we mutex the rest of this method. It is not in the
-	// hot path, i.e.  Observe is called much more often than Write. The
-	// complication of making Write lock-free isn't worth it.
-	h.writeMtx.Lock()
-	defer h.writeMtx.Unlock()
-
-	// This is a bit arcane, which is why the following spells out this if
-	// clause in English:
-	//
-	// If the currently-hot counts struct is #0, we atomically increment
-	// h.countAndHotIdx by 1 so that from now on Observe will use the counts
-	// struct #1. Furthermore, the atomic increment gives us the new value,
-	// which, in its most significant 63 bits, tells us the count of
-	// observations done so far up to and including currently ongoing
-	// observations still using the counts struct just changed from hot to
-	// cold. To have a normal uint64 for the count, we bitshift by 1 and
-	// save the result in count. We also set h.hotIdx to 1 for the next
-	// Write call, and we will refer to counts #1 as hotCounts and to counts
-	// #0 as coldCounts.
-	//
-	// If the currently-hot counts struct is #1, we do the corresponding
-	// things the other way round. We have to _decrement_ h.countAndHotIdx
-	// (which is a bit arcane in itself, as we have to express -1 with an
-	// unsigned int...).
-	if h.hotIdx == 0 {
-		count = atomic.AddUint64(&h.countAndHotIdx, 1) >> 1
-		h.hotIdx = 1
-		hotCounts = h.counts[1]
-		coldCounts = h.counts[0]
-	} else {
-		count = atomic.AddUint64(&h.countAndHotIdx, ^uint64(0)) >> 1 // Decrement.
-		h.hotIdx = 0
-		hotCounts = h.counts[0]
-		coldCounts = h.counts[1]
-	}
-
-	// Now we have to wait for the now-declared-cold counts to actually cool
-	// down, i.e. wait for all observations still using it to finish. That's
-	// the case once the count in the cold counts struct is the same as the
-	// one atomically retrieved from the upper 63bits of h.countAndHotIdx.
-	for {
-		if count == atomic.LoadUint64(&coldCounts.count) {
-			break
-		}
-		runtime.Gosched() // Let observations get work done.
-	}
-
-	his.SampleCount = proto.Uint64(count)
-	his.SampleSum = proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits)))
-	var cumCount uint64
-	for i, upperBound := range h.upperBounds {
-		cumCount += atomic.LoadUint64(&coldCounts.buckets[i])
-		buckets[i] = &dto.Bucket{
-			CumulativeCount: proto.Uint64(cumCount),
-			UpperBound:      proto.Float64(upperBound),
-		}
-	}
-
-	his.Bucket = buckets
-	out.Histogram = his
-	out.Label = h.labelPairs
-
-	// Finally add all the cold counts to the new hot counts and reset the cold counts.
-	atomic.AddUint64(&hotCounts.count, count)
-	atomic.StoreUint64(&coldCounts.count, 0)
-	for {
-		oldBits := atomic.LoadUint64(&hotCounts.sumBits)
-		newBits := math.Float64bits(math.Float64frombits(oldBits) + his.GetSampleSum())
-		if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
-			atomic.StoreUint64(&coldCounts.sumBits, 0)
-			break
-		}
-	}
-	for i := range h.upperBounds {
-		atomic.AddUint64(&hotCounts.buckets[i], atomic.LoadUint64(&coldCounts.buckets[i]))
-		atomic.StoreUint64(&coldCounts.buckets[i], 0)
-	}
-	return nil
-}
-
-// HistogramVec is a Collector that bundles a set of Histograms that all share the
-// same Desc, but have different values for their variable labels. This is used
-// if you want to count the same thing partitioned by various dimensions
-// (e.g. HTTP request latencies, partitioned by status code and method). Create
-// instances with NewHistogramVec.
-type HistogramVec struct {
-	*metricVec
-}
-
-// NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and
-// partitioned by the given label names.
-func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
-	desc := NewDesc(
-		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-		opts.Help,
-		labelNames,
-		opts.ConstLabels,
-	)
-	return &HistogramVec{
-		metricVec: newMetricVec(desc, func(lvs ...string) Metric {
-			return newHistogram(desc, opts, lvs...)
-		}),
-	}
-}
-
-// GetMetricWithLabelValues returns the Histogram for the given slice of label
-// values (same order as the VariableLabels in Desc). If that combination of
-// label values is accessed for the first time, a new Histogram is created.
-//
-// It is possible to call this method without using the returned Histogram to only
-// create the new Histogram but leave it at its starting value, a Histogram without
-// any observations.
-//
-// Keeping the Histogram for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Histogram from the HistogramVec. In that case, the
-// Histogram will still exist, but it will not be exported anymore, even if a
-// Histogram with the same label values is created later. See also the CounterVec
-// example.
-//
-// An error is returned if the number of label values is not the same as the
-// number of VariableLabels in Desc (minus any curried labels).
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the GaugeVec example.
-func (v *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
-	metric, err := v.metricVec.getMetricWithLabelValues(lvs...)
-	if metric != nil {
-		return metric.(Observer), err
-	}
-	return nil, err
-}
-
-// GetMetricWith returns the Histogram for the given Labels map (the label names
-// must match those of the VariableLabels in Desc). If that label map is
-// accessed for the first time, a new Histogram is created. Implications of
-// creating a Histogram without using it and keeping the Histogram for later use
-// are the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc (minus any curried labels).
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (v *HistogramVec) GetMetricWith(labels Labels) (Observer, error) {
-	metric, err := v.metricVec.getMetricWith(labels)
-	if metric != nil {
-		return metric.(Observer), err
-	}
-	return nil, err
-}
-
-// WithLabelValues works as GetMetricWithLabelValues, but panics where
-// GetMetricWithLabelValues would have returned an error. Not returning an
-// error allows shortcuts like
-//     myVec.WithLabelValues("404", "GET").Observe(42.21)
-func (v *HistogramVec) WithLabelValues(lvs ...string) Observer {
-	h, err := v.GetMetricWithLabelValues(lvs...)
-	if err != nil {
-		panic(err)
-	}
-	return h
-}
-
-// With works as GetMetricWith but panics where GetMetricWithLabels would have
-// returned an error. Not returning an error allows shortcuts like
-//     myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21)
-func (v *HistogramVec) With(labels Labels) Observer {
-	h, err := v.GetMetricWith(labels)
-	if err != nil {
-		panic(err)
-	}
-	return h
-}
-
-// CurryWith returns a vector curried with the provided labels, i.e. the
-// returned vector has those labels pre-set for all labeled operations performed
-// on it. The cardinality of the curried vector is reduced accordingly. The
-// order of the remaining labels stays the same (just with the curried labels
-// taken out of the sequence – which is relevant for the
-// (GetMetric)WithLabelValues methods). It is possible to curry a curried
-// vector, but only with labels not yet used for currying before.
-//
-// The metrics contained in the HistogramVec are shared between the curried and
-// uncurried vectors. They are just accessed differently. Curried and uncurried
-// vectors behave identically in terms of collection. Only one must be
-// registered with a given registry (usually the uncurried version). The Reset
-// method deletes all metrics, even if called on a curried vector.
-func (v *HistogramVec) CurryWith(labels Labels) (ObserverVec, error) {
-	vec, err := v.curryWith(labels)
-	if vec != nil {
-		return &HistogramVec{vec}, err
-	}
-	return nil, err
-}
-
-// MustCurryWith works as CurryWith but panics where CurryWith would have
-// returned an error.
-func (v *HistogramVec) MustCurryWith(labels Labels) ObserverVec {
-	vec, err := v.CurryWith(labels)
-	if err != nil {
-		panic(err)
-	}
-	return vec
-}
-
-type constHistogram struct {
-	desc       *Desc
-	count      uint64
-	sum        float64
-	buckets    map[float64]uint64
-	labelPairs []*dto.LabelPair
-}
-
-func (h *constHistogram) Desc() *Desc {
-	return h.desc
-}
-
-func (h *constHistogram) Write(out *dto.Metric) error {
-	his := &dto.Histogram{}
-	buckets := make([]*dto.Bucket, 0, len(h.buckets))
-
-	his.SampleCount = proto.Uint64(h.count)
-	his.SampleSum = proto.Float64(h.sum)
-
-	for upperBound, count := range h.buckets {
-		buckets = append(buckets, &dto.Bucket{
-			CumulativeCount: proto.Uint64(count),
-			UpperBound:      proto.Float64(upperBound),
-		})
-	}
-
-	if len(buckets) > 0 {
-		sort.Sort(buckSort(buckets))
-	}
-	his.Bucket = buckets
-
-	out.Histogram = his
-	out.Label = h.labelPairs
-
-	return nil
-}
-
-// NewConstHistogram returns a metric representing a Prometheus histogram with
-// fixed values for the count, sum, and bucket counts. As those parameters
-// cannot be changed, the returned value does not implement the Histogram
-// interface (but only the Metric interface). Users of this package will not
-// have much use for it in regular operations. However, when implementing custom
-// Collectors, it is useful as a throw-away metric that is generated on the fly
-// to send it to Prometheus in the Collect method.
-//
-// buckets is a map of upper bounds to cumulative counts, excluding the +Inf
-// bucket.
-//
-// NewConstHistogram returns an error if the length of labelValues is not
-// consistent with the variable labels in Desc or if Desc is invalid.
-func NewConstHistogram(
-	desc *Desc,
-	count uint64,
-	sum float64,
-	buckets map[float64]uint64,
-	labelValues ...string,
-) (Metric, error) {
-	if desc.err != nil {
-		return nil, desc.err
-	}
-	if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
-		return nil, err
-	}
-	return &constHistogram{
-		desc:       desc,
-		count:      count,
-		sum:        sum,
-		buckets:    buckets,
-		labelPairs: makeLabelPairs(desc, labelValues),
-	}, nil
-}
-
-// MustNewConstHistogram is a version of NewConstHistogram that panics where
-// NewConstMetric would have returned an error.
-func MustNewConstHistogram(
-	desc *Desc,
-	count uint64,
-	sum float64,
-	buckets map[float64]uint64,
-	labelValues ...string,
-) Metric {
-	m, err := NewConstHistogram(desc, count, sum, buckets, labelValues...)
-	if err != nil {
-		panic(err)
-	}
-	return m
-}
-
-type buckSort []*dto.Bucket
-
-func (s buckSort) Len() int {
-	return len(s)
-}
-
-func (s buckSort) Swap(i, j int) {
-	s[i], s[j] = s[j], s[i]
-}
-
-func (s buckSort) Less(i, j int) bool {
-	return s[i].GetUpperBound() < s[j].GetUpperBound()
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/http.go b/vendor/github.com/prometheus/client_golang/prometheus/http.go
deleted file mode 100644
index 9f0875b..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/http.go
+++ /dev/null
@@ -1,504 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"bufio"
-	"compress/gzip"
-	"io"
-	"net"
-	"net/http"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-
-	"github.com/prometheus/common/expfmt"
-)
-
-// TODO(beorn7): Remove this whole file. It is a partial mirror of
-// promhttp/http.go (to avoid circular import chains) where everything HTTP
-// related should live. The functions here are just for avoiding
-// breakage. Everything is deprecated.
-
-const (
-	contentTypeHeader     = "Content-Type"
-	contentLengthHeader   = "Content-Length"
-	contentEncodingHeader = "Content-Encoding"
-	acceptEncodingHeader  = "Accept-Encoding"
-)
-
-var gzipPool = sync.Pool{
-	New: func() interface{} {
-		return gzip.NewWriter(nil)
-	},
-}
-
-// Handler returns an HTTP handler for the DefaultGatherer. It is
-// already instrumented with InstrumentHandler (using "prometheus" as handler
-// name).
-//
-// Deprecated: Please note the issues described in the doc comment of
-// InstrumentHandler. You might want to consider using promhttp.Handler instead.
-func Handler() http.Handler {
-	return InstrumentHandler("prometheus", UninstrumentedHandler())
-}
-
-// UninstrumentedHandler returns an HTTP handler for the DefaultGatherer.
-//
-// Deprecated: Use promhttp.HandlerFor(DefaultGatherer, promhttp.HandlerOpts{})
-// instead. See there for further documentation.
-func UninstrumentedHandler() http.Handler {
-	return http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {
-		mfs, err := DefaultGatherer.Gather()
-		if err != nil {
-			httpError(rsp, err)
-			return
-		}
-
-		contentType := expfmt.Negotiate(req.Header)
-		header := rsp.Header()
-		header.Set(contentTypeHeader, string(contentType))
-
-		w := io.Writer(rsp)
-		if gzipAccepted(req.Header) {
-			header.Set(contentEncodingHeader, "gzip")
-			gz := gzipPool.Get().(*gzip.Writer)
-			defer gzipPool.Put(gz)
-
-			gz.Reset(w)
-			defer gz.Close()
-
-			w = gz
-		}
-
-		enc := expfmt.NewEncoder(w, contentType)
-
-		for _, mf := range mfs {
-			if err := enc.Encode(mf); err != nil {
-				httpError(rsp, err)
-				return
-			}
-		}
-	})
-}
-
-var instLabels = []string{"method", "code"}
-
-type nower interface {
-	Now() time.Time
-}
-
-type nowFunc func() time.Time
-
-func (n nowFunc) Now() time.Time {
-	return n()
-}
-
-var now nower = nowFunc(func() time.Time {
-	return time.Now()
-})
-
-// InstrumentHandler wraps the given HTTP handler for instrumentation. It
-// registers four metric collectors (if not already done) and reports HTTP
-// metrics to the (newly or already) registered collectors: http_requests_total
-// (CounterVec), http_request_duration_microseconds (Summary),
-// http_request_size_bytes (Summary), http_response_size_bytes (Summary). Each
-// has a constant label named "handler" with the provided handlerName as
-// value. http_requests_total is a metric vector partitioned by HTTP method
-// (label name "method") and HTTP status code (label name "code").
-//
-// Deprecated: InstrumentHandler has several issues. Use the tooling provided in
-// package promhttp instead. The issues are the following: (1) It uses Summaries
-// rather than Histograms. Summaries are not useful if aggregation across
-// multiple instances is required. (2) It uses microseconds as unit, which is
-// deprecated and should be replaced by seconds. (3) The size of the request is
-// calculated in a separate goroutine. Since this calculator requires access to
-// the request header, it creates a race with any writes to the header performed
-// during request handling.  httputil.ReverseProxy is a prominent example for a
-// handler performing such writes. (4) It has additional issues with HTTP/2, cf.
-// https://github.com/prometheus/client_golang/issues/272.
-func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc {
-	return InstrumentHandlerFunc(handlerName, handler.ServeHTTP)
-}
-
-// InstrumentHandlerFunc wraps the given function for instrumentation. It
-// otherwise works in the same way as InstrumentHandler (and shares the same
-// issues).
-//
-// Deprecated: InstrumentHandlerFunc is deprecated for the same reasons as
-// InstrumentHandler is. Use the tooling provided in package promhttp instead.
-func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
-	return InstrumentHandlerFuncWithOpts(
-		SummaryOpts{
-			Subsystem:   "http",
-			ConstLabels: Labels{"handler": handlerName},
-			Objectives:  map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
-		},
-		handlerFunc,
-	)
-}
-
-// InstrumentHandlerWithOpts works like InstrumentHandler (and shares the same
-// issues) but provides more flexibility (at the cost of a more complex call
-// syntax). As InstrumentHandler, this function registers four metric
-// collectors, but it uses the provided SummaryOpts to create them. However, the
-// fields "Name" and "Help" in the SummaryOpts are ignored. "Name" is replaced
-// by "requests_total", "request_duration_microseconds", "request_size_bytes",
-// and "response_size_bytes", respectively. "Help" is replaced by an appropriate
-// help string. The names of the variable labels of the http_requests_total
-// CounterVec are "method" (get, post, etc.), and "code" (HTTP status code).
-//
-// If InstrumentHandlerWithOpts is called as follows, it mimics exactly the
-// behavior of InstrumentHandler:
-//
-//     prometheus.InstrumentHandlerWithOpts(
-//         prometheus.SummaryOpts{
-//              Subsystem:   "http",
-//              ConstLabels: prometheus.Labels{"handler": handlerName},
-//         },
-//         handler,
-//     )
-//
-// Technical detail: "requests_total" is a CounterVec, not a SummaryVec, so it
-// cannot use SummaryOpts. Instead, a CounterOpts struct is created internally,
-// and all its fields are set to the equally named fields in the provided
-// SummaryOpts.
-//
-// Deprecated: InstrumentHandlerWithOpts is deprecated for the same reasons as
-// InstrumentHandler is. Use the tooling provided in package promhttp instead.
-func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.HandlerFunc {
-	return InstrumentHandlerFuncWithOpts(opts, handler.ServeHTTP)
-}
-
-// InstrumentHandlerFuncWithOpts works like InstrumentHandlerFunc (and shares
-// the same issues) but provides more flexibility (at the cost of a more complex
-// call syntax). See InstrumentHandlerWithOpts for details how the provided
-// SummaryOpts are used.
-//
-// Deprecated: InstrumentHandlerFuncWithOpts is deprecated for the same reasons
-// as InstrumentHandler is. Use the tooling provided in package promhttp instead.
-func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
-	reqCnt := NewCounterVec(
-		CounterOpts{
-			Namespace:   opts.Namespace,
-			Subsystem:   opts.Subsystem,
-			Name:        "requests_total",
-			Help:        "Total number of HTTP requests made.",
-			ConstLabels: opts.ConstLabels,
-		},
-		instLabels,
-	)
-	if err := Register(reqCnt); err != nil {
-		if are, ok := err.(AlreadyRegisteredError); ok {
-			reqCnt = are.ExistingCollector.(*CounterVec)
-		} else {
-			panic(err)
-		}
-	}
-
-	opts.Name = "request_duration_microseconds"
-	opts.Help = "The HTTP request latencies in microseconds."
-	reqDur := NewSummary(opts)
-	if err := Register(reqDur); err != nil {
-		if are, ok := err.(AlreadyRegisteredError); ok {
-			reqDur = are.ExistingCollector.(Summary)
-		} else {
-			panic(err)
-		}
-	}
-
-	opts.Name = "request_size_bytes"
-	opts.Help = "The HTTP request sizes in bytes."
-	reqSz := NewSummary(opts)
-	if err := Register(reqSz); err != nil {
-		if are, ok := err.(AlreadyRegisteredError); ok {
-			reqSz = are.ExistingCollector.(Summary)
-		} else {
-			panic(err)
-		}
-	}
-
-	opts.Name = "response_size_bytes"
-	opts.Help = "The HTTP response sizes in bytes."
-	resSz := NewSummary(opts)
-	if err := Register(resSz); err != nil {
-		if are, ok := err.(AlreadyRegisteredError); ok {
-			resSz = are.ExistingCollector.(Summary)
-		} else {
-			panic(err)
-		}
-	}
-
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		now := time.Now()
-
-		delegate := &responseWriterDelegator{ResponseWriter: w}
-		out := computeApproximateRequestSize(r)
-
-		_, cn := w.(http.CloseNotifier)
-		_, fl := w.(http.Flusher)
-		_, hj := w.(http.Hijacker)
-		_, rf := w.(io.ReaderFrom)
-		var rw http.ResponseWriter
-		if cn && fl && hj && rf {
-			rw = &fancyResponseWriterDelegator{delegate}
-		} else {
-			rw = delegate
-		}
-		handlerFunc(rw, r)
-
-		elapsed := float64(time.Since(now)) / float64(time.Microsecond)
-
-		method := sanitizeMethod(r.Method)
-		code := sanitizeCode(delegate.status)
-		reqCnt.WithLabelValues(method, code).Inc()
-		reqDur.Observe(elapsed)
-		resSz.Observe(float64(delegate.written))
-		reqSz.Observe(float64(<-out))
-	})
-}
-
-func computeApproximateRequestSize(r *http.Request) <-chan int {
-	// Get URL length in current goroutine for avoiding a race condition.
-	// HandlerFunc that runs in parallel may modify the URL.
-	s := 0
-	if r.URL != nil {
-		s += len(r.URL.String())
-	}
-
-	out := make(chan int, 1)
-
-	go func() {
-		s += len(r.Method)
-		s += len(r.Proto)
-		for name, values := range r.Header {
-			s += len(name)
-			for _, value := range values {
-				s += len(value)
-			}
-		}
-		s += len(r.Host)
-
-		// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
-
-		if r.ContentLength != -1 {
-			s += int(r.ContentLength)
-		}
-		out <- s
-		close(out)
-	}()
-
-	return out
-}
-
-type responseWriterDelegator struct {
-	http.ResponseWriter
-
-	status      int
-	written     int64
-	wroteHeader bool
-}
-
-func (r *responseWriterDelegator) WriteHeader(code int) {
-	r.status = code
-	r.wroteHeader = true
-	r.ResponseWriter.WriteHeader(code)
-}
-
-func (r *responseWriterDelegator) Write(b []byte) (int, error) {
-	if !r.wroteHeader {
-		r.WriteHeader(http.StatusOK)
-	}
-	n, err := r.ResponseWriter.Write(b)
-	r.written += int64(n)
-	return n, err
-}
-
-type fancyResponseWriterDelegator struct {
-	*responseWriterDelegator
-}
-
-func (f *fancyResponseWriterDelegator) CloseNotify() <-chan bool {
-	return f.ResponseWriter.(http.CloseNotifier).CloseNotify()
-}
-
-func (f *fancyResponseWriterDelegator) Flush() {
-	f.ResponseWriter.(http.Flusher).Flush()
-}
-
-func (f *fancyResponseWriterDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
-	return f.ResponseWriter.(http.Hijacker).Hijack()
-}
-
-func (f *fancyResponseWriterDelegator) ReadFrom(r io.Reader) (int64, error) {
-	if !f.wroteHeader {
-		f.WriteHeader(http.StatusOK)
-	}
-	n, err := f.ResponseWriter.(io.ReaderFrom).ReadFrom(r)
-	f.written += n
-	return n, err
-}
-
-func sanitizeMethod(m string) string {
-	switch m {
-	case "GET", "get":
-		return "get"
-	case "PUT", "put":
-		return "put"
-	case "HEAD", "head":
-		return "head"
-	case "POST", "post":
-		return "post"
-	case "DELETE", "delete":
-		return "delete"
-	case "CONNECT", "connect":
-		return "connect"
-	case "OPTIONS", "options":
-		return "options"
-	case "NOTIFY", "notify":
-		return "notify"
-	default:
-		return strings.ToLower(m)
-	}
-}
-
-func sanitizeCode(s int) string {
-	switch s {
-	case 100:
-		return "100"
-	case 101:
-		return "101"
-
-	case 200:
-		return "200"
-	case 201:
-		return "201"
-	case 202:
-		return "202"
-	case 203:
-		return "203"
-	case 204:
-		return "204"
-	case 205:
-		return "205"
-	case 206:
-		return "206"
-
-	case 300:
-		return "300"
-	case 301:
-		return "301"
-	case 302:
-		return "302"
-	case 304:
-		return "304"
-	case 305:
-		return "305"
-	case 307:
-		return "307"
-
-	case 400:
-		return "400"
-	case 401:
-		return "401"
-	case 402:
-		return "402"
-	case 403:
-		return "403"
-	case 404:
-		return "404"
-	case 405:
-		return "405"
-	case 406:
-		return "406"
-	case 407:
-		return "407"
-	case 408:
-		return "408"
-	case 409:
-		return "409"
-	case 410:
-		return "410"
-	case 411:
-		return "411"
-	case 412:
-		return "412"
-	case 413:
-		return "413"
-	case 414:
-		return "414"
-	case 415:
-		return "415"
-	case 416:
-		return "416"
-	case 417:
-		return "417"
-	case 418:
-		return "418"
-
-	case 500:
-		return "500"
-	case 501:
-		return "501"
-	case 502:
-		return "502"
-	case 503:
-		return "503"
-	case 504:
-		return "504"
-	case 505:
-		return "505"
-
-	case 428:
-		return "428"
-	case 429:
-		return "429"
-	case 431:
-		return "431"
-	case 511:
-		return "511"
-
-	default:
-		return strconv.Itoa(s)
-	}
-}
-
-// gzipAccepted returns whether the client will accept gzip-encoded content.
-func gzipAccepted(header http.Header) bool {
-	a := header.Get(acceptEncodingHeader)
-	parts := strings.Split(a, ",")
-	for _, part := range parts {
-		part = strings.TrimSpace(part)
-		if part == "gzip" || strings.HasPrefix(part, "gzip;") {
-			return true
-		}
-	}
-	return false
-}
-
-// httpError removes any content-encoding header and then calls http.Error with
-// the provided error and http.StatusInternalServerErrer. Error contents is
-// supposed to be uncompressed plain text. However, same as with a plain
-// http.Error, any header settings will be void if the header has already been
-// sent. The error message will still be written to the writer, but it will
-// probably be of limited use.
-func httpError(rsp http.ResponseWriter, err error) {
-	rsp.Header().Del(contentEncodingHeader)
-	http.Error(
-		rsp,
-		"An error has occurred while serving metrics:\n\n"+err.Error(),
-		http.StatusInternalServerError,
-	)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go
deleted file mode 100644
index 351c26e..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package internal
-
-import (
-	"sort"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-// metricSorter is a sortable slice of *dto.Metric.
-type metricSorter []*dto.Metric
-
-func (s metricSorter) Len() int {
-	return len(s)
-}
-
-func (s metricSorter) Swap(i, j int) {
-	s[i], s[j] = s[j], s[i]
-}
-
-func (s metricSorter) Less(i, j int) bool {
-	if len(s[i].Label) != len(s[j].Label) {
-		// This should not happen. The metrics are
-		// inconsistent. However, we have to deal with the fact, as
-		// people might use custom collectors or metric family injection
-		// to create inconsistent metrics. So let's simply compare the
-		// number of labels in this case. That will still yield
-		// reproducible sorting.
-		return len(s[i].Label) < len(s[j].Label)
-	}
-	for n, lp := range s[i].Label {
-		vi := lp.GetValue()
-		vj := s[j].Label[n].GetValue()
-		if vi != vj {
-			return vi < vj
-		}
-	}
-
-	// We should never arrive here. Multiple metrics with the same
-	// label set in the same scrape will lead to undefined ingestion
-	// behavior. However, as above, we have to provide stable sorting
-	// here, even for inconsistent metrics. So sort equal metrics
-	// by their timestamp, with missing timestamps (implying "now")
-	// coming last.
-	if s[i].TimestampMs == nil {
-		return false
-	}
-	if s[j].TimestampMs == nil {
-		return true
-	}
-	return s[i].GetTimestampMs() < s[j].GetTimestampMs()
-}
-
-// NormalizeMetricFamilies returns a MetricFamily slice with empty
-// MetricFamilies pruned and the remaining MetricFamilies sorted by name within
-// the slice, with the contained Metrics sorted within each MetricFamily.
-func NormalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily {
-	for _, mf := range metricFamiliesByName {
-		sort.Sort(metricSorter(mf.Metric))
-	}
-	names := make([]string, 0, len(metricFamiliesByName))
-	for name, mf := range metricFamiliesByName {
-		if len(mf.Metric) > 0 {
-			names = append(names, name)
-		}
-	}
-	sort.Strings(names)
-	result := make([]*dto.MetricFamily, 0, len(names))
-	for _, name := range names {
-		result = append(result, metricFamiliesByName[name])
-	}
-	return result
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/labels.go b/vendor/github.com/prometheus/client_golang/prometheus/labels.go
deleted file mode 100644
index 2744443..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/labels.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-	"unicode/utf8"
-
-	"github.com/prometheus/common/model"
-)
-
-// Labels represents a collection of label name -> value mappings. This type is
-// commonly used with the With(Labels) and GetMetricWith(Labels) methods of
-// metric vector Collectors, e.g.:
-//     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
-//
-// The other use-case is the specification of constant label pairs in Opts or to
-// create a Desc.
-type Labels map[string]string
-
-// reservedLabelPrefix is a prefix which is not legal in user-supplied
-// label names.
-const reservedLabelPrefix = "__"
-
-var errInconsistentCardinality = errors.New("inconsistent label cardinality")
-
-func makeInconsistentCardinalityError(fqName string, labels, labelValues []string) error {
-	return fmt.Errorf(
-		"%s: %q has %d variable labels named %q but %d values %q were provided",
-		errInconsistentCardinality, fqName,
-		len(labels), labels,
-		len(labelValues), labelValues,
-	)
-}
-
-func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error {
-	if len(labels) != expectedNumberOfValues {
-		return fmt.Errorf(
-			"%s: expected %d label values but got %d in %#v",
-			errInconsistentCardinality, expectedNumberOfValues,
-			len(labels), labels,
-		)
-	}
-
-	for name, val := range labels {
-		if !utf8.ValidString(val) {
-			return fmt.Errorf("label %s: value %q is not valid UTF-8", name, val)
-		}
-	}
-
-	return nil
-}
-
-func validateLabelValues(vals []string, expectedNumberOfValues int) error {
-	if len(vals) != expectedNumberOfValues {
-		return fmt.Errorf(
-			"%s: expected %d label values but got %d in %#v",
-			errInconsistentCardinality, expectedNumberOfValues,
-			len(vals), vals,
-		)
-	}
-
-	for _, val := range vals {
-		if !utf8.ValidString(val) {
-			return fmt.Errorf("label value %q is not valid UTF-8", val)
-		}
-	}
-
-	return nil
-}
-
-func checkLabelName(l string) bool {
-	return model.LabelName(l).IsValid() && !strings.HasPrefix(l, reservedLabelPrefix)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/metric.go
deleted file mode 100644
index 55e6d86..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/metric.go
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"strings"
-	"time"
-
-	"github.com/golang/protobuf/proto"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-const separatorByte byte = 255
-
-// A Metric models a single sample value with its meta data being exported to
-// Prometheus. Implementations of Metric in this package are Gauge, Counter,
-// Histogram, Summary, and Untyped.
-type Metric interface {
-	// Desc returns the descriptor for the Metric. This method idempotently
-	// returns the same descriptor throughout the lifetime of the
-	// Metric. The returned descriptor is immutable by contract. A Metric
-	// unable to describe itself must return an invalid descriptor (created
-	// with NewInvalidDesc).
-	Desc() *Desc
-	// Write encodes the Metric into a "Metric" Protocol Buffer data
-	// transmission object.
-	//
-	// Metric implementations must observe concurrency safety as reads of
-	// this metric may occur at any time, and any blocking occurs at the
-	// expense of total performance of rendering all registered
-	// metrics. Ideally, Metric implementations should support concurrent
-	// readers.
-	//
-	// While populating dto.Metric, it is the responsibility of the
-	// implementation to ensure validity of the Metric protobuf (like valid
-	// UTF-8 strings or syntactically valid metric and label names). It is
-	// recommended to sort labels lexicographically. Callers of Write should
-	// still make sure of sorting if they depend on it.
-	Write(*dto.Metric) error
-	// TODO(beorn7): The original rationale of passing in a pre-allocated
-	// dto.Metric protobuf to save allocations has disappeared. The
-	// signature of this method should be changed to "Write() (*dto.Metric,
-	// error)".
-}
-
-// Opts bundles the options for creating most Metric types. Each metric
-// implementation XXX has its own XXXOpts type, but in most cases, it is just be
-// an alias of this type (which might change when the requirement arises.)
-//
-// It is mandatory to set Name to a non-empty string. All other fields are
-// optional and can safely be left at their zero value, although it is strongly
-// encouraged to set a Help string.
-type Opts struct {
-	// Namespace, Subsystem, and Name are components of the fully-qualified
-	// name of the Metric (created by joining these components with
-	// "_"). Only Name is mandatory, the others merely help structuring the
-	// name. Note that the fully-qualified name of the metric must be a
-	// valid Prometheus metric name.
-	Namespace string
-	Subsystem string
-	Name      string
-
-	// Help provides information about this metric.
-	//
-	// Metrics with the same fully-qualified name must have the same Help
-	// string.
-	Help string
-
-	// ConstLabels are used to attach fixed labels to this metric. Metrics
-	// with the same fully-qualified name must have the same label names in
-	// their ConstLabels.
-	//
-	// ConstLabels are only used rarely. In particular, do not use them to
-	// attach the same labels to all your metrics. Those use cases are
-	// better covered by target labels set by the scraping Prometheus
-	// server, or by one specific metric (e.g. a build_info or a
-	// machine_role metric). See also
-	// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels,-not-static-scraped-labels
-	ConstLabels Labels
-}
-
-// BuildFQName joins the given three name components by "_". Empty name
-// components are ignored. If the name parameter itself is empty, an empty
-// string is returned, no matter what. Metric implementations included in this
-// library use this function internally to generate the fully-qualified metric
-// name from the name component in their Opts. Users of the library will only
-// need this function if they implement their own Metric or instantiate a Desc
-// (with NewDesc) directly.
-func BuildFQName(namespace, subsystem, name string) string {
-	if name == "" {
-		return ""
-	}
-	switch {
-	case namespace != "" && subsystem != "":
-		return strings.Join([]string{namespace, subsystem, name}, "_")
-	case namespace != "":
-		return strings.Join([]string{namespace, name}, "_")
-	case subsystem != "":
-		return strings.Join([]string{subsystem, name}, "_")
-	}
-	return name
-}
-
-// labelPairSorter implements sort.Interface. It is used to sort a slice of
-// dto.LabelPair pointers.
-type labelPairSorter []*dto.LabelPair
-
-func (s labelPairSorter) Len() int {
-	return len(s)
-}
-
-func (s labelPairSorter) Swap(i, j int) {
-	s[i], s[j] = s[j], s[i]
-}
-
-func (s labelPairSorter) Less(i, j int) bool {
-	return s[i].GetName() < s[j].GetName()
-}
-
-type invalidMetric struct {
-	desc *Desc
-	err  error
-}
-
-// NewInvalidMetric returns a metric whose Write method always returns the
-// provided error. It is useful if a Collector finds itself unable to collect
-// a metric and wishes to report an error to the registry.
-func NewInvalidMetric(desc *Desc, err error) Metric {
-	return &invalidMetric{desc, err}
-}
-
-func (m *invalidMetric) Desc() *Desc { return m.desc }
-
-func (m *invalidMetric) Write(*dto.Metric) error { return m.err }
-
-type timestampedMetric struct {
-	Metric
-	t time.Time
-}
-
-func (m timestampedMetric) Write(pb *dto.Metric) error {
-	e := m.Metric.Write(pb)
-	pb.TimestampMs = proto.Int64(m.t.Unix()*1000 + int64(m.t.Nanosecond()/1000000))
-	return e
-}
-
-// NewMetricWithTimestamp returns a new Metric wrapping the provided Metric in a
-// way that it has an explicit timestamp set to the provided Time. This is only
-// useful in rare cases as the timestamp of a Prometheus metric should usually
-// be set by the Prometheus server during scraping. Exceptions include mirroring
-// metrics with given timestamps from other metric
-// sources.
-//
-// NewMetricWithTimestamp works best with MustNewConstMetric,
-// MustNewConstHistogram, and MustNewConstSummary, see example.
-//
-// Currently, the exposition formats used by Prometheus are limited to
-// millisecond resolution. Thus, the provided time will be rounded down to the
-// next full millisecond value.
-func NewMetricWithTimestamp(t time.Time, m Metric) Metric {
-	return timestampedMetric{Metric: m, t: t}
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/observer.go b/vendor/github.com/prometheus/client_golang/prometheus/observer.go
deleted file mode 100644
index 5806cd0..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/observer.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-// Observer is the interface that wraps the Observe method, which is used by
-// Histogram and Summary to add observations.
-type Observer interface {
-	Observe(float64)
-}
-
-// The ObserverFunc type is an adapter to allow the use of ordinary
-// functions as Observers. If f is a function with the appropriate
-// signature, ObserverFunc(f) is an Observer that calls f.
-//
-// This adapter is usually used in connection with the Timer type, and there are
-// two general use cases:
-//
-// The most common one is to use a Gauge as the Observer for a Timer.
-// See the "Gauge" Timer example.
-//
-// The more advanced use case is to create a function that dynamically decides
-// which Observer to use for observing the duration. See the "Complex" Timer
-// example.
-type ObserverFunc func(float64)
-
-// Observe calls f(value). It implements Observer.
-func (f ObserverFunc) Observe(value float64) {
-	f(value)
-}
-
-// ObserverVec is an interface implemented by `HistogramVec` and `SummaryVec`.
-type ObserverVec interface {
-	GetMetricWith(Labels) (Observer, error)
-	GetMetricWithLabelValues(lvs ...string) (Observer, error)
-	With(Labels) Observer
-	WithLabelValues(...string) Observer
-	CurryWith(Labels) (ObserverVec, error)
-	MustCurryWith(Labels) ObserverVec
-
-	Collector
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
deleted file mode 100644
index 55176d5..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"errors"
-	"os"
-
-	"github.com/prometheus/procfs"
-)
-
-type processCollector struct {
-	collectFn       func(chan<- Metric)
-	pidFn           func() (int, error)
-	reportErrors    bool
-	cpuTotal        *Desc
-	openFDs, maxFDs *Desc
-	vsize, maxVsize *Desc
-	rss             *Desc
-	startTime       *Desc
-}
-
-// ProcessCollectorOpts defines the behavior of a process metrics collector
-// created with NewProcessCollector.
-type ProcessCollectorOpts struct {
-	// PidFn returns the PID of the process the collector collects metrics
-	// for. It is called upon each collection. By default, the PID of the
-	// current process is used, as determined on construction time by
-	// calling os.Getpid().
-	PidFn func() (int, error)
-	// If non-empty, each of the collected metrics is prefixed by the
-	// provided string and an underscore ("_").
-	Namespace string
-	// If true, any error encountered during collection is reported as an
-	// invalid metric (see NewInvalidMetric). Otherwise, errors are ignored
-	// and the collected metrics will be incomplete. (Possibly, no metrics
-	// will be collected at all.) While that's usually not desired, it is
-	// appropriate for the common "mix-in" of process metrics, where process
-	// metrics are nice to have, but failing to collect them should not
-	// disrupt the collection of the remaining metrics.
-	ReportErrors bool
-}
-
-// NewProcessCollector returns a collector which exports the current state of
-// process metrics including CPU, memory and file descriptor usage as well as
-// the process start time. The detailed behavior is defined by the provided
-// ProcessCollectorOpts. The zero value of ProcessCollectorOpts creates a
-// collector for the current process with an empty namespace string and no error
-// reporting.
-//
-// Currently, the collector depends on a Linux-style proc filesystem and
-// therefore only exports metrics for Linux.
-//
-// Note: An older version of this function had the following signature:
-//
-//     NewProcessCollector(pid int, namespace string) Collector
-//
-// Most commonly, it was called as
-//
-//     NewProcessCollector(os.Getpid(), "")
-//
-// The following call of the current version is equivalent to the above:
-//
-//     NewProcessCollector(ProcessCollectorOpts{})
-func NewProcessCollector(opts ProcessCollectorOpts) Collector {
-	ns := ""
-	if len(opts.Namespace) > 0 {
-		ns = opts.Namespace + "_"
-	}
-
-	c := &processCollector{
-		reportErrors: opts.ReportErrors,
-		cpuTotal: NewDesc(
-			ns+"process_cpu_seconds_total",
-			"Total user and system CPU time spent in seconds.",
-			nil, nil,
-		),
-		openFDs: NewDesc(
-			ns+"process_open_fds",
-			"Number of open file descriptors.",
-			nil, nil,
-		),
-		maxFDs: NewDesc(
-			ns+"process_max_fds",
-			"Maximum number of open file descriptors.",
-			nil, nil,
-		),
-		vsize: NewDesc(
-			ns+"process_virtual_memory_bytes",
-			"Virtual memory size in bytes.",
-			nil, nil,
-		),
-		maxVsize: NewDesc(
-			ns+"process_virtual_memory_max_bytes",
-			"Maximum amount of virtual memory available in bytes.",
-			nil, nil,
-		),
-		rss: NewDesc(
-			ns+"process_resident_memory_bytes",
-			"Resident memory size in bytes.",
-			nil, nil,
-		),
-		startTime: NewDesc(
-			ns+"process_start_time_seconds",
-			"Start time of the process since unix epoch in seconds.",
-			nil, nil,
-		),
-	}
-
-	if opts.PidFn == nil {
-		pid := os.Getpid()
-		c.pidFn = func() (int, error) { return pid, nil }
-	} else {
-		c.pidFn = opts.PidFn
-	}
-
-	// Set up process metric collection if supported by the runtime.
-	if _, err := procfs.NewStat(); err == nil {
-		c.collectFn = c.processCollect
-	} else {
-		c.collectFn = func(ch chan<- Metric) {
-			c.reportError(ch, nil, errors.New("process metrics not supported on this platform"))
-		}
-	}
-
-	return c
-}
-
-// Describe returns all descriptions of the collector.
-func (c *processCollector) Describe(ch chan<- *Desc) {
-	ch <- c.cpuTotal
-	ch <- c.openFDs
-	ch <- c.maxFDs
-	ch <- c.vsize
-	ch <- c.maxVsize
-	ch <- c.rss
-	ch <- c.startTime
-}
-
-// Collect returns the current state of all metrics of the collector.
-func (c *processCollector) Collect(ch chan<- Metric) {
-	c.collectFn(ch)
-}
-
-func (c *processCollector) processCollect(ch chan<- Metric) {
-	pid, err := c.pidFn()
-	if err != nil {
-		c.reportError(ch, nil, err)
-		return
-	}
-
-	p, err := procfs.NewProc(pid)
-	if err != nil {
-		c.reportError(ch, nil, err)
-		return
-	}
-
-	if stat, err := p.NewStat(); err == nil {
-		ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
-		ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
-		ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
-		if startTime, err := stat.StartTime(); err == nil {
-			ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
-		} else {
-			c.reportError(ch, c.startTime, err)
-		}
-	} else {
-		c.reportError(ch, nil, err)
-	}
-
-	if fds, err := p.FileDescriptorsLen(); err == nil {
-		ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
-	} else {
-		c.reportError(ch, c.openFDs, err)
-	}
-
-	if limits, err := p.NewLimits(); err == nil {
-		ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
-		ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(limits.AddressSpace))
-	} else {
-		c.reportError(ch, nil, err)
-	}
-}
-
-func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) {
-	if !c.reportErrors {
-		return
-	}
-	if desc == nil {
-		desc = NewInvalidDesc(err)
-	}
-	ch <- NewInvalidMetric(desc, err)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
deleted file mode 100644
index 67b56d3..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
-	"bufio"
-	"io"
-	"net"
-	"net/http"
-)
-
-const (
-	closeNotifier = 1 << iota
-	flusher
-	hijacker
-	readerFrom
-	pusher
-)
-
-type delegator interface {
-	http.ResponseWriter
-
-	Status() int
-	Written() int64
-}
-
-type responseWriterDelegator struct {
-	http.ResponseWriter
-
-	handler, method    string
-	status             int
-	written            int64
-	wroteHeader        bool
-	observeWriteHeader func(int)
-}
-
-func (r *responseWriterDelegator) Status() int {
-	return r.status
-}
-
-func (r *responseWriterDelegator) Written() int64 {
-	return r.written
-}
-
-func (r *responseWriterDelegator) WriteHeader(code int) {
-	r.status = code
-	r.wroteHeader = true
-	r.ResponseWriter.WriteHeader(code)
-	if r.observeWriteHeader != nil {
-		r.observeWriteHeader(code)
-	}
-}
-
-func (r *responseWriterDelegator) Write(b []byte) (int, error) {
-	if !r.wroteHeader {
-		r.WriteHeader(http.StatusOK)
-	}
-	n, err := r.ResponseWriter.Write(b)
-	r.written += int64(n)
-	return n, err
-}
-
-type closeNotifierDelegator struct{ *responseWriterDelegator }
-type flusherDelegator struct{ *responseWriterDelegator }
-type hijackerDelegator struct{ *responseWriterDelegator }
-type readerFromDelegator struct{ *responseWriterDelegator }
-
-func (d closeNotifierDelegator) CloseNotify() <-chan bool {
-	return d.ResponseWriter.(http.CloseNotifier).CloseNotify()
-}
-func (d flusherDelegator) Flush() {
-	d.ResponseWriter.(http.Flusher).Flush()
-}
-func (d hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
-	return d.ResponseWriter.(http.Hijacker).Hijack()
-}
-func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) {
-	if !d.wroteHeader {
-		d.WriteHeader(http.StatusOK)
-	}
-	n, err := d.ResponseWriter.(io.ReaderFrom).ReadFrom(re)
-	d.written += n
-	return n, err
-}
-
-var pickDelegator = make([]func(*responseWriterDelegator) delegator, 32)
-
-func init() {
-	// TODO(beorn7): Code generation would help here.
-	pickDelegator[0] = func(d *responseWriterDelegator) delegator { // 0
-		return d
-	}
-	pickDelegator[closeNotifier] = func(d *responseWriterDelegator) delegator { // 1
-		return closeNotifierDelegator{d}
-	}
-	pickDelegator[flusher] = func(d *responseWriterDelegator) delegator { // 2
-		return flusherDelegator{d}
-	}
-	pickDelegator[flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 3
-		return struct {
-			*responseWriterDelegator
-			http.Flusher
-			http.CloseNotifier
-		}{d, flusherDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[hijacker] = func(d *responseWriterDelegator) delegator { // 4
-		return hijackerDelegator{d}
-	}
-	pickDelegator[hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 5
-		return struct {
-			*responseWriterDelegator
-			http.Hijacker
-			http.CloseNotifier
-		}{d, hijackerDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 6
-		return struct {
-			*responseWriterDelegator
-			http.Hijacker
-			http.Flusher
-		}{d, hijackerDelegator{d}, flusherDelegator{d}}
-	}
-	pickDelegator[hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 7
-		return struct {
-			*responseWriterDelegator
-			http.Hijacker
-			http.Flusher
-			http.CloseNotifier
-		}{d, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[readerFrom] = func(d *responseWriterDelegator) delegator { // 8
-		return readerFromDelegator{d}
-	}
-	pickDelegator[readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 9
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.CloseNotifier
-		}{d, readerFromDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 10
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Flusher
-		}{d, readerFromDelegator{d}, flusherDelegator{d}}
-	}
-	pickDelegator[readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 11
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Flusher
-			http.CloseNotifier
-		}{d, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 12
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Hijacker
-		}{d, readerFromDelegator{d}, hijackerDelegator{d}}
-	}
-	pickDelegator[readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 13
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Hijacker
-			http.CloseNotifier
-		}{d, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 14
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Hijacker
-			http.Flusher
-		}{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
-	}
-	pickDelegator[readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 15
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Hijacker
-			http.Flusher
-			http.CloseNotifier
-		}{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
-	}
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
deleted file mode 100644
index 31a7069..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build go1.8
-
-package promhttp
-
-import (
-	"io"
-	"net/http"
-)
-
-type pusherDelegator struct{ *responseWriterDelegator }
-
-func (d pusherDelegator) Push(target string, opts *http.PushOptions) error {
-	return d.ResponseWriter.(http.Pusher).Push(target, opts)
-}
-
-func init() {
-	pickDelegator[pusher] = func(d *responseWriterDelegator) delegator { // 16
-		return pusherDelegator{d}
-	}
-	pickDelegator[pusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 17
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.CloseNotifier
-		}{d, pusherDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+flusher] = func(d *responseWriterDelegator) delegator { // 18
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Flusher
-		}{d, pusherDelegator{d}, flusherDelegator{d}}
-	}
-	pickDelegator[pusher+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 19
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Flusher
-			http.CloseNotifier
-		}{d, pusherDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+hijacker] = func(d *responseWriterDelegator) delegator { // 20
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Hijacker
-		}{d, pusherDelegator{d}, hijackerDelegator{d}}
-	}
-	pickDelegator[pusher+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 21
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Hijacker
-			http.CloseNotifier
-		}{d, pusherDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 22
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Hijacker
-			http.Flusher
-		}{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
-	}
-	pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { //23
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Hijacker
-			http.Flusher
-			http.CloseNotifier
-		}{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom] = func(d *responseWriterDelegator) delegator { // 24
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-		}{d, pusherDelegator{d}, readerFromDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 25
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.CloseNotifier
-		}{d, pusherDelegator{d}, readerFromDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 26
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Flusher
-		}{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 27
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Flusher
-			http.CloseNotifier
-		}{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 28
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Hijacker
-		}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 29
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Hijacker
-			http.CloseNotifier
-		}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 30
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Hijacker
-			http.Flusher
-		}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 31
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Hijacker
-			http.Flusher
-			http.CloseNotifier
-		}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
-	}
-}
-
-func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
-	d := &responseWriterDelegator{
-		ResponseWriter:     w,
-		observeWriteHeader: observeWriteHeaderFunc,
-	}
-
-	id := 0
-	if _, ok := w.(http.CloseNotifier); ok {
-		id += closeNotifier
-	}
-	if _, ok := w.(http.Flusher); ok {
-		id += flusher
-	}
-	if _, ok := w.(http.Hijacker); ok {
-		id += hijacker
-	}
-	if _, ok := w.(io.ReaderFrom); ok {
-		id += readerFrom
-	}
-	if _, ok := w.(http.Pusher); ok {
-		id += pusher
-	}
-
-	return pickDelegator[id](d)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_pre_1_8.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_pre_1_8.go
deleted file mode 100644
index 8bb9b8b..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_pre_1_8.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !go1.8
-
-package promhttp
-
-import (
-	"io"
-	"net/http"
-)
-
-func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
-	d := &responseWriterDelegator{
-		ResponseWriter:     w,
-		observeWriteHeader: observeWriteHeaderFunc,
-	}
-
-	id := 0
-	if _, ok := w.(http.CloseNotifier); ok {
-		id += closeNotifier
-	}
-	if _, ok := w.(http.Flusher); ok {
-		id += flusher
-	}
-	if _, ok := w.(http.Hijacker); ok {
-		id += hijacker
-	}
-	if _, ok := w.(io.ReaderFrom); ok {
-		id += readerFrom
-	}
-
-	return pickDelegator[id](d)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
deleted file mode 100644
index 668eb6b..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2016 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package promhttp provides tooling around HTTP servers and clients.
-//
-// First, the package allows the creation of http.Handler instances to expose
-// Prometheus metrics via HTTP. promhttp.Handler acts on the
-// prometheus.DefaultGatherer. With HandlerFor, you can create a handler for a
-// custom registry or anything that implements the Gatherer interface. It also
-// allows the creation of handlers that act differently on errors or allow to
-// log errors.
-//
-// Second, the package provides tooling to instrument instances of http.Handler
-// via middleware. Middleware wrappers follow the naming scheme
-// InstrumentHandlerX, where X describes the intended use of the middleware.
-// See each function's doc comment for specific details.
-//
-// Finally, the package allows for an http.RoundTripper to be instrumented via
-// middleware. Middleware wrappers follow the naming scheme
-// InstrumentRoundTripperX, where X describes the intended use of the
-// middleware. See each function's doc comment for specific details.
-package promhttp
-
-import (
-	"compress/gzip"
-	"fmt"
-	"io"
-	"net/http"
-	"strings"
-	"sync"
-	"time"
-
-	"github.com/prometheus/common/expfmt"
-
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-const (
-	contentTypeHeader     = "Content-Type"
-	contentLengthHeader   = "Content-Length"
-	contentEncodingHeader = "Content-Encoding"
-	acceptEncodingHeader  = "Accept-Encoding"
-)
-
-var gzipPool = sync.Pool{
-	New: func() interface{} {
-		return gzip.NewWriter(nil)
-	},
-}
-
-// Handler returns an http.Handler for the prometheus.DefaultGatherer, using
-// default HandlerOpts, i.e. it reports the first error as an HTTP error, it has
-// no error logging, and it applies compression if requested by the client.
-//
-// The returned http.Handler is already instrumented using the
-// InstrumentMetricHandler function and the prometheus.DefaultRegisterer. If you
-// create multiple http.Handlers by separate calls of the Handler function, the
-// metrics used for instrumentation will be shared between them, providing
-// global scrape counts.
-//
-// This function is meant to cover the bulk of basic use cases. If you are doing
-// anything that requires more customization (including using a non-default
-// Gatherer, different instrumentation, and non-default HandlerOpts), use the
-// HandlerFor function. See there for details.
-func Handler() http.Handler {
-	return InstrumentMetricHandler(
-		prometheus.DefaultRegisterer, HandlerFor(prometheus.DefaultGatherer, HandlerOpts{}),
-	)
-}
-
-// HandlerFor returns an uninstrumented http.Handler for the provided
-// Gatherer. The behavior of the Handler is defined by the provided
-// HandlerOpts. Thus, HandlerFor is useful to create http.Handlers for custom
-// Gatherers, with non-default HandlerOpts, and/or with custom (or no)
-// instrumentation. Use the InstrumentMetricHandler function to apply the same
-// kind of instrumentation as it is used by the Handler function.
-func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
-	var inFlightSem chan struct{}
-	if opts.MaxRequestsInFlight > 0 {
-		inFlightSem = make(chan struct{}, opts.MaxRequestsInFlight)
-	}
-
-	h := http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {
-		if inFlightSem != nil {
-			select {
-			case inFlightSem <- struct{}{}: // All good, carry on.
-				defer func() { <-inFlightSem }()
-			default:
-				http.Error(rsp, fmt.Sprintf(
-					"Limit of concurrent requests reached (%d), try again later.", opts.MaxRequestsInFlight,
-				), http.StatusServiceUnavailable)
-				return
-			}
-		}
-		mfs, err := reg.Gather()
-		if err != nil {
-			if opts.ErrorLog != nil {
-				opts.ErrorLog.Println("error gathering metrics:", err)
-			}
-			switch opts.ErrorHandling {
-			case PanicOnError:
-				panic(err)
-			case ContinueOnError:
-				if len(mfs) == 0 {
-					// Still report the error if no metrics have been gathered.
-					httpError(rsp, err)
-					return
-				}
-			case HTTPErrorOnError:
-				httpError(rsp, err)
-				return
-			}
-		}
-
-		contentType := expfmt.Negotiate(req.Header)
-		header := rsp.Header()
-		header.Set(contentTypeHeader, string(contentType))
-
-		w := io.Writer(rsp)
-		if !opts.DisableCompression && gzipAccepted(req.Header) {
-			header.Set(contentEncodingHeader, "gzip")
-			gz := gzipPool.Get().(*gzip.Writer)
-			defer gzipPool.Put(gz)
-
-			gz.Reset(w)
-			defer gz.Close()
-
-			w = gz
-		}
-
-		enc := expfmt.NewEncoder(w, contentType)
-
-		var lastErr error
-		for _, mf := range mfs {
-			if err := enc.Encode(mf); err != nil {
-				lastErr = err
-				if opts.ErrorLog != nil {
-					opts.ErrorLog.Println("error encoding and sending metric family:", err)
-				}
-				switch opts.ErrorHandling {
-				case PanicOnError:
-					panic(err)
-				case ContinueOnError:
-					// Handled later.
-				case HTTPErrorOnError:
-					httpError(rsp, err)
-					return
-				}
-			}
-		}
-
-		if lastErr != nil {
-			httpError(rsp, lastErr)
-		}
-	})
-
-	if opts.Timeout <= 0 {
-		return h
-	}
-	return http.TimeoutHandler(h, opts.Timeout, fmt.Sprintf(
-		"Exceeded configured timeout of %v.\n",
-		opts.Timeout,
-	))
-}
-
-// InstrumentMetricHandler is usually used with an http.Handler returned by the
-// HandlerFor function. It instruments the provided http.Handler with two
-// metrics: A counter vector "promhttp_metric_handler_requests_total" to count
-// scrapes partitioned by HTTP status code, and a gauge
-// "promhttp_metric_handler_requests_in_flight" to track the number of
-// simultaneous scrapes. This function idempotently registers collectors for
-// both metrics with the provided Registerer. It panics if the registration
-// fails. The provided metrics are useful to see how many scrapes hit the
-// monitored target (which could be from different Prometheus servers or other
-// scrapers), and how often they overlap (which would result in more than one
-// scrape in flight at the same time). Note that the scrapes-in-flight gauge
-// will contain the scrape by which it is exposed, while the scrape counter will
-// only get incremented after the scrape is complete (as only then the status
-// code is known). For tracking scrape durations, use the
-// "scrape_duration_seconds" gauge created by the Prometheus server upon each
-// scrape.
-func InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) http.Handler {
-	cnt := prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Name: "promhttp_metric_handler_requests_total",
-			Help: "Total number of scrapes by HTTP status code.",
-		},
-		[]string{"code"},
-	)
-	// Initialize the most likely HTTP status codes.
-	cnt.WithLabelValues("200")
-	cnt.WithLabelValues("500")
-	cnt.WithLabelValues("503")
-	if err := reg.Register(cnt); err != nil {
-		if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
-			cnt = are.ExistingCollector.(*prometheus.CounterVec)
-		} else {
-			panic(err)
-		}
-	}
-
-	gge := prometheus.NewGauge(prometheus.GaugeOpts{
-		Name: "promhttp_metric_handler_requests_in_flight",
-		Help: "Current number of scrapes being served.",
-	})
-	if err := reg.Register(gge); err != nil {
-		if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
-			gge = are.ExistingCollector.(prometheus.Gauge)
-		} else {
-			panic(err)
-		}
-	}
-
-	return InstrumentHandlerCounter(cnt, InstrumentHandlerInFlight(gge, handler))
-}
-
-// HandlerErrorHandling defines how a Handler serving metrics will handle
-// errors.
-type HandlerErrorHandling int
-
-// These constants cause handlers serving metrics to behave as described if
-// errors are encountered.
-const (
-	// Serve an HTTP status code 500 upon the first error
-	// encountered. Report the error message in the body.
-	HTTPErrorOnError HandlerErrorHandling = iota
-	// Ignore errors and try to serve as many metrics as possible.  However,
-	// if no metrics can be served, serve an HTTP status code 500 and the
-	// last error message in the body. Only use this in deliberate "best
-	// effort" metrics collection scenarios. It is recommended to at least
-	// log errors (by providing an ErrorLog in HandlerOpts) to not mask
-	// errors completely.
-	ContinueOnError
-	// Panic upon the first error encountered (useful for "crash only" apps).
-	PanicOnError
-)
-
-// Logger is the minimal interface HandlerOpts needs for logging. Note that
-// log.Logger from the standard library implements this interface, and it is
-// easy to implement by custom loggers, if they don't do so already anyway.
-type Logger interface {
-	Println(v ...interface{})
-}
-
-// HandlerOpts specifies options how to serve metrics via an http.Handler. The
-// zero value of HandlerOpts is a reasonable default.
-type HandlerOpts struct {
-	// ErrorLog specifies an optional logger for errors collecting and
-	// serving metrics. If nil, errors are not logged at all.
-	ErrorLog Logger
-	// ErrorHandling defines how errors are handled. Note that errors are
-	// logged regardless of the configured ErrorHandling provided ErrorLog
-	// is not nil.
-	ErrorHandling HandlerErrorHandling
-	// If DisableCompression is true, the handler will never compress the
-	// response, even if requested by the client.
-	DisableCompression bool
-	// The number of concurrent HTTP requests is limited to
-	// MaxRequestsInFlight. Additional requests are responded to with 503
-	// Service Unavailable and a suitable message in the body. If
-	// MaxRequestsInFlight is 0 or negative, no limit is applied.
-	MaxRequestsInFlight int
-	// If handling a request takes longer than Timeout, it is responded to
-	// with 503 ServiceUnavailable and a suitable Message. No timeout is
-	// applied if Timeout is 0 or negative. Note that with the current
-	// implementation, reaching the timeout simply ends the HTTP requests as
-	// described above (and even that only if sending of the body hasn't
-	// started yet), while the bulk work of gathering all the metrics keeps
-	// running in the background (with the eventual result to be thrown
-	// away). Until the implementation is improved, it is recommended to
-	// implement a separate timeout in potentially slow Collectors.
-	Timeout time.Duration
-}
-
-// gzipAccepted returns whether the client will accept gzip-encoded content.
-func gzipAccepted(header http.Header) bool {
-	a := header.Get(acceptEncodingHeader)
-	parts := strings.Split(a, ",")
-	for _, part := range parts {
-		part = strings.TrimSpace(part)
-		if part == "gzip" || strings.HasPrefix(part, "gzip;") {
-			return true
-		}
-	}
-	return false
-}
-
-// httpError removes any content-encoding header and then calls http.Error with
-// the provided error and http.StatusInternalServerErrer. Error contents is
-// supposed to be uncompressed plain text. However, same as with a plain
-// http.Error, any header settings will be void if the header has already been
-// sent. The error message will still be written to the writer, but it will
-// probably be of limited use.
-func httpError(rsp http.ResponseWriter, err error) {
-	rsp.Header().Del(contentEncodingHeader)
-	http.Error(
-		rsp,
-		"An error has occurred while serving metrics:\n\n"+err.Error(),
-		http.StatusInternalServerError,
-	)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
deleted file mode 100644
index 86fd564..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
-	"net/http"
-	"time"
-
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-// The RoundTripperFunc type is an adapter to allow the use of ordinary
-// functions as RoundTrippers. If f is a function with the appropriate
-// signature, RountTripperFunc(f) is a RoundTripper that calls f.
-type RoundTripperFunc func(req *http.Request) (*http.Response, error)
-
-// RoundTrip implements the RoundTripper interface.
-func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
-	return rt(r)
-}
-
-// InstrumentRoundTripperInFlight is a middleware that wraps the provided
-// http.RoundTripper. It sets the provided prometheus.Gauge to the number of
-// requests currently handled by the wrapped http.RoundTripper.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc {
-	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
-		gauge.Inc()
-		defer gauge.Dec()
-		return next.RoundTrip(r)
-	})
-}
-
-// InstrumentRoundTripperCounter is a middleware that wraps the provided
-// http.RoundTripper to observe the request result with the provided CounterVec.
-// The CounterVec must have zero, one, or two non-const non-curried labels. For
-// those, the only allowed label names are "code" and "method". The function
-// panics otherwise. Partitioning of the CounterVec happens by HTTP status code
-// and/or HTTP method if the respective instance label names are present in the
-// CounterVec. For unpartitioned counting, use a CounterVec with zero labels.
-//
-// If the wrapped RoundTripper panics or returns a non-nil error, the Counter
-// is not incremented.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper) RoundTripperFunc {
-	code, method := checkLabels(counter)
-
-	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
-		resp, err := next.RoundTrip(r)
-		if err == nil {
-			counter.With(labels(code, method, r.Method, resp.StatusCode)).Inc()
-		}
-		return resp, err
-	})
-}
-
-// InstrumentRoundTripperDuration is a middleware that wraps the provided
-// http.RoundTripper to observe the request duration with the provided
-// ObserverVec.  The ObserverVec must have zero, one, or two non-const
-// non-curried labels. For those, the only allowed label names are "code" and
-// "method". The function panics otherwise. The Observe method of the Observer
-// in the ObserverVec is called with the request duration in
-// seconds. Partitioning happens by HTTP status code and/or HTTP method if the
-// respective instance label names are present in the ObserverVec. For
-// unpartitioned observations, use an ObserverVec with zero labels. Note that
-// partitioning of Histograms is expensive and should be used judiciously.
-//
-// If the wrapped RoundTripper panics or returns a non-nil error, no values are
-// reported.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper) RoundTripperFunc {
-	code, method := checkLabels(obs)
-
-	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
-		start := time.Now()
-		resp, err := next.RoundTrip(r)
-		if err == nil {
-			obs.With(labels(code, method, r.Method, resp.StatusCode)).Observe(time.Since(start).Seconds())
-		}
-		return resp, err
-	})
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go
deleted file mode 100644
index a034d1e..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build go1.8
-
-package promhttp
-
-import (
-	"context"
-	"crypto/tls"
-	"net/http"
-	"net/http/httptrace"
-	"time"
-)
-
-// InstrumentTrace is used to offer flexibility in instrumenting the available
-// httptrace.ClientTrace hook functions. Each function is passed a float64
-// representing the time in seconds since the start of the http request. A user
-// may choose to use separately buckets Histograms, or implement custom
-// instance labels on a per function basis.
-type InstrumentTrace struct {
-	GotConn              func(float64)
-	PutIdleConn          func(float64)
-	GotFirstResponseByte func(float64)
-	Got100Continue       func(float64)
-	DNSStart             func(float64)
-	DNSDone              func(float64)
-	ConnectStart         func(float64)
-	ConnectDone          func(float64)
-	TLSHandshakeStart    func(float64)
-	TLSHandshakeDone     func(float64)
-	WroteHeaders         func(float64)
-	Wait100Continue      func(float64)
-	WroteRequest         func(float64)
-}
-
-// InstrumentRoundTripperTrace is a middleware that wraps the provided
-// RoundTripper and reports times to hook functions provided in the
-// InstrumentTrace struct. Hook functions that are not present in the provided
-// InstrumentTrace struct are ignored. Times reported to the hook functions are
-// time since the start of the request. Only with Go1.9+, those times are
-// guaranteed to never be negative. (Earlier Go versions are not using a
-// monotonic clock.) Note that partitioning of Histograms is expensive and
-// should be used judiciously.
-//
-// For hook functions that receive an error as an argument, no observations are
-// made in the event of a non-nil error value.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc {
-	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
-		start := time.Now()
-
-		trace := &httptrace.ClientTrace{
-			GotConn: func(_ httptrace.GotConnInfo) {
-				if it.GotConn != nil {
-					it.GotConn(time.Since(start).Seconds())
-				}
-			},
-			PutIdleConn: func(err error) {
-				if err != nil {
-					return
-				}
-				if it.PutIdleConn != nil {
-					it.PutIdleConn(time.Since(start).Seconds())
-				}
-			},
-			DNSStart: func(_ httptrace.DNSStartInfo) {
-				if it.DNSStart != nil {
-					it.DNSStart(time.Since(start).Seconds())
-				}
-			},
-			DNSDone: func(_ httptrace.DNSDoneInfo) {
-				if it.DNSDone != nil {
-					it.DNSDone(time.Since(start).Seconds())
-				}
-			},
-			ConnectStart: func(_, _ string) {
-				if it.ConnectStart != nil {
-					it.ConnectStart(time.Since(start).Seconds())
-				}
-			},
-			ConnectDone: func(_, _ string, err error) {
-				if err != nil {
-					return
-				}
-				if it.ConnectDone != nil {
-					it.ConnectDone(time.Since(start).Seconds())
-				}
-			},
-			GotFirstResponseByte: func() {
-				if it.GotFirstResponseByte != nil {
-					it.GotFirstResponseByte(time.Since(start).Seconds())
-				}
-			},
-			Got100Continue: func() {
-				if it.Got100Continue != nil {
-					it.Got100Continue(time.Since(start).Seconds())
-				}
-			},
-			TLSHandshakeStart: func() {
-				if it.TLSHandshakeStart != nil {
-					it.TLSHandshakeStart(time.Since(start).Seconds())
-				}
-			},
-			TLSHandshakeDone: func(_ tls.ConnectionState, err error) {
-				if err != nil {
-					return
-				}
-				if it.TLSHandshakeDone != nil {
-					it.TLSHandshakeDone(time.Since(start).Seconds())
-				}
-			},
-			WroteHeaders: func() {
-				if it.WroteHeaders != nil {
-					it.WroteHeaders(time.Since(start).Seconds())
-				}
-			},
-			Wait100Continue: func() {
-				if it.Wait100Continue != nil {
-					it.Wait100Continue(time.Since(start).Seconds())
-				}
-			},
-			WroteRequest: func(_ httptrace.WroteRequestInfo) {
-				if it.WroteRequest != nil {
-					it.WroteRequest(time.Since(start).Seconds())
-				}
-			},
-		}
-		r = r.WithContext(httptrace.WithClientTrace(context.Background(), trace))
-
-		return next.RoundTrip(r)
-	})
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
deleted file mode 100644
index 9db2438..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
+++ /dev/null
@@ -1,447 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
-	"errors"
-	"net/http"
-	"strconv"
-	"strings"
-	"time"
-
-	dto "github.com/prometheus/client_model/go"
-
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-// magicString is used for the hacky label test in checkLabels. Remove once fixed.
-const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa"
-
-// InstrumentHandlerInFlight is a middleware that wraps the provided
-// http.Handler. It sets the provided prometheus.Gauge to the number of
-// requests currently handled by the wrapped http.Handler.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		g.Inc()
-		defer g.Dec()
-		next.ServeHTTP(w, r)
-	})
-}
-
-// InstrumentHandlerDuration is a middleware that wraps the provided
-// http.Handler to observe the request duration with the provided ObserverVec.
-// The ObserverVec must have zero, one, or two non-const non-curried labels. For
-// those, the only allowed label names are "code" and "method". The function
-// panics otherwise. The Observe method of the Observer in the ObserverVec is
-// called with the request duration in seconds. Partitioning happens by HTTP
-// status code and/or HTTP method if the respective instance label names are
-// present in the ObserverVec. For unpartitioned observations, use an
-// ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
-	code, method := checkLabels(obs)
-
-	if code {
-		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			now := time.Now()
-			d := newDelegator(w, nil)
-			next.ServeHTTP(d, r)
-
-			obs.With(labels(code, method, r.Method, d.Status())).Observe(time.Since(now).Seconds())
-		})
-	}
-
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		now := time.Now()
-		next.ServeHTTP(w, r)
-		obs.With(labels(code, method, r.Method, 0)).Observe(time.Since(now).Seconds())
-	})
-}
-
-// InstrumentHandlerCounter is a middleware that wraps the provided http.Handler
-// to observe the request result with the provided CounterVec.  The CounterVec
-// must have zero, one, or two non-const non-curried labels. For those, the only
-// allowed label names are "code" and "method". The function panics
-// otherwise. Partitioning of the CounterVec happens by HTTP status code and/or
-// HTTP method if the respective instance label names are present in the
-// CounterVec. For unpartitioned counting, use a CounterVec with zero labels.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, the Counter is not incremented.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler) http.HandlerFunc {
-	code, method := checkLabels(counter)
-
-	if code {
-		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			d := newDelegator(w, nil)
-			next.ServeHTTP(d, r)
-			counter.With(labels(code, method, r.Method, d.Status())).Inc()
-		})
-	}
-
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		next.ServeHTTP(w, r)
-		counter.With(labels(code, method, r.Method, 0)).Inc()
-	})
-}
-
-// InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided
-// http.Handler to observe with the provided ObserverVec the request duration
-// until the response headers are written. The ObserverVec must have zero, one,
-// or two non-const non-curried labels. For those, the only allowed label names
-// are "code" and "method". The function panics otherwise. The Observe method of
-// the Observer in the ObserverVec is called with the request duration in
-// seconds. Partitioning happens by HTTP status code and/or HTTP method if the
-// respective instance label names are present in the ObserverVec. For
-// unpartitioned observations, use an ObserverVec with zero labels. Note that
-// partitioning of Histograms is expensive and should be used judiciously.
-//
-// If the wrapped Handler panics before calling WriteHeader, no value is
-// reported.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
-	code, method := checkLabels(obs)
-
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		now := time.Now()
-		d := newDelegator(w, func(status int) {
-			obs.With(labels(code, method, r.Method, status)).Observe(time.Since(now).Seconds())
-		})
-		next.ServeHTTP(d, r)
-	})
-}
-
-// InstrumentHandlerRequestSize is a middleware that wraps the provided
-// http.Handler to observe the request size with the provided ObserverVec.  The
-// ObserverVec must have zero, one, or two non-const non-curried labels. For
-// those, the only allowed label names are "code" and "method". The function
-// panics otherwise. The Observe method of the Observer in the ObserverVec is
-// called with the request size in bytes. Partitioning happens by HTTP status
-// code and/or HTTP method if the respective instance label names are present in
-// the ObserverVec. For unpartitioned observations, use an ObserverVec with zero
-// labels. Note that partitioning of Histograms is expensive and should be used
-// judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
-	code, method := checkLabels(obs)
-
-	if code {
-		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			d := newDelegator(w, nil)
-			next.ServeHTTP(d, r)
-			size := computeApproximateRequestSize(r)
-			obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(size))
-		})
-	}
-
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		next.ServeHTTP(w, r)
-		size := computeApproximateRequestSize(r)
-		obs.With(labels(code, method, r.Method, 0)).Observe(float64(size))
-	})
-}
-
-// InstrumentHandlerResponseSize is a middleware that wraps the provided
-// http.Handler to observe the response size with the provided ObserverVec.  The
-// ObserverVec must have zero, one, or two non-const non-curried labels. For
-// those, the only allowed label names are "code" and "method". The function
-// panics otherwise. The Observe method of the Observer in the ObserverVec is
-// called with the response size in bytes. Partitioning happens by HTTP status
-// code and/or HTTP method if the respective instance label names are present in
-// the ObserverVec. For unpartitioned observations, use an ObserverVec with zero
-// labels. Note that partitioning of Histograms is expensive and should be used
-// judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler) http.Handler {
-	code, method := checkLabels(obs)
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		d := newDelegator(w, nil)
-		next.ServeHTTP(d, r)
-		obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(d.Written()))
-	})
-}
-
-func checkLabels(c prometheus.Collector) (code bool, method bool) {
-	// TODO(beorn7): Remove this hacky way to check for instance labels
-	// once Descriptors can have their dimensionality queried.
-	var (
-		desc *prometheus.Desc
-		m    prometheus.Metric
-		pm   dto.Metric
-		lvs  []string
-	)
-
-	// Get the Desc from the Collector.
-	descc := make(chan *prometheus.Desc, 1)
-	c.Describe(descc)
-
-	select {
-	case desc = <-descc:
-	default:
-		panic("no description provided by collector")
-	}
-	select {
-	case <-descc:
-		panic("more than one description provided by collector")
-	default:
-	}
-
-	close(descc)
-
-	// Create a ConstMetric with the Desc. Since we don't know how many
-	// variable labels there are, try for as long as it needs.
-	for err := errors.New("dummy"); err != nil; lvs = append(lvs, magicString) {
-		m, err = prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, lvs...)
-	}
-
-	// Write out the metric into a proto message and look at the labels.
-	// If the value is not the magicString, it is a constLabel, which doesn't interest us.
-	// If the label is curried, it doesn't interest us.
-	// In all other cases, only "code" or "method" is allowed.
-	if err := m.Write(&pm); err != nil {
-		panic("error checking metric for labels")
-	}
-	for _, label := range pm.Label {
-		name, value := label.GetName(), label.GetValue()
-		if value != magicString || isLabelCurried(c, name) {
-			continue
-		}
-		switch name {
-		case "code":
-			code = true
-		case "method":
-			method = true
-		default:
-			panic("metric partitioned with non-supported labels")
-		}
-	}
-	return
-}
-
-func isLabelCurried(c prometheus.Collector, label string) bool {
-	// This is even hackier than the label test above.
-	// We essentially try to curry again and see if it works.
-	// But for that, we need to type-convert to the two
-	// types we use here, ObserverVec or *CounterVec.
-	switch v := c.(type) {
-	case *prometheus.CounterVec:
-		if _, err := v.CurryWith(prometheus.Labels{label: "dummy"}); err == nil {
-			return false
-		}
-	case prometheus.ObserverVec:
-		if _, err := v.CurryWith(prometheus.Labels{label: "dummy"}); err == nil {
-			return false
-		}
-	default:
-		panic("unsupported metric vec type")
-	}
-	return true
-}
-
-// emptyLabels is a one-time allocation for non-partitioned metrics to avoid
-// unnecessary allocations on each request.
-var emptyLabels = prometheus.Labels{}
-
-func labels(code, method bool, reqMethod string, status int) prometheus.Labels {
-	if !(code || method) {
-		return emptyLabels
-	}
-	labels := prometheus.Labels{}
-
-	if code {
-		labels["code"] = sanitizeCode(status)
-	}
-	if method {
-		labels["method"] = sanitizeMethod(reqMethod)
-	}
-
-	return labels
-}
-
-func computeApproximateRequestSize(r *http.Request) int {
-	s := 0
-	if r.URL != nil {
-		s += len(r.URL.String())
-	}
-
-	s += len(r.Method)
-	s += len(r.Proto)
-	for name, values := range r.Header {
-		s += len(name)
-		for _, value := range values {
-			s += len(value)
-		}
-	}
-	s += len(r.Host)
-
-	// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
-
-	if r.ContentLength != -1 {
-		s += int(r.ContentLength)
-	}
-	return s
-}
-
-func sanitizeMethod(m string) string {
-	switch m {
-	case "GET", "get":
-		return "get"
-	case "PUT", "put":
-		return "put"
-	case "HEAD", "head":
-		return "head"
-	case "POST", "post":
-		return "post"
-	case "DELETE", "delete":
-		return "delete"
-	case "CONNECT", "connect":
-		return "connect"
-	case "OPTIONS", "options":
-		return "options"
-	case "NOTIFY", "notify":
-		return "notify"
-	default:
-		return strings.ToLower(m)
-	}
-}
-
-// If the wrapped http.Handler has not set a status code, i.e. the value is
-// currently 0, santizeCode will return 200, for consistency with behavior in
-// the stdlib.
-func sanitizeCode(s int) string {
-	switch s {
-	case 100:
-		return "100"
-	case 101:
-		return "101"
-
-	case 200, 0:
-		return "200"
-	case 201:
-		return "201"
-	case 202:
-		return "202"
-	case 203:
-		return "203"
-	case 204:
-		return "204"
-	case 205:
-		return "205"
-	case 206:
-		return "206"
-
-	case 300:
-		return "300"
-	case 301:
-		return "301"
-	case 302:
-		return "302"
-	case 304:
-		return "304"
-	case 305:
-		return "305"
-	case 307:
-		return "307"
-
-	case 400:
-		return "400"
-	case 401:
-		return "401"
-	case 402:
-		return "402"
-	case 403:
-		return "403"
-	case 404:
-		return "404"
-	case 405:
-		return "405"
-	case 406:
-		return "406"
-	case 407:
-		return "407"
-	case 408:
-		return "408"
-	case 409:
-		return "409"
-	case 410:
-		return "410"
-	case 411:
-		return "411"
-	case 412:
-		return "412"
-	case 413:
-		return "413"
-	case 414:
-		return "414"
-	case 415:
-		return "415"
-	case 416:
-		return "416"
-	case 417:
-		return "417"
-	case 418:
-		return "418"
-
-	case 500:
-		return "500"
-	case 501:
-		return "501"
-	case 502:
-		return "502"
-	case 503:
-		return "503"
-	case 504:
-		return "504"
-	case 505:
-		return "505"
-
-	case 428:
-		return "428"
-	case 429:
-		return "429"
-	case 431:
-		return "431"
-	case 511:
-		return "511"
-
-	default:
-		return strconv.Itoa(s)
-	}
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go
deleted file mode 100644
index b5e70b9..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go
+++ /dev/null
@@ -1,937 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"bytes"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"runtime"
-	"sort"
-	"strings"
-	"sync"
-	"unicode/utf8"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/prometheus/common/expfmt"
-
-	dto "github.com/prometheus/client_model/go"
-
-	"github.com/prometheus/client_golang/prometheus/internal"
-)
-
-const (
-	// Capacity for the channel to collect metrics and descriptors.
-	capMetricChan = 1000
-	capDescChan   = 10
-)
-
-// DefaultRegisterer and DefaultGatherer are the implementations of the
-// Registerer and Gatherer interface a number of convenience functions in this
-// package act on. Initially, both variables point to the same Registry, which
-// has a process collector (currently on Linux only, see NewProcessCollector)
-// and a Go collector (see NewGoCollector, in particular the note about
-// stop-the-world implication with Go versions older than 1.9) already
-// registered. This approach to keep default instances as global state mirrors
-// the approach of other packages in the Go standard library. Note that there
-// are caveats. Change the variables with caution and only if you understand the
-// consequences. Users who want to avoid global state altogether should not use
-// the convenience functions and act on custom instances instead.
-var (
-	defaultRegistry              = NewRegistry()
-	DefaultRegisterer Registerer = defaultRegistry
-	DefaultGatherer   Gatherer   = defaultRegistry
-)
-
-func init() {
-	MustRegister(NewProcessCollector(ProcessCollectorOpts{}))
-	MustRegister(NewGoCollector())
-}
-
-// NewRegistry creates a new vanilla Registry without any Collectors
-// pre-registered.
-func NewRegistry() *Registry {
-	return &Registry{
-		collectorsByID:  map[uint64]Collector{},
-		descIDs:         map[uint64]struct{}{},
-		dimHashesByName: map[string]uint64{},
-	}
-}
-
-// NewPedanticRegistry returns a registry that checks during collection if each
-// collected Metric is consistent with its reported Desc, and if the Desc has
-// actually been registered with the registry. Unchecked Collectors (those whose
-// Describe methed does not yield any descriptors) are excluded from the check.
-//
-// Usually, a Registry will be happy as long as the union of all collected
-// Metrics is consistent and valid even if some metrics are not consistent with
-// their own Desc or a Desc provided by their registered Collector. Well-behaved
-// Collectors and Metrics will only provide consistent Descs. This Registry is
-// useful to test the implementation of Collectors and Metrics.
-func NewPedanticRegistry() *Registry {
-	r := NewRegistry()
-	r.pedanticChecksEnabled = true
-	return r
-}
-
-// Registerer is the interface for the part of a registry in charge of
-// registering and unregistering. Users of custom registries should use
-// Registerer as type for registration purposes (rather than the Registry type
-// directly). In that way, they are free to use custom Registerer implementation
-// (e.g. for testing purposes).
-type Registerer interface {
-	// Register registers a new Collector to be included in metrics
-	// collection. It returns an error if the descriptors provided by the
-	// Collector are invalid or if they — in combination with descriptors of
-	// already registered Collectors — do not fulfill the consistency and
-	// uniqueness criteria described in the documentation of metric.Desc.
-	//
-	// If the provided Collector is equal to a Collector already registered
-	// (which includes the case of re-registering the same Collector), the
-	// returned error is an instance of AlreadyRegisteredError, which
-	// contains the previously registered Collector.
-	//
-	// A Collector whose Describe method does not yield any Desc is treated
-	// as unchecked. Registration will always succeed. No check for
-	// re-registering (see previous paragraph) is performed. Thus, the
-	// caller is responsible for not double-registering the same unchecked
-	// Collector, and for providing a Collector that will not cause
-	// inconsistent metrics on collection. (This would lead to scrape
-	// errors.)
-	Register(Collector) error
-	// MustRegister works like Register but registers any number of
-	// Collectors and panics upon the first registration that causes an
-	// error.
-	MustRegister(...Collector)
-	// Unregister unregisters the Collector that equals the Collector passed
-	// in as an argument.  (Two Collectors are considered equal if their
-	// Describe method yields the same set of descriptors.) The function
-	// returns whether a Collector was unregistered. Note that an unchecked
-	// Collector cannot be unregistered (as its Describe method does not
-	// yield any descriptor).
-	//
-	// Note that even after unregistering, it will not be possible to
-	// register a new Collector that is inconsistent with the unregistered
-	// Collector, e.g. a Collector collecting metrics with the same name but
-	// a different help string. The rationale here is that the same registry
-	// instance must only collect consistent metrics throughout its
-	// lifetime.
-	Unregister(Collector) bool
-}
-
-// Gatherer is the interface for the part of a registry in charge of gathering
-// the collected metrics into a number of MetricFamilies. The Gatherer interface
-// comes with the same general implication as described for the Registerer
-// interface.
-type Gatherer interface {
-	// Gather calls the Collect method of the registered Collectors and then
-	// gathers the collected metrics into a lexicographically sorted slice
-	// of uniquely named MetricFamily protobufs. Gather ensures that the
-	// returned slice is valid and self-consistent so that it can be used
-	// for valid exposition. As an exception to the strict consistency
-	// requirements described for metric.Desc, Gather will tolerate
-	// different sets of label names for metrics of the same metric family.
-	//
-	// Even if an error occurs, Gather attempts to gather as many metrics as
-	// possible. Hence, if a non-nil error is returned, the returned
-	// MetricFamily slice could be nil (in case of a fatal error that
-	// prevented any meaningful metric collection) or contain a number of
-	// MetricFamily protobufs, some of which might be incomplete, and some
-	// might be missing altogether. The returned error (which might be a
-	// MultiError) explains the details. Note that this is mostly useful for
-	// debugging purposes. If the gathered protobufs are to be used for
-	// exposition in actual monitoring, it is almost always better to not
-	// expose an incomplete result and instead disregard the returned
-	// MetricFamily protobufs in case the returned error is non-nil.
-	Gather() ([]*dto.MetricFamily, error)
-}
-
-// Register registers the provided Collector with the DefaultRegisterer.
-//
-// Register is a shortcut for DefaultRegisterer.Register(c). See there for more
-// details.
-func Register(c Collector) error {
-	return DefaultRegisterer.Register(c)
-}
-
-// MustRegister registers the provided Collectors with the DefaultRegisterer and
-// panics if any error occurs.
-//
-// MustRegister is a shortcut for DefaultRegisterer.MustRegister(cs...). See
-// there for more details.
-func MustRegister(cs ...Collector) {
-	DefaultRegisterer.MustRegister(cs...)
-}
-
-// Unregister removes the registration of the provided Collector from the
-// DefaultRegisterer.
-//
-// Unregister is a shortcut for DefaultRegisterer.Unregister(c). See there for
-// more details.
-func Unregister(c Collector) bool {
-	return DefaultRegisterer.Unregister(c)
-}
-
-// GathererFunc turns a function into a Gatherer.
-type GathererFunc func() ([]*dto.MetricFamily, error)
-
-// Gather implements Gatherer.
-func (gf GathererFunc) Gather() ([]*dto.MetricFamily, error) {
-	return gf()
-}
-
-// AlreadyRegisteredError is returned by the Register method if the Collector to
-// be registered has already been registered before, or a different Collector
-// that collects the same metrics has been registered before. Registration fails
-// in that case, but you can detect from the kind of error what has
-// happened. The error contains fields for the existing Collector and the
-// (rejected) new Collector that equals the existing one. This can be used to
-// find out if an equal Collector has been registered before and switch over to
-// using the old one, as demonstrated in the example.
-type AlreadyRegisteredError struct {
-	ExistingCollector, NewCollector Collector
-}
-
-func (err AlreadyRegisteredError) Error() string {
-	return "duplicate metrics collector registration attempted"
-}
-
-// MultiError is a slice of errors implementing the error interface. It is used
-// by a Gatherer to report multiple errors during MetricFamily gathering.
-type MultiError []error
-
-func (errs MultiError) Error() string {
-	if len(errs) == 0 {
-		return ""
-	}
-	buf := &bytes.Buffer{}
-	fmt.Fprintf(buf, "%d error(s) occurred:", len(errs))
-	for _, err := range errs {
-		fmt.Fprintf(buf, "\n* %s", err)
-	}
-	return buf.String()
-}
-
-// Append appends the provided error if it is not nil.
-func (errs *MultiError) Append(err error) {
-	if err != nil {
-		*errs = append(*errs, err)
-	}
-}
-
-// MaybeUnwrap returns nil if len(errs) is 0. It returns the first and only
-// contained error as error if len(errs is 1). In all other cases, it returns
-// the MultiError directly. This is helpful for returning a MultiError in a way
-// that only uses the MultiError if needed.
-func (errs MultiError) MaybeUnwrap() error {
-	switch len(errs) {
-	case 0:
-		return nil
-	case 1:
-		return errs[0]
-	default:
-		return errs
-	}
-}
-
-// Registry registers Prometheus collectors, collects their metrics, and gathers
-// them into MetricFamilies for exposition. It implements both Registerer and
-// Gatherer. The zero value is not usable. Create instances with NewRegistry or
-// NewPedanticRegistry.
-type Registry struct {
-	mtx                   sync.RWMutex
-	collectorsByID        map[uint64]Collector // ID is a hash of the descIDs.
-	descIDs               map[uint64]struct{}
-	dimHashesByName       map[string]uint64
-	uncheckedCollectors   []Collector
-	pedanticChecksEnabled bool
-}
-
-// Register implements Registerer.
-func (r *Registry) Register(c Collector) error {
-	var (
-		descChan           = make(chan *Desc, capDescChan)
-		newDescIDs         = map[uint64]struct{}{}
-		newDimHashesByName = map[string]uint64{}
-		collectorID        uint64 // Just a sum of all desc IDs.
-		duplicateDescErr   error
-	)
-	go func() {
-		c.Describe(descChan)
-		close(descChan)
-	}()
-	r.mtx.Lock()
-	defer func() {
-		// Drain channel in case of premature return to not leak a goroutine.
-		for range descChan {
-		}
-		r.mtx.Unlock()
-	}()
-	// Conduct various tests...
-	for desc := range descChan {
-
-		// Is the descriptor valid at all?
-		if desc.err != nil {
-			return fmt.Errorf("descriptor %s is invalid: %s", desc, desc.err)
-		}
-
-		// Is the descID unique?
-		// (In other words: Is the fqName + constLabel combination unique?)
-		if _, exists := r.descIDs[desc.id]; exists {
-			duplicateDescErr = fmt.Errorf("descriptor %s already exists with the same fully-qualified name and const label values", desc)
-		}
-		// If it is not a duplicate desc in this collector, add it to
-		// the collectorID.  (We allow duplicate descs within the same
-		// collector, but their existence must be a no-op.)
-		if _, exists := newDescIDs[desc.id]; !exists {
-			newDescIDs[desc.id] = struct{}{}
-			collectorID += desc.id
-		}
-
-		// Are all the label names and the help string consistent with
-		// previous descriptors of the same name?
-		// First check existing descriptors...
-		if dimHash, exists := r.dimHashesByName[desc.fqName]; exists {
-			if dimHash != desc.dimHash {
-				return fmt.Errorf("a previously registered descriptor with the same fully-qualified name as %s has different label names or a different help string", desc)
-			}
-		} else {
-			// ...then check the new descriptors already seen.
-			if dimHash, exists := newDimHashesByName[desc.fqName]; exists {
-				if dimHash != desc.dimHash {
-					return fmt.Errorf("descriptors reported by collector have inconsistent label names or help strings for the same fully-qualified name, offender is %s", desc)
-				}
-			} else {
-				newDimHashesByName[desc.fqName] = desc.dimHash
-			}
-		}
-	}
-	// A Collector yielding no Desc at all is considered unchecked.
-	if len(newDescIDs) == 0 {
-		r.uncheckedCollectors = append(r.uncheckedCollectors, c)
-		return nil
-	}
-	if existing, exists := r.collectorsByID[collectorID]; exists {
-		return AlreadyRegisteredError{
-			ExistingCollector: existing,
-			NewCollector:      c,
-		}
-	}
-	// If the collectorID is new, but at least one of the descs existed
-	// before, we are in trouble.
-	if duplicateDescErr != nil {
-		return duplicateDescErr
-	}
-
-	// Only after all tests have passed, actually register.
-	r.collectorsByID[collectorID] = c
-	for hash := range newDescIDs {
-		r.descIDs[hash] = struct{}{}
-	}
-	for name, dimHash := range newDimHashesByName {
-		r.dimHashesByName[name] = dimHash
-	}
-	return nil
-}
-
-// Unregister implements Registerer.
-func (r *Registry) Unregister(c Collector) bool {
-	var (
-		descChan    = make(chan *Desc, capDescChan)
-		descIDs     = map[uint64]struct{}{}
-		collectorID uint64 // Just a sum of the desc IDs.
-	)
-	go func() {
-		c.Describe(descChan)
-		close(descChan)
-	}()
-	for desc := range descChan {
-		if _, exists := descIDs[desc.id]; !exists {
-			collectorID += desc.id
-			descIDs[desc.id] = struct{}{}
-		}
-	}
-
-	r.mtx.RLock()
-	if _, exists := r.collectorsByID[collectorID]; !exists {
-		r.mtx.RUnlock()
-		return false
-	}
-	r.mtx.RUnlock()
-
-	r.mtx.Lock()
-	defer r.mtx.Unlock()
-
-	delete(r.collectorsByID, collectorID)
-	for id := range descIDs {
-		delete(r.descIDs, id)
-	}
-	// dimHashesByName is left untouched as those must be consistent
-	// throughout the lifetime of a program.
-	return true
-}
-
-// MustRegister implements Registerer.
-func (r *Registry) MustRegister(cs ...Collector) {
-	for _, c := range cs {
-		if err := r.Register(c); err != nil {
-			panic(err)
-		}
-	}
-}
-
-// Gather implements Gatherer.
-func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
-	var (
-		checkedMetricChan   = make(chan Metric, capMetricChan)
-		uncheckedMetricChan = make(chan Metric, capMetricChan)
-		metricHashes        = map[uint64]struct{}{}
-		wg                  sync.WaitGroup
-		errs                MultiError          // The collected errors to return in the end.
-		registeredDescIDs   map[uint64]struct{} // Only used for pedantic checks
-	)
-
-	r.mtx.RLock()
-	goroutineBudget := len(r.collectorsByID) + len(r.uncheckedCollectors)
-	metricFamiliesByName := make(map[string]*dto.MetricFamily, len(r.dimHashesByName))
-	checkedCollectors := make(chan Collector, len(r.collectorsByID))
-	uncheckedCollectors := make(chan Collector, len(r.uncheckedCollectors))
-	for _, collector := range r.collectorsByID {
-		checkedCollectors <- collector
-	}
-	for _, collector := range r.uncheckedCollectors {
-		uncheckedCollectors <- collector
-	}
-	// In case pedantic checks are enabled, we have to copy the map before
-	// giving up the RLock.
-	if r.pedanticChecksEnabled {
-		registeredDescIDs = make(map[uint64]struct{}, len(r.descIDs))
-		for id := range r.descIDs {
-			registeredDescIDs[id] = struct{}{}
-		}
-	}
-	r.mtx.RUnlock()
-
-	wg.Add(goroutineBudget)
-
-	collectWorker := func() {
-		for {
-			select {
-			case collector := <-checkedCollectors:
-				collector.Collect(checkedMetricChan)
-			case collector := <-uncheckedCollectors:
-				collector.Collect(uncheckedMetricChan)
-			default:
-				return
-			}
-			wg.Done()
-		}
-	}
-
-	// Start the first worker now to make sure at least one is running.
-	go collectWorker()
-	goroutineBudget--
-
-	// Close checkedMetricChan and uncheckedMetricChan once all collectors
-	// are collected.
-	go func() {
-		wg.Wait()
-		close(checkedMetricChan)
-		close(uncheckedMetricChan)
-	}()
-
-	// Drain checkedMetricChan and uncheckedMetricChan in case of premature return.
-	defer func() {
-		if checkedMetricChan != nil {
-			for range checkedMetricChan {
-			}
-		}
-		if uncheckedMetricChan != nil {
-			for range uncheckedMetricChan {
-			}
-		}
-	}()
-
-	// Copy the channel references so we can nil them out later to remove
-	// them from the select statements below.
-	cmc := checkedMetricChan
-	umc := uncheckedMetricChan
-
-	for {
-		select {
-		case metric, ok := <-cmc:
-			if !ok {
-				cmc = nil
-				break
-			}
-			errs.Append(processMetric(
-				metric, metricFamiliesByName,
-				metricHashes,
-				registeredDescIDs,
-			))
-		case metric, ok := <-umc:
-			if !ok {
-				umc = nil
-				break
-			}
-			errs.Append(processMetric(
-				metric, metricFamiliesByName,
-				metricHashes,
-				nil,
-			))
-		default:
-			if goroutineBudget <= 0 || len(checkedCollectors)+len(uncheckedCollectors) == 0 {
-				// All collectors are already being worked on or
-				// we have already as many goroutines started as
-				// there are collectors. Do the same as above,
-				// just without the default.
-				select {
-				case metric, ok := <-cmc:
-					if !ok {
-						cmc = nil
-						break
-					}
-					errs.Append(processMetric(
-						metric, metricFamiliesByName,
-						metricHashes,
-						registeredDescIDs,
-					))
-				case metric, ok := <-umc:
-					if !ok {
-						umc = nil
-						break
-					}
-					errs.Append(processMetric(
-						metric, metricFamiliesByName,
-						metricHashes,
-						nil,
-					))
-				}
-				break
-			}
-			// Start more workers.
-			go collectWorker()
-			goroutineBudget--
-			runtime.Gosched()
-		}
-		// Once both checkedMetricChan and uncheckdMetricChan are closed
-		// and drained, the contraption above will nil out cmc and umc,
-		// and then we can leave the collect loop here.
-		if cmc == nil && umc == nil {
-			break
-		}
-	}
-	return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap()
-}
-
-// WriteToTextfile calls Gather on the provided Gatherer, encodes the result in the
-// Prometheus text format, and writes it to a temporary file. Upon success, the
-// temporary file is renamed to the provided filename.
-//
-// This is intended for use with the textfile collector of the node exporter.
-// Note that the node exporter expects the filename to be suffixed with ".prom".
-func WriteToTextfile(filename string, g Gatherer) error {
-	tmp, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename))
-	if err != nil {
-		return err
-	}
-	defer os.Remove(tmp.Name())
-
-	mfs, err := g.Gather()
-	if err != nil {
-		return err
-	}
-	for _, mf := range mfs {
-		if _, err := expfmt.MetricFamilyToText(tmp, mf); err != nil {
-			return err
-		}
-	}
-	if err := tmp.Close(); err != nil {
-		return err
-	}
-
-	if err := os.Chmod(tmp.Name(), 0644); err != nil {
-		return err
-	}
-	return os.Rename(tmp.Name(), filename)
-}
-
-// processMetric is an internal helper method only used by the Gather method.
-func processMetric(
-	metric Metric,
-	metricFamiliesByName map[string]*dto.MetricFamily,
-	metricHashes map[uint64]struct{},
-	registeredDescIDs map[uint64]struct{},
-) error {
-	desc := metric.Desc()
-	// Wrapped metrics collected by an unchecked Collector can have an
-	// invalid Desc.
-	if desc.err != nil {
-		return desc.err
-	}
-	dtoMetric := &dto.Metric{}
-	if err := metric.Write(dtoMetric); err != nil {
-		return fmt.Errorf("error collecting metric %v: %s", desc, err)
-	}
-	metricFamily, ok := metricFamiliesByName[desc.fqName]
-	if ok { // Existing name.
-		if metricFamily.GetHelp() != desc.help {
-			return fmt.Errorf(
-				"collected metric %s %s has help %q but should have %q",
-				desc.fqName, dtoMetric, desc.help, metricFamily.GetHelp(),
-			)
-		}
-		// TODO(beorn7): Simplify switch once Desc has type.
-		switch metricFamily.GetType() {
-		case dto.MetricType_COUNTER:
-			if dtoMetric.Counter == nil {
-				return fmt.Errorf(
-					"collected metric %s %s should be a Counter",
-					desc.fqName, dtoMetric,
-				)
-			}
-		case dto.MetricType_GAUGE:
-			if dtoMetric.Gauge == nil {
-				return fmt.Errorf(
-					"collected metric %s %s should be a Gauge",
-					desc.fqName, dtoMetric,
-				)
-			}
-		case dto.MetricType_SUMMARY:
-			if dtoMetric.Summary == nil {
-				return fmt.Errorf(
-					"collected metric %s %s should be a Summary",
-					desc.fqName, dtoMetric,
-				)
-			}
-		case dto.MetricType_UNTYPED:
-			if dtoMetric.Untyped == nil {
-				return fmt.Errorf(
-					"collected metric %s %s should be Untyped",
-					desc.fqName, dtoMetric,
-				)
-			}
-		case dto.MetricType_HISTOGRAM:
-			if dtoMetric.Histogram == nil {
-				return fmt.Errorf(
-					"collected metric %s %s should be a Histogram",
-					desc.fqName, dtoMetric,
-				)
-			}
-		default:
-			panic("encountered MetricFamily with invalid type")
-		}
-	} else { // New name.
-		metricFamily = &dto.MetricFamily{}
-		metricFamily.Name = proto.String(desc.fqName)
-		metricFamily.Help = proto.String(desc.help)
-		// TODO(beorn7): Simplify switch once Desc has type.
-		switch {
-		case dtoMetric.Gauge != nil:
-			metricFamily.Type = dto.MetricType_GAUGE.Enum()
-		case dtoMetric.Counter != nil:
-			metricFamily.Type = dto.MetricType_COUNTER.Enum()
-		case dtoMetric.Summary != nil:
-			metricFamily.Type = dto.MetricType_SUMMARY.Enum()
-		case dtoMetric.Untyped != nil:
-			metricFamily.Type = dto.MetricType_UNTYPED.Enum()
-		case dtoMetric.Histogram != nil:
-			metricFamily.Type = dto.MetricType_HISTOGRAM.Enum()
-		default:
-			return fmt.Errorf("empty metric collected: %s", dtoMetric)
-		}
-		if err := checkSuffixCollisions(metricFamily, metricFamiliesByName); err != nil {
-			return err
-		}
-		metricFamiliesByName[desc.fqName] = metricFamily
-	}
-	if err := checkMetricConsistency(metricFamily, dtoMetric, metricHashes); err != nil {
-		return err
-	}
-	if registeredDescIDs != nil {
-		// Is the desc registered at all?
-		if _, exist := registeredDescIDs[desc.id]; !exist {
-			return fmt.Errorf(
-				"collected metric %s %s with unregistered descriptor %s",
-				metricFamily.GetName(), dtoMetric, desc,
-			)
-		}
-		if err := checkDescConsistency(metricFamily, dtoMetric, desc); err != nil {
-			return err
-		}
-	}
-	metricFamily.Metric = append(metricFamily.Metric, dtoMetric)
-	return nil
-}
-
-// Gatherers is a slice of Gatherer instances that implements the Gatherer
-// interface itself. Its Gather method calls Gather on all Gatherers in the
-// slice in order and returns the merged results. Errors returned from the
-// Gather calles are all returned in a flattened MultiError. Duplicate and
-// inconsistent Metrics are skipped (first occurrence in slice order wins) and
-// reported in the returned error.
-//
-// Gatherers can be used to merge the Gather results from multiple
-// Registries. It also provides a way to directly inject existing MetricFamily
-// protobufs into the gathering by creating a custom Gatherer with a Gather
-// method that simply returns the existing MetricFamily protobufs. Note that no
-// registration is involved (in contrast to Collector registration), so
-// obviously registration-time checks cannot happen. Any inconsistencies between
-// the gathered MetricFamilies are reported as errors by the Gather method, and
-// inconsistent Metrics are dropped. Invalid parts of the MetricFamilies
-// (e.g. syntactically invalid metric or label names) will go undetected.
-type Gatherers []Gatherer
-
-// Gather implements Gatherer.
-func (gs Gatherers) Gather() ([]*dto.MetricFamily, error) {
-	var (
-		metricFamiliesByName = map[string]*dto.MetricFamily{}
-		metricHashes         = map[uint64]struct{}{}
-		errs                 MultiError // The collected errors to return in the end.
-	)
-
-	for i, g := range gs {
-		mfs, err := g.Gather()
-		if err != nil {
-			if multiErr, ok := err.(MultiError); ok {
-				for _, err := range multiErr {
-					errs = append(errs, fmt.Errorf("[from Gatherer #%d] %s", i+1, err))
-				}
-			} else {
-				errs = append(errs, fmt.Errorf("[from Gatherer #%d] %s", i+1, err))
-			}
-		}
-		for _, mf := range mfs {
-			existingMF, exists := metricFamiliesByName[mf.GetName()]
-			if exists {
-				if existingMF.GetHelp() != mf.GetHelp() {
-					errs = append(errs, fmt.Errorf(
-						"gathered metric family %s has help %q but should have %q",
-						mf.GetName(), mf.GetHelp(), existingMF.GetHelp(),
-					))
-					continue
-				}
-				if existingMF.GetType() != mf.GetType() {
-					errs = append(errs, fmt.Errorf(
-						"gathered metric family %s has type %s but should have %s",
-						mf.GetName(), mf.GetType(), existingMF.GetType(),
-					))
-					continue
-				}
-			} else {
-				existingMF = &dto.MetricFamily{}
-				existingMF.Name = mf.Name
-				existingMF.Help = mf.Help
-				existingMF.Type = mf.Type
-				if err := checkSuffixCollisions(existingMF, metricFamiliesByName); err != nil {
-					errs = append(errs, err)
-					continue
-				}
-				metricFamiliesByName[mf.GetName()] = existingMF
-			}
-			for _, m := range mf.Metric {
-				if err := checkMetricConsistency(existingMF, m, metricHashes); err != nil {
-					errs = append(errs, err)
-					continue
-				}
-				existingMF.Metric = append(existingMF.Metric, m)
-			}
-		}
-	}
-	return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap()
-}
-
-// checkSuffixCollisions checks for collisions with the “magic” suffixes the
-// Prometheus text format and the internal metric representation of the
-// Prometheus server add while flattening Summaries and Histograms.
-func checkSuffixCollisions(mf *dto.MetricFamily, mfs map[string]*dto.MetricFamily) error {
-	var (
-		newName              = mf.GetName()
-		newType              = mf.GetType()
-		newNameWithoutSuffix = ""
-	)
-	switch {
-	case strings.HasSuffix(newName, "_count"):
-		newNameWithoutSuffix = newName[:len(newName)-6]
-	case strings.HasSuffix(newName, "_sum"):
-		newNameWithoutSuffix = newName[:len(newName)-4]
-	case strings.HasSuffix(newName, "_bucket"):
-		newNameWithoutSuffix = newName[:len(newName)-7]
-	}
-	if newNameWithoutSuffix != "" {
-		if existingMF, ok := mfs[newNameWithoutSuffix]; ok {
-			switch existingMF.GetType() {
-			case dto.MetricType_SUMMARY:
-				if !strings.HasSuffix(newName, "_bucket") {
-					return fmt.Errorf(
-						"collected metric named %q collides with previously collected summary named %q",
-						newName, newNameWithoutSuffix,
-					)
-				}
-			case dto.MetricType_HISTOGRAM:
-				return fmt.Errorf(
-					"collected metric named %q collides with previously collected histogram named %q",
-					newName, newNameWithoutSuffix,
-				)
-			}
-		}
-	}
-	if newType == dto.MetricType_SUMMARY || newType == dto.MetricType_HISTOGRAM {
-		if _, ok := mfs[newName+"_count"]; ok {
-			return fmt.Errorf(
-				"collected histogram or summary named %q collides with previously collected metric named %q",
-				newName, newName+"_count",
-			)
-		}
-		if _, ok := mfs[newName+"_sum"]; ok {
-			return fmt.Errorf(
-				"collected histogram or summary named %q collides with previously collected metric named %q",
-				newName, newName+"_sum",
-			)
-		}
-	}
-	if newType == dto.MetricType_HISTOGRAM {
-		if _, ok := mfs[newName+"_bucket"]; ok {
-			return fmt.Errorf(
-				"collected histogram named %q collides with previously collected metric named %q",
-				newName, newName+"_bucket",
-			)
-		}
-	}
-	return nil
-}
-
-// checkMetricConsistency checks if the provided Metric is consistent with the
-// provided MetricFamily. It also hashes the Metric labels and the MetricFamily
-// name. If the resulting hash is already in the provided metricHashes, an error
-// is returned. If not, it is added to metricHashes.
-func checkMetricConsistency(
-	metricFamily *dto.MetricFamily,
-	dtoMetric *dto.Metric,
-	metricHashes map[uint64]struct{},
-) error {
-	name := metricFamily.GetName()
-
-	// Type consistency with metric family.
-	if metricFamily.GetType() == dto.MetricType_GAUGE && dtoMetric.Gauge == nil ||
-		metricFamily.GetType() == dto.MetricType_COUNTER && dtoMetric.Counter == nil ||
-		metricFamily.GetType() == dto.MetricType_SUMMARY && dtoMetric.Summary == nil ||
-		metricFamily.GetType() == dto.MetricType_HISTOGRAM && dtoMetric.Histogram == nil ||
-		metricFamily.GetType() == dto.MetricType_UNTYPED && dtoMetric.Untyped == nil {
-		return fmt.Errorf(
-			"collected metric %q { %s} is not a %s",
-			name, dtoMetric, metricFamily.GetType(),
-		)
-	}
-
-	previousLabelName := ""
-	for _, labelPair := range dtoMetric.GetLabel() {
-		labelName := labelPair.GetName()
-		if labelName == previousLabelName {
-			return fmt.Errorf(
-				"collected metric %q { %s} has two or more labels with the same name: %s",
-				name, dtoMetric, labelName,
-			)
-		}
-		if !checkLabelName(labelName) {
-			return fmt.Errorf(
-				"collected metric %q { %s} has a label with an invalid name: %s",
-				name, dtoMetric, labelName,
-			)
-		}
-		if dtoMetric.Summary != nil && labelName == quantileLabel {
-			return fmt.Errorf(
-				"collected metric %q { %s} must not have an explicit %q label",
-				name, dtoMetric, quantileLabel,
-			)
-		}
-		if !utf8.ValidString(labelPair.GetValue()) {
-			return fmt.Errorf(
-				"collected metric %q { %s} has a label named %q whose value is not utf8: %#v",
-				name, dtoMetric, labelName, labelPair.GetValue())
-		}
-		previousLabelName = labelName
-	}
-
-	// Is the metric unique (i.e. no other metric with the same name and the same labels)?
-	h := hashNew()
-	h = hashAdd(h, name)
-	h = hashAddByte(h, separatorByte)
-	// Make sure label pairs are sorted. We depend on it for the consistency
-	// check.
-	if !sort.IsSorted(labelPairSorter(dtoMetric.Label)) {
-		// We cannot sort dtoMetric.Label in place as it is immutable by contract.
-		copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label))
-		copy(copiedLabels, dtoMetric.Label)
-		sort.Sort(labelPairSorter(copiedLabels))
-		dtoMetric.Label = copiedLabels
-	}
-	for _, lp := range dtoMetric.Label {
-		h = hashAdd(h, lp.GetName())
-		h = hashAddByte(h, separatorByte)
-		h = hashAdd(h, lp.GetValue())
-		h = hashAddByte(h, separatorByte)
-	}
-	if _, exists := metricHashes[h]; exists {
-		return fmt.Errorf(
-			"collected metric %q { %s} was collected before with the same name and label values",
-			name, dtoMetric,
-		)
-	}
-	metricHashes[h] = struct{}{}
-	return nil
-}
-
-func checkDescConsistency(
-	metricFamily *dto.MetricFamily,
-	dtoMetric *dto.Metric,
-	desc *Desc,
-) error {
-	// Desc help consistency with metric family help.
-	if metricFamily.GetHelp() != desc.help {
-		return fmt.Errorf(
-			"collected metric %s %s has help %q but should have %q",
-			metricFamily.GetName(), dtoMetric, metricFamily.GetHelp(), desc.help,
-		)
-	}
-
-	// Is the desc consistent with the content of the metric?
-	lpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label))
-	copy(lpsFromDesc, desc.constLabelPairs)
-	for _, l := range desc.variableLabels {
-		lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{
-			Name: proto.String(l),
-		})
-	}
-	if len(lpsFromDesc) != len(dtoMetric.Label) {
-		return fmt.Errorf(
-			"labels in collected metric %s %s are inconsistent with descriptor %s",
-			metricFamily.GetName(), dtoMetric, desc,
-		)
-	}
-	sort.Sort(labelPairSorter(lpsFromDesc))
-	for i, lpFromDesc := range lpsFromDesc {
-		lpFromMetric := dtoMetric.Label[i]
-		if lpFromDesc.GetName() != lpFromMetric.GetName() ||
-			lpFromDesc.Value != nil && lpFromDesc.GetValue() != lpFromMetric.GetValue() {
-			return fmt.Errorf(
-				"labels in collected metric %s %s are inconsistent with descriptor %s",
-				metricFamily.GetName(), dtoMetric, desc,
-			)
-		}
-	}
-	return nil
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/summary.go b/vendor/github.com/prometheus/client_golang/prometheus/summary.go
deleted file mode 100644
index 2980614..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/summary.go
+++ /dev/null
@@ -1,626 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"fmt"
-	"math"
-	"sort"
-	"sync"
-	"time"
-
-	"github.com/beorn7/perks/quantile"
-	"github.com/golang/protobuf/proto"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-// quantileLabel is used for the label that defines the quantile in a
-// summary.
-const quantileLabel = "quantile"
-
-// A Summary captures individual observations from an event or sample stream and
-// summarizes them in a manner similar to traditional summary statistics: 1. sum
-// of observations, 2. observation count, 3. rank estimations.
-//
-// A typical use-case is the observation of request latencies. By default, a
-// Summary provides the median, the 90th and the 99th percentile of the latency
-// as rank estimations. However, the default behavior will change in the
-// upcoming v0.10 of the library. There will be no rank estimations at all by
-// default. For a sane transition, it is recommended to set the desired rank
-// estimations explicitly.
-//
-// Note that the rank estimations cannot be aggregated in a meaningful way with
-// the Prometheus query language (i.e. you cannot average or add them). If you
-// need aggregatable quantiles (e.g. you want the 99th percentile latency of all
-// queries served across all instances of a service), consider the Histogram
-// metric type. See the Prometheus documentation for more details.
-//
-// To create Summary instances, use NewSummary.
-type Summary interface {
-	Metric
-	Collector
-
-	// Observe adds a single observation to the summary.
-	Observe(float64)
-}
-
-// DefObjectives are the default Summary quantile values.
-//
-// Deprecated: DefObjectives will not be used as the default objectives in
-// v0.10 of the library. The default Summary will have no quantiles then.
-var (
-	DefObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
-
-	errQuantileLabelNotAllowed = fmt.Errorf(
-		"%q is not allowed as label name in summaries", quantileLabel,
-	)
-)
-
-// Default values for SummaryOpts.
-const (
-	// DefMaxAge is the default duration for which observations stay
-	// relevant.
-	DefMaxAge time.Duration = 10 * time.Minute
-	// DefAgeBuckets is the default number of buckets used to calculate the
-	// age of observations.
-	DefAgeBuckets = 5
-	// DefBufCap is the standard buffer size for collecting Summary observations.
-	DefBufCap = 500
-)
-
-// SummaryOpts bundles the options for creating a Summary metric. It is
-// mandatory to set Name to a non-empty string. While all other fields are
-// optional and can safely be left at their zero value, it is recommended to set
-// a help string and to explicitly set the Objectives field to the desired value
-// as the default value will change in the upcoming v0.10 of the library.
-type SummaryOpts struct {
-	// Namespace, Subsystem, and Name are components of the fully-qualified
-	// name of the Summary (created by joining these components with
-	// "_"). Only Name is mandatory, the others merely help structuring the
-	// name. Note that the fully-qualified name of the Summary must be a
-	// valid Prometheus metric name.
-	Namespace string
-	Subsystem string
-	Name      string
-
-	// Help provides information about this Summary.
-	//
-	// Metrics with the same fully-qualified name must have the same Help
-	// string.
-	Help string
-
-	// ConstLabels are used to attach fixed labels to this metric. Metrics
-	// with the same fully-qualified name must have the same label names in
-	// their ConstLabels.
-	//
-	// Due to the way a Summary is represented in the Prometheus text format
-	// and how it is handled by the Prometheus server internally, “quantile”
-	// is an illegal label name. Construction of a Summary or SummaryVec
-	// will panic if this label name is used in ConstLabels.
-	//
-	// ConstLabels are only used rarely. In particular, do not use them to
-	// attach the same labels to all your metrics. Those use cases are
-	// better covered by target labels set by the scraping Prometheus
-	// server, or by one specific metric (e.g. a build_info or a
-	// machine_role metric). See also
-	// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels,-not-static-scraped-labels
-	ConstLabels Labels
-
-	// Objectives defines the quantile rank estimates with their respective
-	// absolute error. If Objectives[q] = e, then the value reported for q
-	// will be the φ-quantile value for some φ between q-e and q+e.  The
-	// default value is DefObjectives. It is used if Objectives is left at
-	// its zero value (i.e. nil). To create a Summary without Objectives,
-	// set it to an empty map (i.e. map[float64]float64{}).
-	//
-	// Deprecated: Note that the current value of DefObjectives is
-	// deprecated. It will be replaced by an empty map in v0.10 of the
-	// library. Please explicitly set Objectives to the desired value.
-	Objectives map[float64]float64
-
-	// MaxAge defines the duration for which an observation stays relevant
-	// for the summary. Must be positive. The default value is DefMaxAge.
-	MaxAge time.Duration
-
-	// AgeBuckets is the number of buckets used to exclude observations that
-	// are older than MaxAge from the summary. A higher number has a
-	// resource penalty, so only increase it if the higher resolution is
-	// really required. For very high observation rates, you might want to
-	// reduce the number of age buckets. With only one age bucket, you will
-	// effectively see a complete reset of the summary each time MaxAge has
-	// passed. The default value is DefAgeBuckets.
-	AgeBuckets uint32
-
-	// BufCap defines the default sample stream buffer size.  The default
-	// value of DefBufCap should suffice for most uses. If there is a need
-	// to increase the value, a multiple of 500 is recommended (because that
-	// is the internal buffer size of the underlying package
-	// "github.com/bmizerany/perks/quantile").
-	BufCap uint32
-}
-
-// Great fuck-up with the sliding-window decay algorithm... The Merge method of
-// perk/quantile is actually not working as advertised - and it might be
-// unfixable, as the underlying algorithm is apparently not capable of merging
-// summaries in the first place. To avoid using Merge, we are currently adding
-// observations to _each_ age bucket, i.e. the effort to add a sample is
-// essentially multiplied by the number of age buckets. When rotating age
-// buckets, we empty the previous head stream. On scrape time, we simply take
-// the quantiles from the head stream (no merging required). Result: More effort
-// on observation time, less effort on scrape time, which is exactly the
-// opposite of what we try to accomplish, but at least the results are correct.
-//
-// The quite elegant previous contraption to merge the age buckets efficiently
-// on scrape time (see code up commit 6b9530d72ea715f0ba612c0120e6e09fbf1d49d0)
-// can't be used anymore.
-
-// NewSummary creates a new Summary based on the provided SummaryOpts.
-func NewSummary(opts SummaryOpts) Summary {
-	return newSummary(
-		NewDesc(
-			BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-			opts.Help,
-			nil,
-			opts.ConstLabels,
-		),
-		opts,
-	)
-}
-
-func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
-	if len(desc.variableLabels) != len(labelValues) {
-		panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, labelValues))
-	}
-
-	for _, n := range desc.variableLabels {
-		if n == quantileLabel {
-			panic(errQuantileLabelNotAllowed)
-		}
-	}
-	for _, lp := range desc.constLabelPairs {
-		if lp.GetName() == quantileLabel {
-			panic(errQuantileLabelNotAllowed)
-		}
-	}
-
-	if opts.Objectives == nil {
-		opts.Objectives = DefObjectives
-	}
-
-	if opts.MaxAge < 0 {
-		panic(fmt.Errorf("illegal max age MaxAge=%v", opts.MaxAge))
-	}
-	if opts.MaxAge == 0 {
-		opts.MaxAge = DefMaxAge
-	}
-
-	if opts.AgeBuckets == 0 {
-		opts.AgeBuckets = DefAgeBuckets
-	}
-
-	if opts.BufCap == 0 {
-		opts.BufCap = DefBufCap
-	}
-
-	s := &summary{
-		desc: desc,
-
-		objectives:       opts.Objectives,
-		sortedObjectives: make([]float64, 0, len(opts.Objectives)),
-
-		labelPairs: makeLabelPairs(desc, labelValues),
-
-		hotBuf:         make([]float64, 0, opts.BufCap),
-		coldBuf:        make([]float64, 0, opts.BufCap),
-		streamDuration: opts.MaxAge / time.Duration(opts.AgeBuckets),
-	}
-	s.headStreamExpTime = time.Now().Add(s.streamDuration)
-	s.hotBufExpTime = s.headStreamExpTime
-
-	for i := uint32(0); i < opts.AgeBuckets; i++ {
-		s.streams = append(s.streams, s.newStream())
-	}
-	s.headStream = s.streams[0]
-
-	for qu := range s.objectives {
-		s.sortedObjectives = append(s.sortedObjectives, qu)
-	}
-	sort.Float64s(s.sortedObjectives)
-
-	s.init(s) // Init self-collection.
-	return s
-}
-
-type summary struct {
-	selfCollector
-
-	bufMtx sync.Mutex // Protects hotBuf and hotBufExpTime.
-	mtx    sync.Mutex // Protects every other moving part.
-	// Lock bufMtx before mtx if both are needed.
-
-	desc *Desc
-
-	objectives       map[float64]float64
-	sortedObjectives []float64
-
-	labelPairs []*dto.LabelPair
-
-	sum float64
-	cnt uint64
-
-	hotBuf, coldBuf []float64
-
-	streams                          []*quantile.Stream
-	streamDuration                   time.Duration
-	headStream                       *quantile.Stream
-	headStreamIdx                    int
-	headStreamExpTime, hotBufExpTime time.Time
-}
-
-func (s *summary) Desc() *Desc {
-	return s.desc
-}
-
-func (s *summary) Observe(v float64) {
-	s.bufMtx.Lock()
-	defer s.bufMtx.Unlock()
-
-	now := time.Now()
-	if now.After(s.hotBufExpTime) {
-		s.asyncFlush(now)
-	}
-	s.hotBuf = append(s.hotBuf, v)
-	if len(s.hotBuf) == cap(s.hotBuf) {
-		s.asyncFlush(now)
-	}
-}
-
-func (s *summary) Write(out *dto.Metric) error {
-	sum := &dto.Summary{}
-	qs := make([]*dto.Quantile, 0, len(s.objectives))
-
-	s.bufMtx.Lock()
-	s.mtx.Lock()
-	// Swap bufs even if hotBuf is empty to set new hotBufExpTime.
-	s.swapBufs(time.Now())
-	s.bufMtx.Unlock()
-
-	s.flushColdBuf()
-	sum.SampleCount = proto.Uint64(s.cnt)
-	sum.SampleSum = proto.Float64(s.sum)
-
-	for _, rank := range s.sortedObjectives {
-		var q float64
-		if s.headStream.Count() == 0 {
-			q = math.NaN()
-		} else {
-			q = s.headStream.Query(rank)
-		}
-		qs = append(qs, &dto.Quantile{
-			Quantile: proto.Float64(rank),
-			Value:    proto.Float64(q),
-		})
-	}
-
-	s.mtx.Unlock()
-
-	if len(qs) > 0 {
-		sort.Sort(quantSort(qs))
-	}
-	sum.Quantile = qs
-
-	out.Summary = sum
-	out.Label = s.labelPairs
-	return nil
-}
-
-func (s *summary) newStream() *quantile.Stream {
-	return quantile.NewTargeted(s.objectives)
-}
-
-// asyncFlush needs bufMtx locked.
-func (s *summary) asyncFlush(now time.Time) {
-	s.mtx.Lock()
-	s.swapBufs(now)
-
-	// Unblock the original goroutine that was responsible for the mutation
-	// that triggered the compaction.  But hold onto the global non-buffer
-	// state mutex until the operation finishes.
-	go func() {
-		s.flushColdBuf()
-		s.mtx.Unlock()
-	}()
-}
-
-// rotateStreams needs mtx AND bufMtx locked.
-func (s *summary) maybeRotateStreams() {
-	for !s.hotBufExpTime.Equal(s.headStreamExpTime) {
-		s.headStream.Reset()
-		s.headStreamIdx++
-		if s.headStreamIdx >= len(s.streams) {
-			s.headStreamIdx = 0
-		}
-		s.headStream = s.streams[s.headStreamIdx]
-		s.headStreamExpTime = s.headStreamExpTime.Add(s.streamDuration)
-	}
-}
-
-// flushColdBuf needs mtx locked.
-func (s *summary) flushColdBuf() {
-	for _, v := range s.coldBuf {
-		for _, stream := range s.streams {
-			stream.Insert(v)
-		}
-		s.cnt++
-		s.sum += v
-	}
-	s.coldBuf = s.coldBuf[0:0]
-	s.maybeRotateStreams()
-}
-
-// swapBufs needs mtx AND bufMtx locked, coldBuf must be empty.
-func (s *summary) swapBufs(now time.Time) {
-	if len(s.coldBuf) != 0 {
-		panic("coldBuf is not empty")
-	}
-	s.hotBuf, s.coldBuf = s.coldBuf, s.hotBuf
-	// hotBuf is now empty and gets new expiration set.
-	for now.After(s.hotBufExpTime) {
-		s.hotBufExpTime = s.hotBufExpTime.Add(s.streamDuration)
-	}
-}
-
-type quantSort []*dto.Quantile
-
-func (s quantSort) Len() int {
-	return len(s)
-}
-
-func (s quantSort) Swap(i, j int) {
-	s[i], s[j] = s[j], s[i]
-}
-
-func (s quantSort) Less(i, j int) bool {
-	return s[i].GetQuantile() < s[j].GetQuantile()
-}
-
-// SummaryVec is a Collector that bundles a set of Summaries that all share the
-// same Desc, but have different values for their variable labels. This is used
-// if you want to count the same thing partitioned by various dimensions
-// (e.g. HTTP request latencies, partitioned by status code and method). Create
-// instances with NewSummaryVec.
-type SummaryVec struct {
-	*metricVec
-}
-
-// NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and
-// partitioned by the given label names.
-//
-// Due to the way a Summary is represented in the Prometheus text format and how
-// it is handled by the Prometheus server internally, “quantile” is an illegal
-// label name. NewSummaryVec will panic if this label name is used.
-func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
-	for _, ln := range labelNames {
-		if ln == quantileLabel {
-			panic(errQuantileLabelNotAllowed)
-		}
-	}
-	desc := NewDesc(
-		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-		opts.Help,
-		labelNames,
-		opts.ConstLabels,
-	)
-	return &SummaryVec{
-		metricVec: newMetricVec(desc, func(lvs ...string) Metric {
-			return newSummary(desc, opts, lvs...)
-		}),
-	}
-}
-
-// GetMetricWithLabelValues returns the Summary for the given slice of label
-// values (same order as the VariableLabels in Desc). If that combination of
-// label values is accessed for the first time, a new Summary is created.
-//
-// It is possible to call this method without using the returned Summary to only
-// create the new Summary but leave it at its starting value, a Summary without
-// any observations.
-//
-// Keeping the Summary for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Summary from the SummaryVec. In that case,
-// the Summary will still exist, but it will not be exported anymore, even if a
-// Summary with the same label values is created later. See also the CounterVec
-// example.
-//
-// An error is returned if the number of label values is not the same as the
-// number of VariableLabels in Desc (minus any curried labels).
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the GaugeVec example.
-func (v *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
-	metric, err := v.metricVec.getMetricWithLabelValues(lvs...)
-	if metric != nil {
-		return metric.(Observer), err
-	}
-	return nil, err
-}
-
-// GetMetricWith returns the Summary for the given Labels map (the label names
-// must match those of the VariableLabels in Desc). If that label map is
-// accessed for the first time, a new Summary is created. Implications of
-// creating a Summary without using it and keeping the Summary for later use are
-// the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc (minus any curried labels).
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (v *SummaryVec) GetMetricWith(labels Labels) (Observer, error) {
-	metric, err := v.metricVec.getMetricWith(labels)
-	if metric != nil {
-		return metric.(Observer), err
-	}
-	return nil, err
-}
-
-// WithLabelValues works as GetMetricWithLabelValues, but panics where
-// GetMetricWithLabelValues would have returned an error. Not returning an
-// error allows shortcuts like
-//     myVec.WithLabelValues("404", "GET").Observe(42.21)
-func (v *SummaryVec) WithLabelValues(lvs ...string) Observer {
-	s, err := v.GetMetricWithLabelValues(lvs...)
-	if err != nil {
-		panic(err)
-	}
-	return s
-}
-
-// With works as GetMetricWith, but panics where GetMetricWithLabels would have
-// returned an error. Not returning an error allows shortcuts like
-//     myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21)
-func (v *SummaryVec) With(labels Labels) Observer {
-	s, err := v.GetMetricWith(labels)
-	if err != nil {
-		panic(err)
-	}
-	return s
-}
-
-// CurryWith returns a vector curried with the provided labels, i.e. the
-// returned vector has those labels pre-set for all labeled operations performed
-// on it. The cardinality of the curried vector is reduced accordingly. The
-// order of the remaining labels stays the same (just with the curried labels
-// taken out of the sequence – which is relevant for the
-// (GetMetric)WithLabelValues methods). It is possible to curry a curried
-// vector, but only with labels not yet used for currying before.
-//
-// The metrics contained in the SummaryVec are shared between the curried and
-// uncurried vectors. They are just accessed differently. Curried and uncurried
-// vectors behave identically in terms of collection. Only one must be
-// registered with a given registry (usually the uncurried version). The Reset
-// method deletes all metrics, even if called on a curried vector.
-func (v *SummaryVec) CurryWith(labels Labels) (ObserverVec, error) {
-	vec, err := v.curryWith(labels)
-	if vec != nil {
-		return &SummaryVec{vec}, err
-	}
-	return nil, err
-}
-
-// MustCurryWith works as CurryWith but panics where CurryWith would have
-// returned an error.
-func (v *SummaryVec) MustCurryWith(labels Labels) ObserverVec {
-	vec, err := v.CurryWith(labels)
-	if err != nil {
-		panic(err)
-	}
-	return vec
-}
-
-type constSummary struct {
-	desc       *Desc
-	count      uint64
-	sum        float64
-	quantiles  map[float64]float64
-	labelPairs []*dto.LabelPair
-}
-
-func (s *constSummary) Desc() *Desc {
-	return s.desc
-}
-
-func (s *constSummary) Write(out *dto.Metric) error {
-	sum := &dto.Summary{}
-	qs := make([]*dto.Quantile, 0, len(s.quantiles))
-
-	sum.SampleCount = proto.Uint64(s.count)
-	sum.SampleSum = proto.Float64(s.sum)
-
-	for rank, q := range s.quantiles {
-		qs = append(qs, &dto.Quantile{
-			Quantile: proto.Float64(rank),
-			Value:    proto.Float64(q),
-		})
-	}
-
-	if len(qs) > 0 {
-		sort.Sort(quantSort(qs))
-	}
-	sum.Quantile = qs
-
-	out.Summary = sum
-	out.Label = s.labelPairs
-
-	return nil
-}
-
-// NewConstSummary returns a metric representing a Prometheus summary with fixed
-// values for the count, sum, and quantiles. As those parameters cannot be
-// changed, the returned value does not implement the Summary interface (but
-// only the Metric interface). Users of this package will not have much use for
-// it in regular operations. However, when implementing custom Collectors, it is
-// useful as a throw-away metric that is generated on the fly to send it to
-// Prometheus in the Collect method.
-//
-// quantiles maps ranks to quantile values. For example, a median latency of
-// 0.23s and a 99th percentile latency of 0.56s would be expressed as:
-//     map[float64]float64{0.5: 0.23, 0.99: 0.56}
-//
-// NewConstSummary returns an error if the length of labelValues is not
-// consistent with the variable labels in Desc or if Desc is invalid.
-func NewConstSummary(
-	desc *Desc,
-	count uint64,
-	sum float64,
-	quantiles map[float64]float64,
-	labelValues ...string,
-) (Metric, error) {
-	if desc.err != nil {
-		return nil, desc.err
-	}
-	if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
-		return nil, err
-	}
-	return &constSummary{
-		desc:       desc,
-		count:      count,
-		sum:        sum,
-		quantiles:  quantiles,
-		labelPairs: makeLabelPairs(desc, labelValues),
-	}, nil
-}
-
-// MustNewConstSummary is a version of NewConstSummary that panics where
-// NewConstMetric would have returned an error.
-func MustNewConstSummary(
-	desc *Desc,
-	count uint64,
-	sum float64,
-	quantiles map[float64]float64,
-	labelValues ...string,
-) Metric {
-	m, err := NewConstSummary(desc, count, sum, quantiles, labelValues...)
-	if err != nil {
-		panic(err)
-	}
-	return m
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/timer.go b/vendor/github.com/prometheus/client_golang/prometheus/timer.go
deleted file mode 100644
index 8d5f105..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/timer.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import "time"
-
-// Timer is a helper type to time functions. Use NewTimer to create new
-// instances.
-type Timer struct {
-	begin    time.Time
-	observer Observer
-}
-
-// NewTimer creates a new Timer. The provided Observer is used to observe a
-// duration in seconds. Timer is usually used to time a function call in the
-// following way:
-//    func TimeMe() {
-//        timer := NewTimer(myHistogram)
-//        defer timer.ObserveDuration()
-//        // Do actual work.
-//    }
-func NewTimer(o Observer) *Timer {
-	return &Timer{
-		begin:    time.Now(),
-		observer: o,
-	}
-}
-
-// ObserveDuration records the duration passed since the Timer was created with
-// NewTimer. It calls the Observe method of the Observer provided during
-// construction with the duration in seconds as an argument. The observed
-// duration is also returned. ObserveDuration is usually called with a defer
-// statement.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-func (t *Timer) ObserveDuration() time.Duration {
-	d := time.Since(t.begin)
-	if t.observer != nil {
-		t.observer.Observe(d.Seconds())
-	}
-	return d
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/untyped.go b/vendor/github.com/prometheus/client_golang/prometheus/untyped.go
deleted file mode 100644
index 0f9ce63..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/untyped.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-// UntypedOpts is an alias for Opts. See there for doc comments.
-type UntypedOpts Opts
-
-// UntypedFunc works like GaugeFunc but the collected metric is of type
-// "Untyped". UntypedFunc is useful to mirror an external metric of unknown
-// type.
-//
-// To create UntypedFunc instances, use NewUntypedFunc.
-type UntypedFunc interface {
-	Metric
-	Collector
-}
-
-// NewUntypedFunc creates a new UntypedFunc based on the provided
-// UntypedOpts. The value reported is determined by calling the given function
-// from within the Write method. Take into account that metric collection may
-// happen concurrently. If that results in concurrent calls to Write, like in
-// the case where an UntypedFunc is directly registered with Prometheus, the
-// provided function must be concurrency-safe.
-func NewUntypedFunc(opts UntypedOpts, function func() float64) UntypedFunc {
-	return newValueFunc(NewDesc(
-		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-		opts.Help,
-		nil,
-		opts.ConstLabels,
-	), UntypedValue, function)
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/value.go b/vendor/github.com/prometheus/client_golang/prometheus/value.go
deleted file mode 100644
index eb248f1..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/value.go
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"fmt"
-	"sort"
-
-	"github.com/golang/protobuf/proto"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-// ValueType is an enumeration of metric types that represent a simple value.
-type ValueType int
-
-// Possible values for the ValueType enum.
-const (
-	_ ValueType = iota
-	CounterValue
-	GaugeValue
-	UntypedValue
-)
-
-// valueFunc is a generic metric for simple values retrieved on collect time
-// from a function. It implements Metric and Collector. Its effective type is
-// determined by ValueType. This is a low-level building block used by the
-// library to back the implementations of CounterFunc, GaugeFunc, and
-// UntypedFunc.
-type valueFunc struct {
-	selfCollector
-
-	desc       *Desc
-	valType    ValueType
-	function   func() float64
-	labelPairs []*dto.LabelPair
-}
-
-// newValueFunc returns a newly allocated valueFunc with the given Desc and
-// ValueType. The value reported is determined by calling the given function
-// from within the Write method. Take into account that metric collection may
-// happen concurrently. If that results in concurrent calls to Write, like in
-// the case where a valueFunc is directly registered with Prometheus, the
-// provided function must be concurrency-safe.
-func newValueFunc(desc *Desc, valueType ValueType, function func() float64) *valueFunc {
-	result := &valueFunc{
-		desc:       desc,
-		valType:    valueType,
-		function:   function,
-		labelPairs: makeLabelPairs(desc, nil),
-	}
-	result.init(result)
-	return result
-}
-
-func (v *valueFunc) Desc() *Desc {
-	return v.desc
-}
-
-func (v *valueFunc) Write(out *dto.Metric) error {
-	return populateMetric(v.valType, v.function(), v.labelPairs, out)
-}
-
-// NewConstMetric returns a metric with one fixed value that cannot be
-// changed. Users of this package will not have much use for it in regular
-// operations. However, when implementing custom Collectors, it is useful as a
-// throw-away metric that is generated on the fly to send it to Prometheus in
-// the Collect method. NewConstMetric returns an error if the length of
-// labelValues is not consistent with the variable labels in Desc or if Desc is
-// invalid.
-func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) {
-	if desc.err != nil {
-		return nil, desc.err
-	}
-	if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
-		return nil, err
-	}
-	return &constMetric{
-		desc:       desc,
-		valType:    valueType,
-		val:        value,
-		labelPairs: makeLabelPairs(desc, labelValues),
-	}, nil
-}
-
-// MustNewConstMetric is a version of NewConstMetric that panics where
-// NewConstMetric would have returned an error.
-func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric {
-	m, err := NewConstMetric(desc, valueType, value, labelValues...)
-	if err != nil {
-		panic(err)
-	}
-	return m
-}
-
-type constMetric struct {
-	desc       *Desc
-	valType    ValueType
-	val        float64
-	labelPairs []*dto.LabelPair
-}
-
-func (m *constMetric) Desc() *Desc {
-	return m.desc
-}
-
-func (m *constMetric) Write(out *dto.Metric) error {
-	return populateMetric(m.valType, m.val, m.labelPairs, out)
-}
-
-func populateMetric(
-	t ValueType,
-	v float64,
-	labelPairs []*dto.LabelPair,
-	m *dto.Metric,
-) error {
-	m.Label = labelPairs
-	switch t {
-	case CounterValue:
-		m.Counter = &dto.Counter{Value: proto.Float64(v)}
-	case GaugeValue:
-		m.Gauge = &dto.Gauge{Value: proto.Float64(v)}
-	case UntypedValue:
-		m.Untyped = &dto.Untyped{Value: proto.Float64(v)}
-	default:
-		return fmt.Errorf("encountered unknown type %v", t)
-	}
-	return nil
-}
-
-func makeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair {
-	totalLen := len(desc.variableLabels) + len(desc.constLabelPairs)
-	if totalLen == 0 {
-		// Super fast path.
-		return nil
-	}
-	if len(desc.variableLabels) == 0 {
-		// Moderately fast path.
-		return desc.constLabelPairs
-	}
-	labelPairs := make([]*dto.LabelPair, 0, totalLen)
-	for i, n := range desc.variableLabels {
-		labelPairs = append(labelPairs, &dto.LabelPair{
-			Name:  proto.String(n),
-			Value: proto.String(labelValues[i]),
-		})
-	}
-	labelPairs = append(labelPairs, desc.constLabelPairs...)
-	sort.Sort(labelPairSorter(labelPairs))
-	return labelPairs
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/vendor/github.com/prometheus/client_golang/prometheus/vec.go
deleted file mode 100644
index 14ed9e8..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/vec.go
+++ /dev/null
@@ -1,472 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"fmt"
-	"sync"
-
-	"github.com/prometheus/common/model"
-)
-
-// metricVec is a Collector to bundle metrics of the same name that differ in
-// their label values. metricVec is not used directly (and therefore
-// unexported). It is used as a building block for implementations of vectors of
-// a given metric type, like GaugeVec, CounterVec, SummaryVec, and HistogramVec.
-// It also handles label currying. It uses basicMetricVec internally.
-type metricVec struct {
-	*metricMap
-
-	curry []curriedLabelValue
-
-	// hashAdd and hashAddByte can be replaced for testing collision handling.
-	hashAdd     func(h uint64, s string) uint64
-	hashAddByte func(h uint64, b byte) uint64
-}
-
-// newMetricVec returns an initialized metricVec.
-func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *metricVec {
-	return &metricVec{
-		metricMap: &metricMap{
-			metrics:   map[uint64][]metricWithLabelValues{},
-			desc:      desc,
-			newMetric: newMetric,
-		},
-		hashAdd:     hashAdd,
-		hashAddByte: hashAddByte,
-	}
-}
-
-// DeleteLabelValues removes the metric where the variable labels are the same
-// as those passed in as labels (same order as the VariableLabels in Desc). It
-// returns true if a metric was deleted.
-//
-// It is not an error if the number of label values is not the same as the
-// number of VariableLabels in Desc. However, such inconsistent label count can
-// never match an actual metric, so the method will always return false in that
-// case.
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider Delete(Labels) as an
-// alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the CounterVec example.
-func (m *metricVec) DeleteLabelValues(lvs ...string) bool {
-	h, err := m.hashLabelValues(lvs)
-	if err != nil {
-		return false
-	}
-
-	return m.metricMap.deleteByHashWithLabelValues(h, lvs, m.curry)
-}
-
-// Delete deletes the metric where the variable labels are the same as those
-// passed in as labels. It returns true if a metric was deleted.
-//
-// It is not an error if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc. However, such inconsistent Labels
-// can never match an actual metric, so the method will always return false in
-// that case.
-//
-// This method is used for the same purpose as DeleteLabelValues(...string). See
-// there for pros and cons of the two methods.
-func (m *metricVec) Delete(labels Labels) bool {
-	h, err := m.hashLabels(labels)
-	if err != nil {
-		return false
-	}
-
-	return m.metricMap.deleteByHashWithLabels(h, labels, m.curry)
-}
-
-func (m *metricVec) curryWith(labels Labels) (*metricVec, error) {
-	var (
-		newCurry []curriedLabelValue
-		oldCurry = m.curry
-		iCurry   int
-	)
-	for i, label := range m.desc.variableLabels {
-		val, ok := labels[label]
-		if iCurry < len(oldCurry) && oldCurry[iCurry].index == i {
-			if ok {
-				return nil, fmt.Errorf("label name %q is already curried", label)
-			}
-			newCurry = append(newCurry, oldCurry[iCurry])
-			iCurry++
-		} else {
-			if !ok {
-				continue // Label stays uncurried.
-			}
-			newCurry = append(newCurry, curriedLabelValue{i, val})
-		}
-	}
-	if l := len(oldCurry) + len(labels) - len(newCurry); l > 0 {
-		return nil, fmt.Errorf("%d unknown label(s) found during currying", l)
-	}
-
-	return &metricVec{
-		metricMap:   m.metricMap,
-		curry:       newCurry,
-		hashAdd:     m.hashAdd,
-		hashAddByte: m.hashAddByte,
-	}, nil
-}
-
-func (m *metricVec) getMetricWithLabelValues(lvs ...string) (Metric, error) {
-	h, err := m.hashLabelValues(lvs)
-	if err != nil {
-		return nil, err
-	}
-
-	return m.metricMap.getOrCreateMetricWithLabelValues(h, lvs, m.curry), nil
-}
-
-func (m *metricVec) getMetricWith(labels Labels) (Metric, error) {
-	h, err := m.hashLabels(labels)
-	if err != nil {
-		return nil, err
-	}
-
-	return m.metricMap.getOrCreateMetricWithLabels(h, labels, m.curry), nil
-}
-
-func (m *metricVec) hashLabelValues(vals []string) (uint64, error) {
-	if err := validateLabelValues(vals, len(m.desc.variableLabels)-len(m.curry)); err != nil {
-		return 0, err
-	}
-
-	var (
-		h             = hashNew()
-		curry         = m.curry
-		iVals, iCurry int
-	)
-	for i := 0; i < len(m.desc.variableLabels); i++ {
-		if iCurry < len(curry) && curry[iCurry].index == i {
-			h = m.hashAdd(h, curry[iCurry].value)
-			iCurry++
-		} else {
-			h = m.hashAdd(h, vals[iVals])
-			iVals++
-		}
-		h = m.hashAddByte(h, model.SeparatorByte)
-	}
-	return h, nil
-}
-
-func (m *metricVec) hashLabels(labels Labels) (uint64, error) {
-	if err := validateValuesInLabels(labels, len(m.desc.variableLabels)-len(m.curry)); err != nil {
-		return 0, err
-	}
-
-	var (
-		h      = hashNew()
-		curry  = m.curry
-		iCurry int
-	)
-	for i, label := range m.desc.variableLabels {
-		val, ok := labels[label]
-		if iCurry < len(curry) && curry[iCurry].index == i {
-			if ok {
-				return 0, fmt.Errorf("label name %q is already curried", label)
-			}
-			h = m.hashAdd(h, curry[iCurry].value)
-			iCurry++
-		} else {
-			if !ok {
-				return 0, fmt.Errorf("label name %q missing in label map", label)
-			}
-			h = m.hashAdd(h, val)
-		}
-		h = m.hashAddByte(h, model.SeparatorByte)
-	}
-	return h, nil
-}
-
-// metricWithLabelValues provides the metric and its label values for
-// disambiguation on hash collision.
-type metricWithLabelValues struct {
-	values []string
-	metric Metric
-}
-
-// curriedLabelValue sets the curried value for a label at the given index.
-type curriedLabelValue struct {
-	index int
-	value string
-}
-
-// metricMap is a helper for metricVec and shared between differently curried
-// metricVecs.
-type metricMap struct {
-	mtx       sync.RWMutex // Protects metrics.
-	metrics   map[uint64][]metricWithLabelValues
-	desc      *Desc
-	newMetric func(labelValues ...string) Metric
-}
-
-// Describe implements Collector. It will send exactly one Desc to the provided
-// channel.
-func (m *metricMap) Describe(ch chan<- *Desc) {
-	ch <- m.desc
-}
-
-// Collect implements Collector.
-func (m *metricMap) Collect(ch chan<- Metric) {
-	m.mtx.RLock()
-	defer m.mtx.RUnlock()
-
-	for _, metrics := range m.metrics {
-		for _, metric := range metrics {
-			ch <- metric.metric
-		}
-	}
-}
-
-// Reset deletes all metrics in this vector.
-func (m *metricMap) Reset() {
-	m.mtx.Lock()
-	defer m.mtx.Unlock()
-
-	for h := range m.metrics {
-		delete(m.metrics, h)
-	}
-}
-
-// deleteByHashWithLabelValues removes the metric from the hash bucket h. If
-// there are multiple matches in the bucket, use lvs to select a metric and
-// remove only that metric.
-func (m *metricMap) deleteByHashWithLabelValues(
-	h uint64, lvs []string, curry []curriedLabelValue,
-) bool {
-	m.mtx.Lock()
-	defer m.mtx.Unlock()
-
-	metrics, ok := m.metrics[h]
-	if !ok {
-		return false
-	}
-
-	i := findMetricWithLabelValues(metrics, lvs, curry)
-	if i >= len(metrics) {
-		return false
-	}
-
-	if len(metrics) > 1 {
-		m.metrics[h] = append(metrics[:i], metrics[i+1:]...)
-	} else {
-		delete(m.metrics, h)
-	}
-	return true
-}
-
-// deleteByHashWithLabels removes the metric from the hash bucket h. If there
-// are multiple matches in the bucket, use lvs to select a metric and remove
-// only that metric.
-func (m *metricMap) deleteByHashWithLabels(
-	h uint64, labels Labels, curry []curriedLabelValue,
-) bool {
-	m.mtx.Lock()
-	defer m.mtx.Unlock()
-
-	metrics, ok := m.metrics[h]
-	if !ok {
-		return false
-	}
-	i := findMetricWithLabels(m.desc, metrics, labels, curry)
-	if i >= len(metrics) {
-		return false
-	}
-
-	if len(metrics) > 1 {
-		m.metrics[h] = append(metrics[:i], metrics[i+1:]...)
-	} else {
-		delete(m.metrics, h)
-	}
-	return true
-}
-
-// getOrCreateMetricWithLabelValues retrieves the metric by hash and label value
-// or creates it and returns the new one.
-//
-// This function holds the mutex.
-func (m *metricMap) getOrCreateMetricWithLabelValues(
-	hash uint64, lvs []string, curry []curriedLabelValue,
-) Metric {
-	m.mtx.RLock()
-	metric, ok := m.getMetricWithHashAndLabelValues(hash, lvs, curry)
-	m.mtx.RUnlock()
-	if ok {
-		return metric
-	}
-
-	m.mtx.Lock()
-	defer m.mtx.Unlock()
-	metric, ok = m.getMetricWithHashAndLabelValues(hash, lvs, curry)
-	if !ok {
-		inlinedLVs := inlineLabelValues(lvs, curry)
-		metric = m.newMetric(inlinedLVs...)
-		m.metrics[hash] = append(m.metrics[hash], metricWithLabelValues{values: inlinedLVs, metric: metric})
-	}
-	return metric
-}
-
-// getOrCreateMetricWithLabelValues retrieves the metric by hash and label value
-// or creates it and returns the new one.
-//
-// This function holds the mutex.
-func (m *metricMap) getOrCreateMetricWithLabels(
-	hash uint64, labels Labels, curry []curriedLabelValue,
-) Metric {
-	m.mtx.RLock()
-	metric, ok := m.getMetricWithHashAndLabels(hash, labels, curry)
-	m.mtx.RUnlock()
-	if ok {
-		return metric
-	}
-
-	m.mtx.Lock()
-	defer m.mtx.Unlock()
-	metric, ok = m.getMetricWithHashAndLabels(hash, labels, curry)
-	if !ok {
-		lvs := extractLabelValues(m.desc, labels, curry)
-		metric = m.newMetric(lvs...)
-		m.metrics[hash] = append(m.metrics[hash], metricWithLabelValues{values: lvs, metric: metric})
-	}
-	return metric
-}
-
-// getMetricWithHashAndLabelValues gets a metric while handling possible
-// collisions in the hash space. Must be called while holding the read mutex.
-func (m *metricMap) getMetricWithHashAndLabelValues(
-	h uint64, lvs []string, curry []curriedLabelValue,
-) (Metric, bool) {
-	metrics, ok := m.metrics[h]
-	if ok {
-		if i := findMetricWithLabelValues(metrics, lvs, curry); i < len(metrics) {
-			return metrics[i].metric, true
-		}
-	}
-	return nil, false
-}
-
-// getMetricWithHashAndLabels gets a metric while handling possible collisions in
-// the hash space. Must be called while holding read mutex.
-func (m *metricMap) getMetricWithHashAndLabels(
-	h uint64, labels Labels, curry []curriedLabelValue,
-) (Metric, bool) {
-	metrics, ok := m.metrics[h]
-	if ok {
-		if i := findMetricWithLabels(m.desc, metrics, labels, curry); i < len(metrics) {
-			return metrics[i].metric, true
-		}
-	}
-	return nil, false
-}
-
-// findMetricWithLabelValues returns the index of the matching metric or
-// len(metrics) if not found.
-func findMetricWithLabelValues(
-	metrics []metricWithLabelValues, lvs []string, curry []curriedLabelValue,
-) int {
-	for i, metric := range metrics {
-		if matchLabelValues(metric.values, lvs, curry) {
-			return i
-		}
-	}
-	return len(metrics)
-}
-
-// findMetricWithLabels returns the index of the matching metric or len(metrics)
-// if not found.
-func findMetricWithLabels(
-	desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue,
-) int {
-	for i, metric := range metrics {
-		if matchLabels(desc, metric.values, labels, curry) {
-			return i
-		}
-	}
-	return len(metrics)
-}
-
-func matchLabelValues(values []string, lvs []string, curry []curriedLabelValue) bool {
-	if len(values) != len(lvs)+len(curry) {
-		return false
-	}
-	var iLVs, iCurry int
-	for i, v := range values {
-		if iCurry < len(curry) && curry[iCurry].index == i {
-			if v != curry[iCurry].value {
-				return false
-			}
-			iCurry++
-			continue
-		}
-		if v != lvs[iLVs] {
-			return false
-		}
-		iLVs++
-	}
-	return true
-}
-
-func matchLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool {
-	if len(values) != len(labels)+len(curry) {
-		return false
-	}
-	iCurry := 0
-	for i, k := range desc.variableLabels {
-		if iCurry < len(curry) && curry[iCurry].index == i {
-			if values[i] != curry[iCurry].value {
-				return false
-			}
-			iCurry++
-			continue
-		}
-		if values[i] != labels[k] {
-			return false
-		}
-	}
-	return true
-}
-
-func extractLabelValues(desc *Desc, labels Labels, curry []curriedLabelValue) []string {
-	labelValues := make([]string, len(labels)+len(curry))
-	iCurry := 0
-	for i, k := range desc.variableLabels {
-		if iCurry < len(curry) && curry[iCurry].index == i {
-			labelValues[i] = curry[iCurry].value
-			iCurry++
-			continue
-		}
-		labelValues[i] = labels[k]
-	}
-	return labelValues
-}
-
-func inlineLabelValues(lvs []string, curry []curriedLabelValue) []string {
-	labelValues := make([]string, len(lvs)+len(curry))
-	var iCurry, iLVs int
-	for i := range labelValues {
-		if iCurry < len(curry) && curry[iCurry].index == i {
-			labelValues[i] = curry[iCurry].value
-			iCurry++
-			continue
-		}
-		labelValues[i] = lvs[iLVs]
-		iLVs++
-	}
-	return labelValues
-}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go
deleted file mode 100644
index 49159bf..0000000
--- a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import (
-	"fmt"
-	"sort"
-
-	"github.com/golang/protobuf/proto"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-// WrapRegistererWith returns a Registerer wrapping the provided
-// Registerer. Collectors registered with the returned Registerer will be
-// registered with the wrapped Registerer in a modified way. The modified
-// Collector adds the provided Labels to all Metrics it collects (as
-// ConstLabels). The Metrics collected by the unmodified Collector must not
-// duplicate any of those labels.
-//
-// WrapRegistererWith provides a way to add fixed labels to a subset of
-// Collectors. It should not be used to add fixed labels to all metrics exposed.
-//
-// The Collector example demonstrates a use of WrapRegistererWith.
-func WrapRegistererWith(labels Labels, reg Registerer) Registerer {
-	return &wrappingRegisterer{
-		wrappedRegisterer: reg,
-		labels:            labels,
-	}
-}
-
-// WrapRegistererWithPrefix returns a Registerer wrapping the provided
-// Registerer. Collectors registered with the returned Registerer will be
-// registered with the wrapped Registerer in a modified way. The modified
-// Collector adds the provided prefix to the name of all Metrics it collects.
-//
-// WrapRegistererWithPrefix is useful to have one place to prefix all metrics of
-// a sub-system. To make this work, register metrics of the sub-system with the
-// wrapping Registerer returned by WrapRegistererWithPrefix. It is rarely useful
-// to use the same prefix for all metrics exposed. In particular, do not prefix
-// metric names that are standardized across applications, as that would break
-// horizontal monitoring, for example the metrics provided by the Go collector
-// (see NewGoCollector) and the process collector (see NewProcessCollector). (In
-// fact, those metrics are already prefixed with “go_” or “process_”,
-// respectively.)
-func WrapRegistererWithPrefix(prefix string, reg Registerer) Registerer {
-	return &wrappingRegisterer{
-		wrappedRegisterer: reg,
-		prefix:            prefix,
-	}
-}
-
-type wrappingRegisterer struct {
-	wrappedRegisterer Registerer
-	prefix            string
-	labels            Labels
-}
-
-func (r *wrappingRegisterer) Register(c Collector) error {
-	return r.wrappedRegisterer.Register(&wrappingCollector{
-		wrappedCollector: c,
-		prefix:           r.prefix,
-		labels:           r.labels,
-	})
-}
-
-func (r *wrappingRegisterer) MustRegister(cs ...Collector) {
-	for _, c := range cs {
-		if err := r.Register(c); err != nil {
-			panic(err)
-		}
-	}
-}
-
-func (r *wrappingRegisterer) Unregister(c Collector) bool {
-	return r.wrappedRegisterer.Unregister(&wrappingCollector{
-		wrappedCollector: c,
-		prefix:           r.prefix,
-		labels:           r.labels,
-	})
-}
-
-type wrappingCollector struct {
-	wrappedCollector Collector
-	prefix           string
-	labels           Labels
-}
-
-func (c *wrappingCollector) Collect(ch chan<- Metric) {
-	wrappedCh := make(chan Metric)
-	go func() {
-		c.wrappedCollector.Collect(wrappedCh)
-		close(wrappedCh)
-	}()
-	for m := range wrappedCh {
-		ch <- &wrappingMetric{
-			wrappedMetric: m,
-			prefix:        c.prefix,
-			labels:        c.labels,
-		}
-	}
-}
-
-func (c *wrappingCollector) Describe(ch chan<- *Desc) {
-	wrappedCh := make(chan *Desc)
-	go func() {
-		c.wrappedCollector.Describe(wrappedCh)
-		close(wrappedCh)
-	}()
-	for desc := range wrappedCh {
-		ch <- wrapDesc(desc, c.prefix, c.labels)
-	}
-}
-
-type wrappingMetric struct {
-	wrappedMetric Metric
-	prefix        string
-	labels        Labels
-}
-
-func (m *wrappingMetric) Desc() *Desc {
-	return wrapDesc(m.wrappedMetric.Desc(), m.prefix, m.labels)
-}
-
-func (m *wrappingMetric) Write(out *dto.Metric) error {
-	if err := m.wrappedMetric.Write(out); err != nil {
-		return err
-	}
-	if len(m.labels) == 0 {
-		// No wrapping labels.
-		return nil
-	}
-	for ln, lv := range m.labels {
-		out.Label = append(out.Label, &dto.LabelPair{
-			Name:  proto.String(ln),
-			Value: proto.String(lv),
-		})
-	}
-	sort.Sort(labelPairSorter(out.Label))
-	return nil
-}
-
-func wrapDesc(desc *Desc, prefix string, labels Labels) *Desc {
-	constLabels := Labels{}
-	for _, lp := range desc.constLabelPairs {
-		constLabels[*lp.Name] = *lp.Value
-	}
-	for ln, lv := range labels {
-		if _, alreadyUsed := constLabels[ln]; alreadyUsed {
-			return &Desc{
-				fqName:          desc.fqName,
-				help:            desc.help,
-				variableLabels:  desc.variableLabels,
-				constLabelPairs: desc.constLabelPairs,
-				err:             fmt.Errorf("attempted wrapping with already existing label name %q", ln),
-			}
-		}
-		constLabels[ln] = lv
-	}
-	// NewDesc will do remaining validations.
-	newDesc := NewDesc(prefix+desc.fqName, desc.help, desc.variableLabels, constLabels)
-	// Propagate errors if there was any. This will override any errer
-	// created by NewDesc above, i.e. earlier errors get precedence.
-	if desc.err != nil {
-		newDesc.err = desc.err
-	}
-	return newDesc
-}
diff --git a/vendor/github.com/prometheus/client_model/LICENSE b/vendor/github.com/prometheus/client_model/LICENSE
deleted file mode 100644
index 261eeb9..0000000
--- a/vendor/github.com/prometheus/client_model/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/prometheus/client_model/NOTICE b/vendor/github.com/prometheus/client_model/NOTICE
deleted file mode 100644
index 20110e4..0000000
--- a/vendor/github.com/prometheus/client_model/NOTICE
+++ /dev/null
@@ -1,5 +0,0 @@
-Data model artifacts for Prometheus.
-Copyright 2012-2015 The Prometheus Authors
-
-This product includes software developed at
-SoundCloud Ltd. (http://soundcloud.com/).
diff --git a/vendor/github.com/prometheus/client_model/ruby/LICENSE b/vendor/github.com/prometheus/client_model/ruby/LICENSE
deleted file mode 100644
index 11069ed..0000000
--- a/vendor/github.com/prometheus/client_model/ruby/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                              Apache License
-                        Version 2.0, January 2004
-                     http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-   "License" shall mean the terms and conditions for use, reproduction,
-   and distribution as defined by Sections 1 through 9 of this document.
-
-   "Licensor" shall mean the copyright owner or entity authorized by
-   the copyright owner that is granting the License.
-
-   "Legal Entity" shall mean the union of the acting entity and all
-   other entities that control, are controlled by, or are under common
-   control with that entity. For the purposes of this definition,
-   "control" means (i) the power, direct or indirect, to cause the
-   direction or management of such entity, whether by contract or
-   otherwise, or (ii) ownership of fifty percent (50%) or more of the
-   outstanding shares, or (iii) beneficial ownership of such entity.
-
-   "You" (or "Your") shall mean an individual or Legal Entity
-   exercising permissions granted by this License.
-
-   "Source" form shall mean the preferred form for making modifications,
-   including but not limited to software source code, documentation
-   source, and configuration files.
-
-   "Object" form shall mean any form resulting from mechanical
-   transformation or translation of a Source form, including but
-   not limited to compiled object code, generated documentation,
-   and conversions to other media types.
-
-   "Work" shall mean the work of authorship, whether in Source or
-   Object form, made available under the License, as indicated by a
-   copyright notice that is included in or attached to the work
-   (an example is provided in the Appendix below).
-
-   "Derivative Works" shall mean any work, whether in Source or Object
-   form, that is based on (or derived from) the Work and for which the
-   editorial revisions, annotations, elaborations, or other modifications
-   represent, as a whole, an original work of authorship. For the purposes
-   of this License, Derivative Works shall not include works that remain
-   separable from, or merely link (or bind by name) to the interfaces of,
-   the Work and Derivative Works thereof.
-
-   "Contribution" shall mean any work of authorship, including
-   the original version of the Work and any modifications or additions
-   to that Work or Derivative Works thereof, that is intentionally
-   submitted to Licensor for inclusion in the Work by the copyright owner
-   or by an individual or Legal Entity authorized to submit on behalf of
-   the copyright owner. For the purposes of this definition, "submitted"
-   means any form of electronic, verbal, or written communication sent
-   to the Licensor or its representatives, including but not limited to
-   communication on electronic mailing lists, source code control systems,
-   and issue tracking systems that are managed by, or on behalf of, the
-   Licensor for the purpose of discussing and improving the Work, but
-   excluding communication that is conspicuously marked or otherwise
-   designated in writing by the copyright owner as "Not a Contribution."
-
-   "Contributor" shall mean Licensor and any individual or Legal Entity
-   on behalf of whom a Contribution has been received by Licensor and
-   subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   copyright license to reproduce, prepare Derivative Works of,
-   publicly display, publicly perform, sublicense, and distribute the
-   Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   (except as stated in this section) patent license to make, have made,
-   use, offer to sell, sell, import, and otherwise transfer the Work,
-   where such license applies only to those patent claims licensable
-   by such Contributor that are necessarily infringed by their
-   Contribution(s) alone or by combination of their Contribution(s)
-   with the Work to which such Contribution(s) was submitted. If You
-   institute patent litigation against any entity (including a
-   cross-claim or counterclaim in a lawsuit) alleging that the Work
-   or a Contribution incorporated within the Work constitutes direct
-   or contributory patent infringement, then any patent licenses
-   granted to You under this License for that Work shall terminate
-   as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
-   Work or Derivative Works thereof in any medium, with or without
-   modifications, and in Source or Object form, provided that You
-   meet the following conditions:
-
-   (a) You must give any other recipients of the Work or
-       Derivative Works a copy of this License; and
-
-   (b) You must cause any modified files to carry prominent notices
-       stating that You changed the files; and
-
-   (c) You must retain, in the Source form of any Derivative Works
-       that You distribute, all copyright, patent, trademark, and
-       attribution notices from the Source form of the Work,
-       excluding those notices that do not pertain to any part of
-       the Derivative Works; and
-
-   (d) If the Work includes a "NOTICE" text file as part of its
-       distribution, then any Derivative Works that You distribute must
-       include a readable copy of the attribution notices contained
-       within such NOTICE file, excluding those notices that do not
-       pertain to any part of the Derivative Works, in at least one
-       of the following places: within a NOTICE text file distributed
-       as part of the Derivative Works; within the Source form or
-       documentation, if provided along with the Derivative Works; or,
-       within a display generated by the Derivative Works, if and
-       wherever such third-party notices normally appear. The contents
-       of the NOTICE file are for informational purposes only and
-       do not modify the License. You may add Your own attribution
-       notices within Derivative Works that You distribute, alongside
-       or as an addendum to the NOTICE text from the Work, provided
-       that such additional attribution notices cannot be construed
-       as modifying the License.
-
-   You may add Your own copyright statement to Your modifications and
-   may provide additional or different license terms and conditions
-   for use, reproduction, or distribution of Your modifications, or
-   for any such Derivative Works as a whole, provided Your use,
-   reproduction, and distribution of the Work otherwise complies with
-   the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
-   any Contribution intentionally submitted for inclusion in the Work
-   by You to the Licensor shall be under the terms and conditions of
-   this License, without any additional terms or conditions.
-   Notwithstanding the above, nothing herein shall supersede or modify
-   the terms of any separate license agreement you may have executed
-   with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
-   names, trademarks, service marks, or product names of the Licensor,
-   except as required for reasonable and customary use in describing the
-   origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
-   agreed to in writing, Licensor provides the Work (and each
-   Contributor provides its Contributions) on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-   implied, including, without limitation, any warranties or conditions
-   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-   PARTICULAR PURPOSE. You are solely responsible for determining the
-   appropriateness of using or redistributing the Work and assume any
-   risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
-   whether in tort (including negligence), contract, or otherwise,
-   unless required by applicable law (such as deliberate and grossly
-   negligent acts) or agreed to in writing, shall any Contributor be
-   liable to You for damages, including any direct, indirect, special,
-   incidental, or consequential damages of any character arising as a
-   result of this License or out of the use or inability to use the
-   Work (including but not limited to damages for loss of goodwill,
-   work stoppage, computer failure or malfunction, or any and all
-   other commercial damages or losses), even if such Contributor
-   has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
-   the Work or Derivative Works thereof, You may choose to offer,
-   and charge a fee for, acceptance of support, warranty, indemnity,
-   or other liability obligations and/or rights consistent with this
-   License. However, in accepting such obligations, You may act only
-   on Your own behalf and on Your sole responsibility, not on behalf
-   of any other Contributor, and only if You agree to indemnify,
-   defend, and hold each Contributor harmless for any liability
-   incurred by, or claims asserted against, such Contributor by reason
-   of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
-   To apply the Apache License to your work, attach the following
-   boilerplate notice, with the fields enclosed by brackets "[]"
-   replaced with your own identifying information. (Don't include
-   the brackets!)  The text should be enclosed in the appropriate
-   comment syntax for the file format. We also recommend that a
-   file or class name and description of purpose be included on the
-   same "printed page" as the copyright notice for easier
-   identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/vendor/github.com/prometheus/common/LICENSE b/vendor/github.com/prometheus/common/LICENSE
deleted file mode 100644
index 261eeb9..0000000
--- a/vendor/github.com/prometheus/common/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/prometheus/common/NOTICE b/vendor/github.com/prometheus/common/NOTICE
deleted file mode 100644
index 636a2c1..0000000
--- a/vendor/github.com/prometheus/common/NOTICE
+++ /dev/null
@@ -1,5 +0,0 @@
-Common libraries shared by Prometheus Go components.
-Copyright 2015 The Prometheus Authors
-
-This product includes software developed at
-SoundCloud Ltd. (http://soundcloud.com/).
diff --git a/vendor/github.com/prometheus/common/expfmt/decode.go b/vendor/github.com/prometheus/common/expfmt/decode.go
deleted file mode 100644
index c092723..0000000
--- a/vendor/github.com/prometheus/common/expfmt/decode.go
+++ /dev/null
@@ -1,429 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package expfmt
-
-import (
-	"fmt"
-	"io"
-	"math"
-	"mime"
-	"net/http"
-
-	dto "github.com/prometheus/client_model/go"
-
-	"github.com/matttproud/golang_protobuf_extensions/pbutil"
-	"github.com/prometheus/common/model"
-)
-
-// Decoder types decode an input stream into metric families.
-type Decoder interface {
-	Decode(*dto.MetricFamily) error
-}
-
-// DecodeOptions contains options used by the Decoder and in sample extraction.
-type DecodeOptions struct {
-	// Timestamp is added to each value from the stream that has no explicit timestamp set.
-	Timestamp model.Time
-}
-
-// ResponseFormat extracts the correct format from a HTTP response header.
-// If no matching format can be found FormatUnknown is returned.
-func ResponseFormat(h http.Header) Format {
-	ct := h.Get(hdrContentType)
-
-	mediatype, params, err := mime.ParseMediaType(ct)
-	if err != nil {
-		return FmtUnknown
-	}
-
-	const textType = "text/plain"
-
-	switch mediatype {
-	case ProtoType:
-		if p, ok := params["proto"]; ok && p != ProtoProtocol {
-			return FmtUnknown
-		}
-		if e, ok := params["encoding"]; ok && e != "delimited" {
-			return FmtUnknown
-		}
-		return FmtProtoDelim
-
-	case textType:
-		if v, ok := params["version"]; ok && v != TextVersion {
-			return FmtUnknown
-		}
-		return FmtText
-	}
-
-	return FmtUnknown
-}
-
-// NewDecoder returns a new decoder based on the given input format.
-// If the input format does not imply otherwise, a text format decoder is returned.
-func NewDecoder(r io.Reader, format Format) Decoder {
-	switch format {
-	case FmtProtoDelim:
-		return &protoDecoder{r: r}
-	}
-	return &textDecoder{r: r}
-}
-
-// protoDecoder implements the Decoder interface for protocol buffers.
-type protoDecoder struct {
-	r io.Reader
-}
-
-// Decode implements the Decoder interface.
-func (d *protoDecoder) Decode(v *dto.MetricFamily) error {
-	_, err := pbutil.ReadDelimited(d.r, v)
-	if err != nil {
-		return err
-	}
-	if !model.IsValidMetricName(model.LabelValue(v.GetName())) {
-		return fmt.Errorf("invalid metric name %q", v.GetName())
-	}
-	for _, m := range v.GetMetric() {
-		if m == nil {
-			continue
-		}
-		for _, l := range m.GetLabel() {
-			if l == nil {
-				continue
-			}
-			if !model.LabelValue(l.GetValue()).IsValid() {
-				return fmt.Errorf("invalid label value %q", l.GetValue())
-			}
-			if !model.LabelName(l.GetName()).IsValid() {
-				return fmt.Errorf("invalid label name %q", l.GetName())
-			}
-		}
-	}
-	return nil
-}
-
-// textDecoder implements the Decoder interface for the text protocol.
-type textDecoder struct {
-	r    io.Reader
-	p    TextParser
-	fams []*dto.MetricFamily
-}
-
-// Decode implements the Decoder interface.
-func (d *textDecoder) Decode(v *dto.MetricFamily) error {
-	// TODO(fabxc): Wrap this as a line reader to make streaming safer.
-	if len(d.fams) == 0 {
-		// No cached metric families, read everything and parse metrics.
-		fams, err := d.p.TextToMetricFamilies(d.r)
-		if err != nil {
-			return err
-		}
-		if len(fams) == 0 {
-			return io.EOF
-		}
-		d.fams = make([]*dto.MetricFamily, 0, len(fams))
-		for _, f := range fams {
-			d.fams = append(d.fams, f)
-		}
-	}
-
-	*v = *d.fams[0]
-	d.fams = d.fams[1:]
-
-	return nil
-}
-
-// SampleDecoder wraps a Decoder to extract samples from the metric families
-// decoded by the wrapped Decoder.
-type SampleDecoder struct {
-	Dec  Decoder
-	Opts *DecodeOptions
-
-	f dto.MetricFamily
-}
-
-// Decode calls the Decode method of the wrapped Decoder and then extracts the
-// samples from the decoded MetricFamily into the provided model.Vector.
-func (sd *SampleDecoder) Decode(s *model.Vector) error {
-	err := sd.Dec.Decode(&sd.f)
-	if err != nil {
-		return err
-	}
-	*s, err = extractSamples(&sd.f, sd.Opts)
-	return err
-}
-
-// ExtractSamples builds a slice of samples from the provided metric
-// families. If an error occurrs during sample extraction, it continues to
-// extract from the remaining metric families. The returned error is the last
-// error that has occurred.
-func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) {
-	var (
-		all     model.Vector
-		lastErr error
-	)
-	for _, f := range fams {
-		some, err := extractSamples(f, o)
-		if err != nil {
-			lastErr = err
-			continue
-		}
-		all = append(all, some...)
-	}
-	return all, lastErr
-}
-
-func extractSamples(f *dto.MetricFamily, o *DecodeOptions) (model.Vector, error) {
-	switch f.GetType() {
-	case dto.MetricType_COUNTER:
-		return extractCounter(o, f), nil
-	case dto.MetricType_GAUGE:
-		return extractGauge(o, f), nil
-	case dto.MetricType_SUMMARY:
-		return extractSummary(o, f), nil
-	case dto.MetricType_UNTYPED:
-		return extractUntyped(o, f), nil
-	case dto.MetricType_HISTOGRAM:
-		return extractHistogram(o, f), nil
-	}
-	return nil, fmt.Errorf("expfmt.extractSamples: unknown metric family type %v", f.GetType())
-}
-
-func extractCounter(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
-	samples := make(model.Vector, 0, len(f.Metric))
-
-	for _, m := range f.Metric {
-		if m.Counter == nil {
-			continue
-		}
-
-		lset := make(model.LabelSet, len(m.Label)+1)
-		for _, p := range m.Label {
-			lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
-		}
-		lset[model.MetricNameLabel] = model.LabelValue(f.GetName())
-
-		smpl := &model.Sample{
-			Metric: model.Metric(lset),
-			Value:  model.SampleValue(m.Counter.GetValue()),
-		}
-
-		if m.TimestampMs != nil {
-			smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)
-		} else {
-			smpl.Timestamp = o.Timestamp
-		}
-
-		samples = append(samples, smpl)
-	}
-
-	return samples
-}
-
-func extractGauge(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
-	samples := make(model.Vector, 0, len(f.Metric))
-
-	for _, m := range f.Metric {
-		if m.Gauge == nil {
-			continue
-		}
-
-		lset := make(model.LabelSet, len(m.Label)+1)
-		for _, p := range m.Label {
-			lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
-		}
-		lset[model.MetricNameLabel] = model.LabelValue(f.GetName())
-
-		smpl := &model.Sample{
-			Metric: model.Metric(lset),
-			Value:  model.SampleValue(m.Gauge.GetValue()),
-		}
-
-		if m.TimestampMs != nil {
-			smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)
-		} else {
-			smpl.Timestamp = o.Timestamp
-		}
-
-		samples = append(samples, smpl)
-	}
-
-	return samples
-}
-
-func extractUntyped(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
-	samples := make(model.Vector, 0, len(f.Metric))
-
-	for _, m := range f.Metric {
-		if m.Untyped == nil {
-			continue
-		}
-
-		lset := make(model.LabelSet, len(m.Label)+1)
-		for _, p := range m.Label {
-			lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
-		}
-		lset[model.MetricNameLabel] = model.LabelValue(f.GetName())
-
-		smpl := &model.Sample{
-			Metric: model.Metric(lset),
-			Value:  model.SampleValue(m.Untyped.GetValue()),
-		}
-
-		if m.TimestampMs != nil {
-			smpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)
-		} else {
-			smpl.Timestamp = o.Timestamp
-		}
-
-		samples = append(samples, smpl)
-	}
-
-	return samples
-}
-
-func extractSummary(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
-	samples := make(model.Vector, 0, len(f.Metric))
-
-	for _, m := range f.Metric {
-		if m.Summary == nil {
-			continue
-		}
-
-		timestamp := o.Timestamp
-		if m.TimestampMs != nil {
-			timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)
-		}
-
-		for _, q := range m.Summary.Quantile {
-			lset := make(model.LabelSet, len(m.Label)+2)
-			for _, p := range m.Label {
-				lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
-			}
-			// BUG(matt): Update other names to "quantile".
-			lset[model.LabelName(model.QuantileLabel)] = model.LabelValue(fmt.Sprint(q.GetQuantile()))
-			lset[model.MetricNameLabel] = model.LabelValue(f.GetName())
-
-			samples = append(samples, &model.Sample{
-				Metric:    model.Metric(lset),
-				Value:     model.SampleValue(q.GetValue()),
-				Timestamp: timestamp,
-			})
-		}
-
-		lset := make(model.LabelSet, len(m.Label)+1)
-		for _, p := range m.Label {
-			lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
-		}
-		lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum")
-
-		samples = append(samples, &model.Sample{
-			Metric:    model.Metric(lset),
-			Value:     model.SampleValue(m.Summary.GetSampleSum()),
-			Timestamp: timestamp,
-		})
-
-		lset = make(model.LabelSet, len(m.Label)+1)
-		for _, p := range m.Label {
-			lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
-		}
-		lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count")
-
-		samples = append(samples, &model.Sample{
-			Metric:    model.Metric(lset),
-			Value:     model.SampleValue(m.Summary.GetSampleCount()),
-			Timestamp: timestamp,
-		})
-	}
-
-	return samples
-}
-
-func extractHistogram(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
-	samples := make(model.Vector, 0, len(f.Metric))
-
-	for _, m := range f.Metric {
-		if m.Histogram == nil {
-			continue
-		}
-
-		timestamp := o.Timestamp
-		if m.TimestampMs != nil {
-			timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)
-		}
-
-		infSeen := false
-
-		for _, q := range m.Histogram.Bucket {
-			lset := make(model.LabelSet, len(m.Label)+2)
-			for _, p := range m.Label {
-				lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
-			}
-			lset[model.LabelName(model.BucketLabel)] = model.LabelValue(fmt.Sprint(q.GetUpperBound()))
-			lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket")
-
-			if math.IsInf(q.GetUpperBound(), +1) {
-				infSeen = true
-			}
-
-			samples = append(samples, &model.Sample{
-				Metric:    model.Metric(lset),
-				Value:     model.SampleValue(q.GetCumulativeCount()),
-				Timestamp: timestamp,
-			})
-		}
-
-		lset := make(model.LabelSet, len(m.Label)+1)
-		for _, p := range m.Label {
-			lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
-		}
-		lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_sum")
-
-		samples = append(samples, &model.Sample{
-			Metric:    model.Metric(lset),
-			Value:     model.SampleValue(m.Histogram.GetSampleSum()),
-			Timestamp: timestamp,
-		})
-
-		lset = make(model.LabelSet, len(m.Label)+1)
-		for _, p := range m.Label {
-			lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
-		}
-		lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_count")
-
-		count := &model.Sample{
-			Metric:    model.Metric(lset),
-			Value:     model.SampleValue(m.Histogram.GetSampleCount()),
-			Timestamp: timestamp,
-		}
-		samples = append(samples, count)
-
-		if !infSeen {
-			// Append an infinity bucket sample.
-			lset := make(model.LabelSet, len(m.Label)+2)
-			for _, p := range m.Label {
-				lset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())
-			}
-			lset[model.LabelName(model.BucketLabel)] = model.LabelValue("+Inf")
-			lset[model.MetricNameLabel] = model.LabelValue(f.GetName() + "_bucket")
-
-			samples = append(samples, &model.Sample{
-				Metric:    model.Metric(lset),
-				Value:     count.Value,
-				Timestamp: timestamp,
-			})
-		}
-	}
-
-	return samples
-}
diff --git a/vendor/github.com/prometheus/common/expfmt/encode.go b/vendor/github.com/prometheus/common/expfmt/encode.go
deleted file mode 100644
index 11839ed..0000000
--- a/vendor/github.com/prometheus/common/expfmt/encode.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package expfmt
-
-import (
-	"fmt"
-	"io"
-	"net/http"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/matttproud/golang_protobuf_extensions/pbutil"
-	"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-// Encoder types encode metric families into an underlying wire protocol.
-type Encoder interface {
-	Encode(*dto.MetricFamily) error
-}
-
-type encoder func(*dto.MetricFamily) error
-
-func (e encoder) Encode(v *dto.MetricFamily) error {
-	return e(v)
-}
-
-// Negotiate returns the Content-Type based on the given Accept header.
-// If no appropriate accepted type is found, FmtText is returned.
-func Negotiate(h http.Header) Format {
-	for _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) {
-		// Check for protocol buffer
-		if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol {
-			switch ac.Params["encoding"] {
-			case "delimited":
-				return FmtProtoDelim
-			case "text":
-				return FmtProtoText
-			case "compact-text":
-				return FmtProtoCompact
-			}
-		}
-		// Check for text format.
-		ver := ac.Params["version"]
-		if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") {
-			return FmtText
-		}
-	}
-	return FmtText
-}
-
-// NewEncoder returns a new encoder based on content type negotiation.
-func NewEncoder(w io.Writer, format Format) Encoder {
-	switch format {
-	case FmtProtoDelim:
-		return encoder(func(v *dto.MetricFamily) error {
-			_, err := pbutil.WriteDelimited(w, v)
-			return err
-		})
-	case FmtProtoCompact:
-		return encoder(func(v *dto.MetricFamily) error {
-			_, err := fmt.Fprintln(w, v.String())
-			return err
-		})
-	case FmtProtoText:
-		return encoder(func(v *dto.MetricFamily) error {
-			_, err := fmt.Fprintln(w, proto.MarshalTextString(v))
-			return err
-		})
-	case FmtText:
-		return encoder(func(v *dto.MetricFamily) error {
-			_, err := MetricFamilyToText(w, v)
-			return err
-		})
-	}
-	panic("expfmt.NewEncoder: unknown format")
-}
diff --git a/vendor/github.com/prometheus/common/expfmt/expfmt.go b/vendor/github.com/prometheus/common/expfmt/expfmt.go
deleted file mode 100644
index c71bcb9..0000000
--- a/vendor/github.com/prometheus/common/expfmt/expfmt.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package expfmt contains tools for reading and writing Prometheus metrics.
-package expfmt
-
-// Format specifies the HTTP content type of the different wire protocols.
-type Format string
-
-// Constants to assemble the Content-Type values for the different wire protocols.
-const (
-	TextVersion   = "0.0.4"
-	ProtoType     = `application/vnd.google.protobuf`
-	ProtoProtocol = `io.prometheus.client.MetricFamily`
-	ProtoFmt      = ProtoType + "; proto=" + ProtoProtocol + ";"
-
-	// The Content-Type values for the different wire protocols.
-	FmtUnknown      Format = `<unknown>`
-	FmtText         Format = `text/plain; version=` + TextVersion + `; charset=utf-8`
-	FmtProtoDelim   Format = ProtoFmt + ` encoding=delimited`
-	FmtProtoText    Format = ProtoFmt + ` encoding=text`
-	FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`
-)
-
-const (
-	hdrContentType = "Content-Type"
-	hdrAccept      = "Accept"
-)
diff --git a/vendor/github.com/prometheus/common/expfmt/fuzz.go b/vendor/github.com/prometheus/common/expfmt/fuzz.go
deleted file mode 100644
index dc2eede..0000000
--- a/vendor/github.com/prometheus/common/expfmt/fuzz.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Build only when actually fuzzing
-// +build gofuzz
-
-package expfmt
-
-import "bytes"
-
-// Fuzz text metric parser with with github.com/dvyukov/go-fuzz:
-//
-//     go-fuzz-build github.com/prometheus/common/expfmt
-//     go-fuzz -bin expfmt-fuzz.zip -workdir fuzz
-//
-// Further input samples should go in the folder fuzz/corpus.
-func Fuzz(in []byte) int {
-	parser := TextParser{}
-	_, err := parser.TextToMetricFamilies(bytes.NewReader(in))
-
-	if err != nil {
-		return 0
-	}
-
-	return 1
-}
diff --git a/vendor/github.com/prometheus/common/expfmt/text_create.go b/vendor/github.com/prometheus/common/expfmt/text_create.go
deleted file mode 100644
index 16655d4..0000000
--- a/vendor/github.com/prometheus/common/expfmt/text_create.go
+++ /dev/null
@@ -1,474 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package expfmt
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"math"
-	"strconv"
-	"strings"
-	"sync"
-
-	"github.com/prometheus/common/model"
-
-	dto "github.com/prometheus/client_model/go"
-)
-
-// enhancedWriter has all the enhanced write functions needed here. bytes.Buffer
-// implements it.
-type enhancedWriter interface {
-	io.Writer
-	WriteRune(r rune) (n int, err error)
-	WriteString(s string) (n int, err error)
-	WriteByte(c byte) error
-}
-
-const (
-	initialBufSize    = 512
-	initialNumBufSize = 24
-)
-
-var (
-	bufPool = sync.Pool{
-		New: func() interface{} {
-			return bytes.NewBuffer(make([]byte, 0, initialBufSize))
-		},
-	}
-	numBufPool = sync.Pool{
-		New: func() interface{} {
-			b := make([]byte, 0, initialNumBufSize)
-			return &b
-		},
-	}
-)
-
-// MetricFamilyToText converts a MetricFamily proto message into text format and
-// writes the resulting lines to 'out'. It returns the number of bytes written
-// and any error encountered. The output will have the same order as the input,
-// no further sorting is performed. Furthermore, this function assumes the input
-// is already sanitized and does not perform any sanity checks. If the input
-// contains duplicate metrics or invalid metric or label names, the conversion
-// will result in invalid text format output.
-//
-// This method fulfills the type 'prometheus.encoder'.
-func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err error) {
-	// Fail-fast checks.
-	if len(in.Metric) == 0 {
-		return 0, fmt.Errorf("MetricFamily has no metrics: %s", in)
-	}
-	name := in.GetName()
-	if name == "" {
-		return 0, fmt.Errorf("MetricFamily has no name: %s", in)
-	}
-
-	// Try the interface upgrade. If it doesn't work, we'll use a
-	// bytes.Buffer from the sync.Pool and write out its content to out in a
-	// single go in the end.
-	w, ok := out.(enhancedWriter)
-	if !ok {
-		b := bufPool.Get().(*bytes.Buffer)
-		b.Reset()
-		w = b
-		defer func() {
-			bWritten, bErr := out.Write(b.Bytes())
-			written = bWritten
-			if err == nil {
-				err = bErr
-			}
-			bufPool.Put(b)
-		}()
-	}
-
-	var n int
-
-	// Comments, first HELP, then TYPE.
-	if in.Help != nil {
-		n, err = w.WriteString("# HELP ")
-		written += n
-		if err != nil {
-			return
-		}
-		n, err = w.WriteString(name)
-		written += n
-		if err != nil {
-			return
-		}
-		err = w.WriteByte(' ')
-		written++
-		if err != nil {
-			return
-		}
-		n, err = writeEscapedString(w, *in.Help, false)
-		written += n
-		if err != nil {
-			return
-		}
-		err = w.WriteByte('\n')
-		written++
-		if err != nil {
-			return
-		}
-	}
-	n, err = w.WriteString("# TYPE ")
-	written += n
-	if err != nil {
-		return
-	}
-	n, err = w.WriteString(name)
-	written += n
-	if err != nil {
-		return
-	}
-	metricType := in.GetType()
-	switch metricType {
-	case dto.MetricType_COUNTER:
-		n, err = w.WriteString(" counter\n")
-	case dto.MetricType_GAUGE:
-		n, err = w.WriteString(" gauge\n")
-	case dto.MetricType_SUMMARY:
-		n, err = w.WriteString(" summary\n")
-	case dto.MetricType_UNTYPED:
-		n, err = w.WriteString(" untyped\n")
-	case dto.MetricType_HISTOGRAM:
-		n, err = w.WriteString(" histogram\n")
-	default:
-		return written, fmt.Errorf("unknown metric type %s", metricType.String())
-	}
-	written += n
-	if err != nil {
-		return
-	}
-
-	// Finally the samples, one line for each.
-	for _, metric := range in.Metric {
-		switch metricType {
-		case dto.MetricType_COUNTER:
-			if metric.Counter == nil {
-				return written, fmt.Errorf(
-					"expected counter in metric %s %s", name, metric,
-				)
-			}
-			n, err = writeSample(
-				w, name, "", metric, "", 0,
-				metric.Counter.GetValue(),
-			)
-		case dto.MetricType_GAUGE:
-			if metric.Gauge == nil {
-				return written, fmt.Errorf(
-					"expected gauge in metric %s %s", name, metric,
-				)
-			}
-			n, err = writeSample(
-				w, name, "", metric, "", 0,
-				metric.Gauge.GetValue(),
-			)
-		case dto.MetricType_UNTYPED:
-			if metric.Untyped == nil {
-				return written, fmt.Errorf(
-					"expected untyped in metric %s %s", name, metric,
-				)
-			}
-			n, err = writeSample(
-				w, name, "", metric, "", 0,
-				metric.Untyped.GetValue(),
-			)
-		case dto.MetricType_SUMMARY:
-			if metric.Summary == nil {
-				return written, fmt.Errorf(
-					"expected summary in metric %s %s", name, metric,
-				)
-			}
-			for _, q := range metric.Summary.Quantile {
-				n, err = writeSample(
-					w, name, "", metric,
-					model.QuantileLabel, q.GetQuantile(),
-					q.GetValue(),
-				)
-				written += n
-				if err != nil {
-					return
-				}
-			}
-			n, err = writeSample(
-				w, name, "_sum", metric, "", 0,
-				metric.Summary.GetSampleSum(),
-			)
-			written += n
-			if err != nil {
-				return
-			}
-			n, err = writeSample(
-				w, name, "_count", metric, "", 0,
-				float64(metric.Summary.GetSampleCount()),
-			)
-		case dto.MetricType_HISTOGRAM:
-			if metric.Histogram == nil {
-				return written, fmt.Errorf(
-					"expected histogram in metric %s %s", name, metric,
-				)
-			}
-			infSeen := false
-			for _, b := range metric.Histogram.Bucket {
-				n, err = writeSample(
-					w, name, "_bucket", metric,
-					model.BucketLabel, b.GetUpperBound(),
-					float64(b.GetCumulativeCount()),
-				)
-				written += n
-				if err != nil {
-					return
-				}
-				if math.IsInf(b.GetUpperBound(), +1) {
-					infSeen = true
-				}
-			}
-			if !infSeen {
-				n, err = writeSample(
-					w, name, "_bucket", metric,
-					model.BucketLabel, math.Inf(+1),
-					float64(metric.Histogram.GetSampleCount()),
-				)
-				written += n
-				if err != nil {
-					return
-				}
-			}
-			n, err = writeSample(
-				w, name, "_sum", metric, "", 0,
-				metric.Histogram.GetSampleSum(),
-			)
-			written += n
-			if err != nil {
-				return
-			}
-			n, err = writeSample(
-				w, name, "_count", metric, "", 0,
-				float64(metric.Histogram.GetSampleCount()),
-			)
-		default:
-			return written, fmt.Errorf(
-				"unexpected type in metric %s %s", name, metric,
-			)
-		}
-		written += n
-		if err != nil {
-			return
-		}
-	}
-	return
-}
-
-// writeSample writes a single sample in text format to w, given the metric
-// name, the metric proto message itself, optionally an additional label name
-// with a float64 value (use empty string as label name if not required), and
-// the value. The function returns the number of bytes written and any error
-// encountered.
-func writeSample(
-	w enhancedWriter,
-	name, suffix string,
-	metric *dto.Metric,
-	additionalLabelName string, additionalLabelValue float64,
-	value float64,
-) (int, error) {
-	var written int
-	n, err := w.WriteString(name)
-	written += n
-	if err != nil {
-		return written, err
-	}
-	if suffix != "" {
-		n, err = w.WriteString(suffix)
-		written += n
-		if err != nil {
-			return written, err
-		}
-	}
-	n, err = writeLabelPairs(
-		w, metric.Label, additionalLabelName, additionalLabelValue,
-	)
-	written += n
-	if err != nil {
-		return written, err
-	}
-	err = w.WriteByte(' ')
-	written++
-	if err != nil {
-		return written, err
-	}
-	n, err = writeFloat(w, value)
-	written += n
-	if err != nil {
-		return written, err
-	}
-	if metric.TimestampMs != nil {
-		err = w.WriteByte(' ')
-		written++
-		if err != nil {
-			return written, err
-		}
-		n, err = writeInt(w, *metric.TimestampMs)
-		written += n
-		if err != nil {
-			return written, err
-		}
-	}
-	err = w.WriteByte('\n')
-	written++
-	if err != nil {
-		return written, err
-	}
-	return written, nil
-}
-
-// writeLabelPairs converts a slice of LabelPair proto messages plus the
-// explicitly given additional label pair into text formatted as required by the
-// text format and writes it to 'w'. An empty slice in combination with an empty
-// string 'additionalLabelName' results in nothing being written. Otherwise, the
-// label pairs are written, escaped as required by the text format, and enclosed
-// in '{...}'. The function returns the number of bytes written and any error
-// encountered.
-func writeLabelPairs(
-	w enhancedWriter,
-	in []*dto.LabelPair,
-	additionalLabelName string, additionalLabelValue float64,
-) (int, error) {
-	if len(in) == 0 && additionalLabelName == "" {
-		return 0, nil
-	}
-	var (
-		written   int
-		separator byte = '{'
-	)
-	for _, lp := range in {
-		err := w.WriteByte(separator)
-		written++
-		if err != nil {
-			return written, err
-		}
-		n, err := w.WriteString(lp.GetName())
-		written += n
-		if err != nil {
-			return written, err
-		}
-		n, err = w.WriteString(`="`)
-		written += n
-		if err != nil {
-			return written, err
-		}
-		n, err = writeEscapedString(w, lp.GetValue(), true)
-		written += n
-		if err != nil {
-			return written, err
-		}
-		err = w.WriteByte('"')
-		written++
-		if err != nil {
-			return written, err
-		}
-		separator = ','
-	}
-	if additionalLabelName != "" {
-		err := w.WriteByte(separator)
-		written++
-		if err != nil {
-			return written, err
-		}
-		n, err := w.WriteString(additionalLabelName)
-		written += n
-		if err != nil {
-			return written, err
-		}
-		n, err = w.WriteString(`="`)
-		written += n
-		if err != nil {
-			return written, err
-		}
-		n, err = writeFloat(w, additionalLabelValue)
-		written += n
-		if err != nil {
-			return written, err
-		}
-		err = w.WriteByte('"')
-		written++
-		if err != nil {
-			return written, err
-		}
-	}
-	err := w.WriteByte('}')
-	written++
-	if err != nil {
-		return written, err
-	}
-	return written, nil
-}
-
-// writeEscapedString replaces '\' by '\\', new line character by '\n', and - if
-// includeDoubleQuote is true - '"' by '\"'.
-var (
-	escaper       = strings.NewReplacer("\\", `\\`, "\n", `\n`)
-	quotedEscaper = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`)
-)
-
-func writeEscapedString(w enhancedWriter, v string, includeDoubleQuote bool) (int, error) {
-	if includeDoubleQuote {
-		return quotedEscaper.WriteString(w, v)
-	} else {
-		return escaper.WriteString(w, v)
-	}
-}
-
-// writeFloat is equivalent to fmt.Fprint with a float64 argument but hardcodes
-// a few common cases for increased efficiency. For non-hardcoded cases, it uses
-// strconv.AppendFloat to avoid allocations, similar to writeInt.
-func writeFloat(w enhancedWriter, f float64) (int, error) {
-	switch {
-	case f == 1:
-		return w.WriteString("1.0")
-	case f == 0:
-		return w.WriteString("0.0")
-	case f == -1:
-		return w.WriteString("-1.0")
-	case math.IsNaN(f):
-		return w.WriteString("NaN")
-	case math.IsInf(f, +1):
-		return w.WriteString("+Inf")
-	case math.IsInf(f, -1):
-		return w.WriteString("-Inf")
-	default:
-		bp := numBufPool.Get().(*[]byte)
-		*bp = strconv.AppendFloat((*bp)[:0], f, 'g', -1, 64)
-		// Add a .0 if used fixed point and there is no decimal
-		// point already. This is for future proofing with OpenMetrics,
-		// where floats always contain either an exponent or decimal.
-		if !bytes.ContainsAny(*bp, "e.") {
-			*bp = append(*bp, '.', '0')
-		}
-		written, err := w.Write(*bp)
-		numBufPool.Put(bp)
-		return written, err
-	}
-}
-
-// writeInt is equivalent to fmt.Fprint with an int64 argument but uses
-// strconv.AppendInt with a byte slice taken from a sync.Pool to avoid
-// allocations.
-func writeInt(w enhancedWriter, i int64) (int, error) {
-	bp := numBufPool.Get().(*[]byte)
-	*bp = strconv.AppendInt((*bp)[:0], i, 10)
-	written, err := w.Write(*bp)
-	numBufPool.Put(bp)
-	return written, err
-}
diff --git a/vendor/github.com/prometheus/common/expfmt/text_parse.go b/vendor/github.com/prometheus/common/expfmt/text_parse.go
deleted file mode 100644
index ec3d86b..0000000
--- a/vendor/github.com/prometheus/common/expfmt/text_parse.go
+++ /dev/null
@@ -1,757 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package expfmt
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"math"
-	"strconv"
-	"strings"
-
-	dto "github.com/prometheus/client_model/go"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/prometheus/common/model"
-)
-
-// A stateFn is a function that represents a state in a state machine. By
-// executing it, the state is progressed to the next state. The stateFn returns
-// another stateFn, which represents the new state. The end state is represented
-// by nil.
-type stateFn func() stateFn
-
-// ParseError signals errors while parsing the simple and flat text-based
-// exchange format.
-type ParseError struct {
-	Line int
-	Msg  string
-}
-
-// Error implements the error interface.
-func (e ParseError) Error() string {
-	return fmt.Sprintf("text format parsing error in line %d: %s", e.Line, e.Msg)
-}
-
-// TextParser is used to parse the simple and flat text-based exchange format. Its
-// zero value is ready to use.
-type TextParser struct {
-	metricFamiliesByName map[string]*dto.MetricFamily
-	buf                  *bufio.Reader // Where the parsed input is read through.
-	err                  error         // Most recent error.
-	lineCount            int           // Tracks the line count for error messages.
-	currentByte          byte          // The most recent byte read.
-	currentToken         bytes.Buffer  // Re-used each time a token has to be gathered from multiple bytes.
-	currentMF            *dto.MetricFamily
-	currentMetric        *dto.Metric
-	currentLabelPair     *dto.LabelPair
-
-	// The remaining member variables are only used for summaries/histograms.
-	currentLabels map[string]string // All labels including '__name__' but excluding 'quantile'/'le'
-	// Summary specific.
-	summaries       map[uint64]*dto.Metric // Key is created with LabelsToSignature.
-	currentQuantile float64
-	// Histogram specific.
-	histograms    map[uint64]*dto.Metric // Key is created with LabelsToSignature.
-	currentBucket float64
-	// These tell us if the currently processed line ends on '_count' or
-	// '_sum' respectively and belong to a summary/histogram, representing the sample
-	// count and sum of that summary/histogram.
-	currentIsSummaryCount, currentIsSummarySum     bool
-	currentIsHistogramCount, currentIsHistogramSum bool
-}
-
-// TextToMetricFamilies reads 'in' as the simple and flat text-based exchange
-// format and creates MetricFamily proto messages. It returns the MetricFamily
-// proto messages in a map where the metric names are the keys, along with any
-// error encountered.
-//
-// If the input contains duplicate metrics (i.e. lines with the same metric name
-// and exactly the same label set), the resulting MetricFamily will contain
-// duplicate Metric proto messages. Similar is true for duplicate label
-// names. Checks for duplicates have to be performed separately, if required.
-// Also note that neither the metrics within each MetricFamily are sorted nor
-// the label pairs within each Metric. Sorting is not required for the most
-// frequent use of this method, which is sample ingestion in the Prometheus
-// server. However, for presentation purposes, you might want to sort the
-// metrics, and in some cases, you must sort the labels, e.g. for consumption by
-// the metric family injection hook of the Prometheus registry.
-//
-// Summaries and histograms are rather special beasts. You would probably not
-// use them in the simple text format anyway. This method can deal with
-// summaries and histograms if they are presented in exactly the way the
-// text.Create function creates them.
-//
-// This method must not be called concurrently. If you want to parse different
-// input concurrently, instantiate a separate Parser for each goroutine.
-func (p *TextParser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricFamily, error) {
-	p.reset(in)
-	for nextState := p.startOfLine; nextState != nil; nextState = nextState() {
-		// Magic happens here...
-	}
-	// Get rid of empty metric families.
-	for k, mf := range p.metricFamiliesByName {
-		if len(mf.GetMetric()) == 0 {
-			delete(p.metricFamiliesByName, k)
-		}
-	}
-	// If p.err is io.EOF now, we have run into a premature end of the input
-	// stream. Turn this error into something nicer and more
-	// meaningful. (io.EOF is often used as a signal for the legitimate end
-	// of an input stream.)
-	if p.err == io.EOF {
-		p.parseError("unexpected end of input stream")
-	}
-	return p.metricFamiliesByName, p.err
-}
-
-func (p *TextParser) reset(in io.Reader) {
-	p.metricFamiliesByName = map[string]*dto.MetricFamily{}
-	if p.buf == nil {
-		p.buf = bufio.NewReader(in)
-	} else {
-		p.buf.Reset(in)
-	}
-	p.err = nil
-	p.lineCount = 0
-	if p.summaries == nil || len(p.summaries) > 0 {
-		p.summaries = map[uint64]*dto.Metric{}
-	}
-	if p.histograms == nil || len(p.histograms) > 0 {
-		p.histograms = map[uint64]*dto.Metric{}
-	}
-	p.currentQuantile = math.NaN()
-	p.currentBucket = math.NaN()
-}
-
-// startOfLine represents the state where the next byte read from p.buf is the
-// start of a line (or whitespace leading up to it).
-func (p *TextParser) startOfLine() stateFn {
-	p.lineCount++
-	if p.skipBlankTab(); p.err != nil {
-		// End of input reached. This is the only case where
-		// that is not an error but a signal that we are done.
-		p.err = nil
-		return nil
-	}
-	switch p.currentByte {
-	case '#':
-		return p.startComment
-	case '\n':
-		return p.startOfLine // Empty line, start the next one.
-	}
-	return p.readingMetricName
-}
-
-// startComment represents the state where the next byte read from p.buf is the
-// start of a comment (or whitespace leading up to it).
-func (p *TextParser) startComment() stateFn {
-	if p.skipBlankTab(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	if p.currentByte == '\n' {
-		return p.startOfLine
-	}
-	if p.readTokenUntilWhitespace(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	// If we have hit the end of line already, there is nothing left
-	// to do. This is not considered a syntax error.
-	if p.currentByte == '\n' {
-		return p.startOfLine
-	}
-	keyword := p.currentToken.String()
-	if keyword != "HELP" && keyword != "TYPE" {
-		// Generic comment, ignore by fast forwarding to end of line.
-		for p.currentByte != '\n' {
-			if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil {
-				return nil // Unexpected end of input.
-			}
-		}
-		return p.startOfLine
-	}
-	// There is something. Next has to be a metric name.
-	if p.skipBlankTab(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	if p.readTokenAsMetricName(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	if p.currentByte == '\n' {
-		// At the end of the line already.
-		// Again, this is not considered a syntax error.
-		return p.startOfLine
-	}
-	if !isBlankOrTab(p.currentByte) {
-		p.parseError("invalid metric name in comment")
-		return nil
-	}
-	p.setOrCreateCurrentMF()
-	if p.skipBlankTab(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	if p.currentByte == '\n' {
-		// At the end of the line already.
-		// Again, this is not considered a syntax error.
-		return p.startOfLine
-	}
-	switch keyword {
-	case "HELP":
-		return p.readingHelp
-	case "TYPE":
-		return p.readingType
-	}
-	panic(fmt.Sprintf("code error: unexpected keyword %q", keyword))
-}
-
-// readingMetricName represents the state where the last byte read (now in
-// p.currentByte) is the first byte of a metric name.
-func (p *TextParser) readingMetricName() stateFn {
-	if p.readTokenAsMetricName(); p.err != nil {
-		return nil
-	}
-	if p.currentToken.Len() == 0 {
-		p.parseError("invalid metric name")
-		return nil
-	}
-	p.setOrCreateCurrentMF()
-	// Now is the time to fix the type if it hasn't happened yet.
-	if p.currentMF.Type == nil {
-		p.currentMF.Type = dto.MetricType_UNTYPED.Enum()
-	}
-	p.currentMetric = &dto.Metric{}
-	// Do not append the newly created currentMetric to
-	// currentMF.Metric right now. First wait if this is a summary,
-	// and the metric exists already, which we can only know after
-	// having read all the labels.
-	if p.skipBlankTabIfCurrentBlankTab(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	return p.readingLabels
-}
-
-// readingLabels represents the state where the last byte read (now in
-// p.currentByte) is either the first byte of the label set (i.e. a '{'), or the
-// first byte of the value (otherwise).
-func (p *TextParser) readingLabels() stateFn {
-	// Summaries/histograms are special. We have to reset the
-	// currentLabels map, currentQuantile and currentBucket before starting to
-	// read labels.
-	if p.currentMF.GetType() == dto.MetricType_SUMMARY || p.currentMF.GetType() == dto.MetricType_HISTOGRAM {
-		p.currentLabels = map[string]string{}
-		p.currentLabels[string(model.MetricNameLabel)] = p.currentMF.GetName()
-		p.currentQuantile = math.NaN()
-		p.currentBucket = math.NaN()
-	}
-	if p.currentByte != '{' {
-		return p.readingValue
-	}
-	return p.startLabelName
-}
-
-// startLabelName represents the state where the next byte read from p.buf is
-// the start of a label name (or whitespace leading up to it).
-func (p *TextParser) startLabelName() stateFn {
-	if p.skipBlankTab(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	if p.currentByte == '}' {
-		if p.skipBlankTab(); p.err != nil {
-			return nil // Unexpected end of input.
-		}
-		return p.readingValue
-	}
-	if p.readTokenAsLabelName(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	if p.currentToken.Len() == 0 {
-		p.parseError(fmt.Sprintf("invalid label name for metric %q", p.currentMF.GetName()))
-		return nil
-	}
-	p.currentLabelPair = &dto.LabelPair{Name: proto.String(p.currentToken.String())}
-	if p.currentLabelPair.GetName() == string(model.MetricNameLabel) {
-		p.parseError(fmt.Sprintf("label name %q is reserved", model.MetricNameLabel))
-		return nil
-	}
-	// Special summary/histogram treatment. Don't add 'quantile' and 'le'
-	// labels to 'real' labels.
-	if !(p.currentMF.GetType() == dto.MetricType_SUMMARY && p.currentLabelPair.GetName() == model.QuantileLabel) &&
-		!(p.currentMF.GetType() == dto.MetricType_HISTOGRAM && p.currentLabelPair.GetName() == model.BucketLabel) {
-		p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPair)
-	}
-	if p.skipBlankTabIfCurrentBlankTab(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	if p.currentByte != '=' {
-		p.parseError(fmt.Sprintf("expected '=' after label name, found %q", p.currentByte))
-		return nil
-	}
-	return p.startLabelValue
-}
-
-// startLabelValue represents the state where the next byte read from p.buf is
-// the start of a (quoted) label value (or whitespace leading up to it).
-func (p *TextParser) startLabelValue() stateFn {
-	if p.skipBlankTab(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	if p.currentByte != '"' {
-		p.parseError(fmt.Sprintf("expected '\"' at start of label value, found %q", p.currentByte))
-		return nil
-	}
-	if p.readTokenAsLabelValue(); p.err != nil {
-		return nil
-	}
-	if !model.LabelValue(p.currentToken.String()).IsValid() {
-		p.parseError(fmt.Sprintf("invalid label value %q", p.currentToken.String()))
-		return nil
-	}
-	p.currentLabelPair.Value = proto.String(p.currentToken.String())
-	// Special treatment of summaries:
-	// - Quantile labels are special, will result in dto.Quantile later.
-	// - Other labels have to be added to currentLabels for signature calculation.
-	if p.currentMF.GetType() == dto.MetricType_SUMMARY {
-		if p.currentLabelPair.GetName() == model.QuantileLabel {
-			if p.currentQuantile, p.err = strconv.ParseFloat(p.currentLabelPair.GetValue(), 64); p.err != nil {
-				// Create a more helpful error message.
-				p.parseError(fmt.Sprintf("expected float as value for 'quantile' label, got %q", p.currentLabelPair.GetValue()))
-				return nil
-			}
-		} else {
-			p.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue()
-		}
-	}
-	// Similar special treatment of histograms.
-	if p.currentMF.GetType() == dto.MetricType_HISTOGRAM {
-		if p.currentLabelPair.GetName() == model.BucketLabel {
-			if p.currentBucket, p.err = strconv.ParseFloat(p.currentLabelPair.GetValue(), 64); p.err != nil {
-				// Create a more helpful error message.
-				p.parseError(fmt.Sprintf("expected float as value for 'le' label, got %q", p.currentLabelPair.GetValue()))
-				return nil
-			}
-		} else {
-			p.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue()
-		}
-	}
-	if p.skipBlankTab(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	switch p.currentByte {
-	case ',':
-		return p.startLabelName
-
-	case '}':
-		if p.skipBlankTab(); p.err != nil {
-			return nil // Unexpected end of input.
-		}
-		return p.readingValue
-	default:
-		p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.GetValue()))
-		return nil
-	}
-}
-
-// readingValue represents the state where the last byte read (now in
-// p.currentByte) is the first byte of the sample value (i.e. a float).
-func (p *TextParser) readingValue() stateFn {
-	// When we are here, we have read all the labels, so for the
-	// special case of a summary/histogram, we can finally find out
-	// if the metric already exists.
-	if p.currentMF.GetType() == dto.MetricType_SUMMARY {
-		signature := model.LabelsToSignature(p.currentLabels)
-		if summary := p.summaries[signature]; summary != nil {
-			p.currentMetric = summary
-		} else {
-			p.summaries[signature] = p.currentMetric
-			p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric)
-		}
-	} else if p.currentMF.GetType() == dto.MetricType_HISTOGRAM {
-		signature := model.LabelsToSignature(p.currentLabels)
-		if histogram := p.histograms[signature]; histogram != nil {
-			p.currentMetric = histogram
-		} else {
-			p.histograms[signature] = p.currentMetric
-			p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric)
-		}
-	} else {
-		p.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric)
-	}
-	if p.readTokenUntilWhitespace(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	value, err := strconv.ParseFloat(p.currentToken.String(), 64)
-	if err != nil {
-		// Create a more helpful error message.
-		p.parseError(fmt.Sprintf("expected float as value, got %q", p.currentToken.String()))
-		return nil
-	}
-	switch p.currentMF.GetType() {
-	case dto.MetricType_COUNTER:
-		p.currentMetric.Counter = &dto.Counter{Value: proto.Float64(value)}
-	case dto.MetricType_GAUGE:
-		p.currentMetric.Gauge = &dto.Gauge{Value: proto.Float64(value)}
-	case dto.MetricType_UNTYPED:
-		p.currentMetric.Untyped = &dto.Untyped{Value: proto.Float64(value)}
-	case dto.MetricType_SUMMARY:
-		// *sigh*
-		if p.currentMetric.Summary == nil {
-			p.currentMetric.Summary = &dto.Summary{}
-		}
-		switch {
-		case p.currentIsSummaryCount:
-			p.currentMetric.Summary.SampleCount = proto.Uint64(uint64(value))
-		case p.currentIsSummarySum:
-			p.currentMetric.Summary.SampleSum = proto.Float64(value)
-		case !math.IsNaN(p.currentQuantile):
-			p.currentMetric.Summary.Quantile = append(
-				p.currentMetric.Summary.Quantile,
-				&dto.Quantile{
-					Quantile: proto.Float64(p.currentQuantile),
-					Value:    proto.Float64(value),
-				},
-			)
-		}
-	case dto.MetricType_HISTOGRAM:
-		// *sigh*
-		if p.currentMetric.Histogram == nil {
-			p.currentMetric.Histogram = &dto.Histogram{}
-		}
-		switch {
-		case p.currentIsHistogramCount:
-			p.currentMetric.Histogram.SampleCount = proto.Uint64(uint64(value))
-		case p.currentIsHistogramSum:
-			p.currentMetric.Histogram.SampleSum = proto.Float64(value)
-		case !math.IsNaN(p.currentBucket):
-			p.currentMetric.Histogram.Bucket = append(
-				p.currentMetric.Histogram.Bucket,
-				&dto.Bucket{
-					UpperBound:      proto.Float64(p.currentBucket),
-					CumulativeCount: proto.Uint64(uint64(value)),
-				},
-			)
-		}
-	default:
-		p.err = fmt.Errorf("unexpected type for metric name %q", p.currentMF.GetName())
-	}
-	if p.currentByte == '\n' {
-		return p.startOfLine
-	}
-	return p.startTimestamp
-}
-
-// startTimestamp represents the state where the next byte read from p.buf is
-// the start of the timestamp (or whitespace leading up to it).
-func (p *TextParser) startTimestamp() stateFn {
-	if p.skipBlankTab(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	if p.readTokenUntilWhitespace(); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	timestamp, err := strconv.ParseInt(p.currentToken.String(), 10, 64)
-	if err != nil {
-		// Create a more helpful error message.
-		p.parseError(fmt.Sprintf("expected integer as timestamp, got %q", p.currentToken.String()))
-		return nil
-	}
-	p.currentMetric.TimestampMs = proto.Int64(timestamp)
-	if p.readTokenUntilNewline(false); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	if p.currentToken.Len() > 0 {
-		p.parseError(fmt.Sprintf("spurious string after timestamp: %q", p.currentToken.String()))
-		return nil
-	}
-	return p.startOfLine
-}
-
-// readingHelp represents the state where the last byte read (now in
-// p.currentByte) is the first byte of the docstring after 'HELP'.
-func (p *TextParser) readingHelp() stateFn {
-	if p.currentMF.Help != nil {
-		p.parseError(fmt.Sprintf("second HELP line for metric name %q", p.currentMF.GetName()))
-		return nil
-	}
-	// Rest of line is the docstring.
-	if p.readTokenUntilNewline(true); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	p.currentMF.Help = proto.String(p.currentToken.String())
-	return p.startOfLine
-}
-
-// readingType represents the state where the last byte read (now in
-// p.currentByte) is the first byte of the type hint after 'HELP'.
-func (p *TextParser) readingType() stateFn {
-	if p.currentMF.Type != nil {
-		p.parseError(fmt.Sprintf("second TYPE line for metric name %q, or TYPE reported after samples", p.currentMF.GetName()))
-		return nil
-	}
-	// Rest of line is the type.
-	if p.readTokenUntilNewline(false); p.err != nil {
-		return nil // Unexpected end of input.
-	}
-	metricType, ok := dto.MetricType_value[strings.ToUpper(p.currentToken.String())]
-	if !ok {
-		p.parseError(fmt.Sprintf("unknown metric type %q", p.currentToken.String()))
-		return nil
-	}
-	p.currentMF.Type = dto.MetricType(metricType).Enum()
-	return p.startOfLine
-}
-
-// parseError sets p.err to a ParseError at the current line with the given
-// message.
-func (p *TextParser) parseError(msg string) {
-	p.err = ParseError{
-		Line: p.lineCount,
-		Msg:  msg,
-	}
-}
-
-// skipBlankTab reads (and discards) bytes from p.buf until it encounters a byte
-// that is neither ' ' nor '\t'. That byte is left in p.currentByte.
-func (p *TextParser) skipBlankTab() {
-	for {
-		if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil || !isBlankOrTab(p.currentByte) {
-			return
-		}
-	}
-}
-
-// skipBlankTabIfCurrentBlankTab works exactly as skipBlankTab but doesn't do
-// anything if p.currentByte is neither ' ' nor '\t'.
-func (p *TextParser) skipBlankTabIfCurrentBlankTab() {
-	if isBlankOrTab(p.currentByte) {
-		p.skipBlankTab()
-	}
-}
-
-// readTokenUntilWhitespace copies bytes from p.buf into p.currentToken.  The
-// first byte considered is the byte already read (now in p.currentByte).  The
-// first whitespace byte encountered is still copied into p.currentByte, but not
-// into p.currentToken.
-func (p *TextParser) readTokenUntilWhitespace() {
-	p.currentToken.Reset()
-	for p.err == nil && !isBlankOrTab(p.currentByte) && p.currentByte != '\n' {
-		p.currentToken.WriteByte(p.currentByte)
-		p.currentByte, p.err = p.buf.ReadByte()
-	}
-}
-
-// readTokenUntilNewline copies bytes from p.buf into p.currentToken.  The first
-// byte considered is the byte already read (now in p.currentByte).  The first
-// newline byte encountered is still copied into p.currentByte, but not into
-// p.currentToken. If recognizeEscapeSequence is true, two escape sequences are
-// recognized: '\\' translates into '\', and '\n' into a line-feed character.
-// All other escape sequences are invalid and cause an error.
-func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) {
-	p.currentToken.Reset()
-	escaped := false
-	for p.err == nil {
-		if recognizeEscapeSequence && escaped {
-			switch p.currentByte {
-			case '\\':
-				p.currentToken.WriteByte(p.currentByte)
-			case 'n':
-				p.currentToken.WriteByte('\n')
-			default:
-				p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte))
-				return
-			}
-			escaped = false
-		} else {
-			switch p.currentByte {
-			case '\n':
-				return
-			case '\\':
-				escaped = true
-			default:
-				p.currentToken.WriteByte(p.currentByte)
-			}
-		}
-		p.currentByte, p.err = p.buf.ReadByte()
-	}
-}
-
-// readTokenAsMetricName copies a metric name from p.buf into p.currentToken.
-// The first byte considered is the byte already read (now in p.currentByte).
-// The first byte not part of a metric name is still copied into p.currentByte,
-// but not into p.currentToken.
-func (p *TextParser) readTokenAsMetricName() {
-	p.currentToken.Reset()
-	if !isValidMetricNameStart(p.currentByte) {
-		return
-	}
-	for {
-		p.currentToken.WriteByte(p.currentByte)
-		p.currentByte, p.err = p.buf.ReadByte()
-		if p.err != nil || !isValidMetricNameContinuation(p.currentByte) {
-			return
-		}
-	}
-}
-
-// readTokenAsLabelName copies a label name from p.buf into p.currentToken.
-// The first byte considered is the byte already read (now in p.currentByte).
-// The first byte not part of a label name is still copied into p.currentByte,
-// but not into p.currentToken.
-func (p *TextParser) readTokenAsLabelName() {
-	p.currentToken.Reset()
-	if !isValidLabelNameStart(p.currentByte) {
-		return
-	}
-	for {
-		p.currentToken.WriteByte(p.currentByte)
-		p.currentByte, p.err = p.buf.ReadByte()
-		if p.err != nil || !isValidLabelNameContinuation(p.currentByte) {
-			return
-		}
-	}
-}
-
-// readTokenAsLabelValue copies a label value from p.buf into p.currentToken.
-// In contrast to the other 'readTokenAs...' functions, which start with the
-// last read byte in p.currentByte, this method ignores p.currentByte and starts
-// with reading a new byte from p.buf. The first byte not part of a label value
-// is still copied into p.currentByte, but not into p.currentToken.
-func (p *TextParser) readTokenAsLabelValue() {
-	p.currentToken.Reset()
-	escaped := false
-	for {
-		if p.currentByte, p.err = p.buf.ReadByte(); p.err != nil {
-			return
-		}
-		if escaped {
-			switch p.currentByte {
-			case '"', '\\':
-				p.currentToken.WriteByte(p.currentByte)
-			case 'n':
-				p.currentToken.WriteByte('\n')
-			default:
-				p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte))
-				return
-			}
-			escaped = false
-			continue
-		}
-		switch p.currentByte {
-		case '"':
-			return
-		case '\n':
-			p.parseError(fmt.Sprintf("label value %q contains unescaped new-line", p.currentToken.String()))
-			return
-		case '\\':
-			escaped = true
-		default:
-			p.currentToken.WriteByte(p.currentByte)
-		}
-	}
-}
-
-func (p *TextParser) setOrCreateCurrentMF() {
-	p.currentIsSummaryCount = false
-	p.currentIsSummarySum = false
-	p.currentIsHistogramCount = false
-	p.currentIsHistogramSum = false
-	name := p.currentToken.String()
-	if p.currentMF = p.metricFamiliesByName[name]; p.currentMF != nil {
-		return
-	}
-	// Try out if this is a _sum or _count for a summary/histogram.
-	summaryName := summaryMetricName(name)
-	if p.currentMF = p.metricFamiliesByName[summaryName]; p.currentMF != nil {
-		if p.currentMF.GetType() == dto.MetricType_SUMMARY {
-			if isCount(name) {
-				p.currentIsSummaryCount = true
-			}
-			if isSum(name) {
-				p.currentIsSummarySum = true
-			}
-			return
-		}
-	}
-	histogramName := histogramMetricName(name)
-	if p.currentMF = p.metricFamiliesByName[histogramName]; p.currentMF != nil {
-		if p.currentMF.GetType() == dto.MetricType_HISTOGRAM {
-			if isCount(name) {
-				p.currentIsHistogramCount = true
-			}
-			if isSum(name) {
-				p.currentIsHistogramSum = true
-			}
-			return
-		}
-	}
-	p.currentMF = &dto.MetricFamily{Name: proto.String(name)}
-	p.metricFamiliesByName[name] = p.currentMF
-}
-
-func isValidLabelNameStart(b byte) bool {
-	return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_'
-}
-
-func isValidLabelNameContinuation(b byte) bool {
-	return isValidLabelNameStart(b) || (b >= '0' && b <= '9')
-}
-
-func isValidMetricNameStart(b byte) bool {
-	return isValidLabelNameStart(b) || b == ':'
-}
-
-func isValidMetricNameContinuation(b byte) bool {
-	return isValidLabelNameContinuation(b) || b == ':'
-}
-
-func isBlankOrTab(b byte) bool {
-	return b == ' ' || b == '\t'
-}
-
-func isCount(name string) bool {
-	return len(name) > 6 && name[len(name)-6:] == "_count"
-}
-
-func isSum(name string) bool {
-	return len(name) > 4 && name[len(name)-4:] == "_sum"
-}
-
-func isBucket(name string) bool {
-	return len(name) > 7 && name[len(name)-7:] == "_bucket"
-}
-
-func summaryMetricName(name string) string {
-	switch {
-	case isCount(name):
-		return name[:len(name)-6]
-	case isSum(name):
-		return name[:len(name)-4]
-	default:
-		return name
-	}
-}
-
-func histogramMetricName(name string) string {
-	switch {
-	case isCount(name):
-		return name[:len(name)-6]
-	case isSum(name):
-		return name[:len(name)-4]
-	case isBucket(name):
-		return name[:len(name)-7]
-	default:
-		return name
-	}
-}
diff --git a/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt b/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt
deleted file mode 100644
index 7723656..0000000
--- a/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-PACKAGE
-
-package goautoneg
-import "bitbucket.org/ww/goautoneg"
-
-HTTP Content-Type Autonegotiation.
-
-The functions in this package implement the behaviour specified in
-http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
-
-Copyright (c) 2011, Open Knowledge Foundation Ltd.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-    Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in
-    the documentation and/or other materials provided with the
-    distribution.
-
-    Neither the name of the Open Knowledge Foundation Ltd. nor the
-    names of its contributors may be used to endorse or promote
-    products derived from this software without specific prior written
-    permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-FUNCTIONS
-
-func Negotiate(header string, alternatives []string) (content_type string)
-Negotiate the most appropriate content_type given the accept header
-and a list of alternatives.
-
-func ParseAccept(header string) (accept []Accept)
-Parse an Accept Header string returning a sorted list
-of clauses
-
-
-TYPES
-
-type Accept struct {
-    Type, SubType string
-    Q             float32
-    Params        map[string]string
-}
-Structure to represent a clause in an HTTP Accept Header
-
-
-SUBDIRECTORIES
-
-	.hg
diff --git a/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go b/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go
deleted file mode 100644
index 26e9228..0000000
--- a/vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-Copyright (c) 2011, Open Knowledge Foundation Ltd.
-All rights reserved.
-
-HTTP Content-Type Autonegotiation.
-
-The functions in this package implement the behaviour specified in
-http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-    Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in
-    the documentation and/or other materials provided with the
-    distribution.
-
-    Neither the name of the Open Knowledge Foundation Ltd. nor the
-    names of its contributors may be used to endorse or promote
-    products derived from this software without specific prior written
-    permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-*/
-package goautoneg
-
-import (
-	"sort"
-	"strconv"
-	"strings"
-)
-
-// Structure to represent a clause in an HTTP Accept Header
-type Accept struct {
-	Type, SubType string
-	Q             float64
-	Params        map[string]string
-}
-
-// For internal use, so that we can use the sort interface
-type accept_slice []Accept
-
-func (accept accept_slice) Len() int {
-	slice := []Accept(accept)
-	return len(slice)
-}
-
-func (accept accept_slice) Less(i, j int) bool {
-	slice := []Accept(accept)
-	ai, aj := slice[i], slice[j]
-	if ai.Q > aj.Q {
-		return true
-	}
-	if ai.Type != "*" && aj.Type == "*" {
-		return true
-	}
-	if ai.SubType != "*" && aj.SubType == "*" {
-		return true
-	}
-	return false
-}
-
-func (accept accept_slice) Swap(i, j int) {
-	slice := []Accept(accept)
-	slice[i], slice[j] = slice[j], slice[i]
-}
-
-// Parse an Accept Header string returning a sorted list
-// of clauses
-func ParseAccept(header string) (accept []Accept) {
-	parts := strings.Split(header, ",")
-	accept = make([]Accept, 0, len(parts))
-	for _, part := range parts {
-		part := strings.Trim(part, " ")
-
-		a := Accept{}
-		a.Params = make(map[string]string)
-		a.Q = 1.0
-
-		mrp := strings.Split(part, ";")
-
-		media_range := mrp[0]
-		sp := strings.Split(media_range, "/")
-		a.Type = strings.Trim(sp[0], " ")
-
-		switch {
-		case len(sp) == 1 && a.Type == "*":
-			a.SubType = "*"
-		case len(sp) == 2:
-			a.SubType = strings.Trim(sp[1], " ")
-		default:
-			continue
-		}
-
-		if len(mrp) == 1 {
-			accept = append(accept, a)
-			continue
-		}
-
-		for _, param := range mrp[1:] {
-			sp := strings.SplitN(param, "=", 2)
-			if len(sp) != 2 {
-				continue
-			}
-			token := strings.Trim(sp[0], " ")
-			if token == "q" {
-				a.Q, _ = strconv.ParseFloat(sp[1], 32)
-			} else {
-				a.Params[token] = strings.Trim(sp[1], " ")
-			}
-		}
-
-		accept = append(accept, a)
-	}
-
-	slice := accept_slice(accept)
-	sort.Sort(slice)
-
-	return
-}
-
-// Negotiate the most appropriate content_type given the accept header
-// and a list of alternatives.
-func Negotiate(header string, alternatives []string) (content_type string) {
-	asp := make([][]string, 0, len(alternatives))
-	for _, ctype := range alternatives {
-		asp = append(asp, strings.SplitN(ctype, "/", 2))
-	}
-	for _, clause := range ParseAccept(header) {
-		for i, ctsp := range asp {
-			if clause.Type == ctsp[0] && clause.SubType == ctsp[1] {
-				content_type = alternatives[i]
-				return
-			}
-			if clause.Type == ctsp[0] && clause.SubType == "*" {
-				content_type = alternatives[i]
-				return
-			}
-			if clause.Type == "*" && clause.SubType == "*" {
-				content_type = alternatives[i]
-				return
-			}
-		}
-	}
-	return
-}
diff --git a/vendor/github.com/prometheus/common/model/alert.go b/vendor/github.com/prometheus/common/model/alert.go
deleted file mode 100644
index 35e739c..0000000
--- a/vendor/github.com/prometheus/common/model/alert.go
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2013 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"fmt"
-	"time"
-)
-
-type AlertStatus string
-
-const (
-	AlertFiring   AlertStatus = "firing"
-	AlertResolved AlertStatus = "resolved"
-)
-
-// Alert is a generic representation of an alert in the Prometheus eco-system.
-type Alert struct {
-	// Label value pairs for purpose of aggregation, matching, and disposition
-	// dispatching. This must minimally include an "alertname" label.
-	Labels LabelSet `json:"labels"`
-
-	// Extra key/value information which does not define alert identity.
-	Annotations LabelSet `json:"annotations"`
-
-	// The known time range for this alert. Both ends are optional.
-	StartsAt     time.Time `json:"startsAt,omitempty"`
-	EndsAt       time.Time `json:"endsAt,omitempty"`
-	GeneratorURL string    `json:"generatorURL"`
-}
-
-// Name returns the name of the alert. It is equivalent to the "alertname" label.
-func (a *Alert) Name() string {
-	return string(a.Labels[AlertNameLabel])
-}
-
-// Fingerprint returns a unique hash for the alert. It is equivalent to
-// the fingerprint of the alert's label set.
-func (a *Alert) Fingerprint() Fingerprint {
-	return a.Labels.Fingerprint()
-}
-
-func (a *Alert) String() string {
-	s := fmt.Sprintf("%s[%s]", a.Name(), a.Fingerprint().String()[:7])
-	if a.Resolved() {
-		return s + "[resolved]"
-	}
-	return s + "[active]"
-}
-
-// Resolved returns true iff the activity interval ended in the past.
-func (a *Alert) Resolved() bool {
-	return a.ResolvedAt(time.Now())
-}
-
-// ResolvedAt returns true off the activity interval ended before
-// the given timestamp.
-func (a *Alert) ResolvedAt(ts time.Time) bool {
-	if a.EndsAt.IsZero() {
-		return false
-	}
-	return !a.EndsAt.After(ts)
-}
-
-// Status returns the status of the alert.
-func (a *Alert) Status() AlertStatus {
-	if a.Resolved() {
-		return AlertResolved
-	}
-	return AlertFiring
-}
-
-// Validate checks whether the alert data is inconsistent.
-func (a *Alert) Validate() error {
-	if a.StartsAt.IsZero() {
-		return fmt.Errorf("start time missing")
-	}
-	if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) {
-		return fmt.Errorf("start time must be before end time")
-	}
-	if err := a.Labels.Validate(); err != nil {
-		return fmt.Errorf("invalid label set: %s", err)
-	}
-	if len(a.Labels) == 0 {
-		return fmt.Errorf("at least one label pair required")
-	}
-	if err := a.Annotations.Validate(); err != nil {
-		return fmt.Errorf("invalid annotations: %s", err)
-	}
-	return nil
-}
-
-// Alert is a list of alerts that can be sorted in chronological order.
-type Alerts []*Alert
-
-func (as Alerts) Len() int      { return len(as) }
-func (as Alerts) Swap(i, j int) { as[i], as[j] = as[j], as[i] }
-
-func (as Alerts) Less(i, j int) bool {
-	if as[i].StartsAt.Before(as[j].StartsAt) {
-		return true
-	}
-	if as[i].EndsAt.Before(as[j].EndsAt) {
-		return true
-	}
-	return as[i].Fingerprint() < as[j].Fingerprint()
-}
-
-// HasFiring returns true iff one of the alerts is not resolved.
-func (as Alerts) HasFiring() bool {
-	for _, a := range as {
-		if !a.Resolved() {
-			return true
-		}
-	}
-	return false
-}
-
-// Status returns StatusFiring iff at least one of the alerts is firing.
-func (as Alerts) Status() AlertStatus {
-	if as.HasFiring() {
-		return AlertFiring
-	}
-	return AlertResolved
-}
diff --git a/vendor/github.com/prometheus/common/model/fingerprinting.go b/vendor/github.com/prometheus/common/model/fingerprinting.go
deleted file mode 100644
index fc4de41..0000000
--- a/vendor/github.com/prometheus/common/model/fingerprinting.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2013 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"fmt"
-	"strconv"
-)
-
-// Fingerprint provides a hash-capable representation of a Metric.
-// For our purposes, FNV-1A 64-bit is used.
-type Fingerprint uint64
-
-// FingerprintFromString transforms a string representation into a Fingerprint.
-func FingerprintFromString(s string) (Fingerprint, error) {
-	num, err := strconv.ParseUint(s, 16, 64)
-	return Fingerprint(num), err
-}
-
-// ParseFingerprint parses the input string into a fingerprint.
-func ParseFingerprint(s string) (Fingerprint, error) {
-	num, err := strconv.ParseUint(s, 16, 64)
-	if err != nil {
-		return 0, err
-	}
-	return Fingerprint(num), nil
-}
-
-func (f Fingerprint) String() string {
-	return fmt.Sprintf("%016x", uint64(f))
-}
-
-// Fingerprints represents a collection of Fingerprint subject to a given
-// natural sorting scheme. It implements sort.Interface.
-type Fingerprints []Fingerprint
-
-// Len implements sort.Interface.
-func (f Fingerprints) Len() int {
-	return len(f)
-}
-
-// Less implements sort.Interface.
-func (f Fingerprints) Less(i, j int) bool {
-	return f[i] < f[j]
-}
-
-// Swap implements sort.Interface.
-func (f Fingerprints) Swap(i, j int) {
-	f[i], f[j] = f[j], f[i]
-}
-
-// FingerprintSet is a set of Fingerprints.
-type FingerprintSet map[Fingerprint]struct{}
-
-// Equal returns true if both sets contain the same elements (and not more).
-func (s FingerprintSet) Equal(o FingerprintSet) bool {
-	if len(s) != len(o) {
-		return false
-	}
-
-	for k := range s {
-		if _, ok := o[k]; !ok {
-			return false
-		}
-	}
-
-	return true
-}
-
-// Intersection returns the elements contained in both sets.
-func (s FingerprintSet) Intersection(o FingerprintSet) FingerprintSet {
-	myLength, otherLength := len(s), len(o)
-	if myLength == 0 || otherLength == 0 {
-		return FingerprintSet{}
-	}
-
-	subSet := s
-	superSet := o
-
-	if otherLength < myLength {
-		subSet = o
-		superSet = s
-	}
-
-	out := FingerprintSet{}
-
-	for k := range subSet {
-		if _, ok := superSet[k]; ok {
-			out[k] = struct{}{}
-		}
-	}
-
-	return out
-}
diff --git a/vendor/github.com/prometheus/common/model/fnv.go b/vendor/github.com/prometheus/common/model/fnv.go
deleted file mode 100644
index 038fc1c..0000000
--- a/vendor/github.com/prometheus/common/model/fnv.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-// Inline and byte-free variant of hash/fnv's fnv64a.
-
-const (
-	offset64 = 14695981039346656037
-	prime64  = 1099511628211
-)
-
-// hashNew initializies a new fnv64a hash value.
-func hashNew() uint64 {
-	return offset64
-}
-
-// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
-func hashAdd(h uint64, s string) uint64 {
-	for i := 0; i < len(s); i++ {
-		h ^= uint64(s[i])
-		h *= prime64
-	}
-	return h
-}
-
-// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.
-func hashAddByte(h uint64, b byte) uint64 {
-	h ^= uint64(b)
-	h *= prime64
-	return h
-}
diff --git a/vendor/github.com/prometheus/common/model/labels.go b/vendor/github.com/prometheus/common/model/labels.go
deleted file mode 100644
index 41051a0..0000000
--- a/vendor/github.com/prometheus/common/model/labels.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2013 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"encoding/json"
-	"fmt"
-	"regexp"
-	"strings"
-	"unicode/utf8"
-)
-
-const (
-	// AlertNameLabel is the name of the label containing the an alert's name.
-	AlertNameLabel = "alertname"
-
-	// ExportedLabelPrefix is the prefix to prepend to the label names present in
-	// exported metrics if a label of the same name is added by the server.
-	ExportedLabelPrefix = "exported_"
-
-	// MetricNameLabel is the label name indicating the metric name of a
-	// timeseries.
-	MetricNameLabel = "__name__"
-
-	// SchemeLabel is the name of the label that holds the scheme on which to
-	// scrape a target.
-	SchemeLabel = "__scheme__"
-
-	// AddressLabel is the name of the label that holds the address of
-	// a scrape target.
-	AddressLabel = "__address__"
-
-	// MetricsPathLabel is the name of the label that holds the path on which to
-	// scrape a target.
-	MetricsPathLabel = "__metrics_path__"
-
-	// ReservedLabelPrefix is a prefix which is not legal in user-supplied
-	// label names.
-	ReservedLabelPrefix = "__"
-
-	// MetaLabelPrefix is a prefix for labels that provide meta information.
-	// Labels with this prefix are used for intermediate label processing and
-	// will not be attached to time series.
-	MetaLabelPrefix = "__meta_"
-
-	// TmpLabelPrefix is a prefix for temporary labels as part of relabelling.
-	// Labels with this prefix are used for intermediate label processing and
-	// will not be attached to time series. This is reserved for use in
-	// Prometheus configuration files by users.
-	TmpLabelPrefix = "__tmp_"
-
-	// ParamLabelPrefix is a prefix for labels that provide URL parameters
-	// used to scrape a target.
-	ParamLabelPrefix = "__param_"
-
-	// JobLabel is the label name indicating the job from which a timeseries
-	// was scraped.
-	JobLabel = "job"
-
-	// InstanceLabel is the label name used for the instance label.
-	InstanceLabel = "instance"
-
-	// BucketLabel is used for the label that defines the upper bound of a
-	// bucket of a histogram ("le" -> "less or equal").
-	BucketLabel = "le"
-
-	// QuantileLabel is used for the label that defines the quantile in a
-	// summary.
-	QuantileLabel = "quantile"
-)
-
-// LabelNameRE is a regular expression matching valid label names. Note that the
-// IsValid method of LabelName performs the same check but faster than a match
-// with this regular expression.
-var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
-
-// A LabelName is a key for a LabelSet or Metric.  It has a value associated
-// therewith.
-type LabelName string
-
-// IsValid is true iff the label name matches the pattern of LabelNameRE. This
-// method, however, does not use LabelNameRE for the check but a much faster
-// hardcoded implementation.
-func (ln LabelName) IsValid() bool {
-	if len(ln) == 0 {
-		return false
-	}
-	for i, b := range ln {
-		if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) {
-			return false
-		}
-	}
-	return true
-}
-
-// UnmarshalYAML implements the yaml.Unmarshaler interface.
-func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error {
-	var s string
-	if err := unmarshal(&s); err != nil {
-		return err
-	}
-	if !LabelName(s).IsValid() {
-		return fmt.Errorf("%q is not a valid label name", s)
-	}
-	*ln = LabelName(s)
-	return nil
-}
-
-// UnmarshalJSON implements the json.Unmarshaler interface.
-func (ln *LabelName) UnmarshalJSON(b []byte) error {
-	var s string
-	if err := json.Unmarshal(b, &s); err != nil {
-		return err
-	}
-	if !LabelName(s).IsValid() {
-		return fmt.Errorf("%q is not a valid label name", s)
-	}
-	*ln = LabelName(s)
-	return nil
-}
-
-// LabelNames is a sortable LabelName slice. In implements sort.Interface.
-type LabelNames []LabelName
-
-func (l LabelNames) Len() int {
-	return len(l)
-}
-
-func (l LabelNames) Less(i, j int) bool {
-	return l[i] < l[j]
-}
-
-func (l LabelNames) Swap(i, j int) {
-	l[i], l[j] = l[j], l[i]
-}
-
-func (l LabelNames) String() string {
-	labelStrings := make([]string, 0, len(l))
-	for _, label := range l {
-		labelStrings = append(labelStrings, string(label))
-	}
-	return strings.Join(labelStrings, ", ")
-}
-
-// A LabelValue is an associated value for a LabelName.
-type LabelValue string
-
-// IsValid returns true iff the string is a valid UTF8.
-func (lv LabelValue) IsValid() bool {
-	return utf8.ValidString(string(lv))
-}
-
-// LabelValues is a sortable LabelValue slice. It implements sort.Interface.
-type LabelValues []LabelValue
-
-func (l LabelValues) Len() int {
-	return len(l)
-}
-
-func (l LabelValues) Less(i, j int) bool {
-	return string(l[i]) < string(l[j])
-}
-
-func (l LabelValues) Swap(i, j int) {
-	l[i], l[j] = l[j], l[i]
-}
-
-// LabelPair pairs a name with a value.
-type LabelPair struct {
-	Name  LabelName
-	Value LabelValue
-}
-
-// LabelPairs is a sortable slice of LabelPair pointers. It implements
-// sort.Interface.
-type LabelPairs []*LabelPair
-
-func (l LabelPairs) Len() int {
-	return len(l)
-}
-
-func (l LabelPairs) Less(i, j int) bool {
-	switch {
-	case l[i].Name > l[j].Name:
-		return false
-	case l[i].Name < l[j].Name:
-		return true
-	case l[i].Value > l[j].Value:
-		return false
-	case l[i].Value < l[j].Value:
-		return true
-	default:
-		return false
-	}
-}
-
-func (l LabelPairs) Swap(i, j int) {
-	l[i], l[j] = l[j], l[i]
-}
diff --git a/vendor/github.com/prometheus/common/model/labelset.go b/vendor/github.com/prometheus/common/model/labelset.go
deleted file mode 100644
index 6eda08a..0000000
--- a/vendor/github.com/prometheus/common/model/labelset.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2013 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"encoding/json"
-	"fmt"
-	"sort"
-	"strings"
-)
-
-// A LabelSet is a collection of LabelName and LabelValue pairs.  The LabelSet
-// may be fully-qualified down to the point where it may resolve to a single
-// Metric in the data store or not.  All operations that occur within the realm
-// of a LabelSet can emit a vector of Metric entities to which the LabelSet may
-// match.
-type LabelSet map[LabelName]LabelValue
-
-// Validate checks whether all names and values in the label set
-// are valid.
-func (ls LabelSet) Validate() error {
-	for ln, lv := range ls {
-		if !ln.IsValid() {
-			return fmt.Errorf("invalid name %q", ln)
-		}
-		if !lv.IsValid() {
-			return fmt.Errorf("invalid value %q", lv)
-		}
-	}
-	return nil
-}
-
-// Equal returns true iff both label sets have exactly the same key/value pairs.
-func (ls LabelSet) Equal(o LabelSet) bool {
-	if len(ls) != len(o) {
-		return false
-	}
-	for ln, lv := range ls {
-		olv, ok := o[ln]
-		if !ok {
-			return false
-		}
-		if olv != lv {
-			return false
-		}
-	}
-	return true
-}
-
-// Before compares the metrics, using the following criteria:
-//
-// If m has fewer labels than o, it is before o. If it has more, it is not.
-//
-// If the number of labels is the same, the superset of all label names is
-// sorted alphanumerically. The first differing label pair found in that order
-// determines the outcome: If the label does not exist at all in m, then m is
-// before o, and vice versa. Otherwise the label value is compared
-// alphanumerically.
-//
-// If m and o are equal, the method returns false.
-func (ls LabelSet) Before(o LabelSet) bool {
-	if len(ls) < len(o) {
-		return true
-	}
-	if len(ls) > len(o) {
-		return false
-	}
-
-	lns := make(LabelNames, 0, len(ls)+len(o))
-	for ln := range ls {
-		lns = append(lns, ln)
-	}
-	for ln := range o {
-		lns = append(lns, ln)
-	}
-	// It's probably not worth it to de-dup lns.
-	sort.Sort(lns)
-	for _, ln := range lns {
-		mlv, ok := ls[ln]
-		if !ok {
-			return true
-		}
-		olv, ok := o[ln]
-		if !ok {
-			return false
-		}
-		if mlv < olv {
-			return true
-		}
-		if mlv > olv {
-			return false
-		}
-	}
-	return false
-}
-
-// Clone returns a copy of the label set.
-func (ls LabelSet) Clone() LabelSet {
-	lsn := make(LabelSet, len(ls))
-	for ln, lv := range ls {
-		lsn[ln] = lv
-	}
-	return lsn
-}
-
-// Merge is a helper function to non-destructively merge two label sets.
-func (l LabelSet) Merge(other LabelSet) LabelSet {
-	result := make(LabelSet, len(l))
-
-	for k, v := range l {
-		result[k] = v
-	}
-
-	for k, v := range other {
-		result[k] = v
-	}
-
-	return result
-}
-
-func (l LabelSet) String() string {
-	lstrs := make([]string, 0, len(l))
-	for l, v := range l {
-		lstrs = append(lstrs, fmt.Sprintf("%s=%q", l, v))
-	}
-
-	sort.Strings(lstrs)
-	return fmt.Sprintf("{%s}", strings.Join(lstrs, ", "))
-}
-
-// Fingerprint returns the LabelSet's fingerprint.
-func (ls LabelSet) Fingerprint() Fingerprint {
-	return labelSetToFingerprint(ls)
-}
-
-// FastFingerprint returns the LabelSet's Fingerprint calculated by a faster hashing
-// algorithm, which is, however, more susceptible to hash collisions.
-func (ls LabelSet) FastFingerprint() Fingerprint {
-	return labelSetToFastFingerprint(ls)
-}
-
-// UnmarshalJSON implements the json.Unmarshaler interface.
-func (l *LabelSet) UnmarshalJSON(b []byte) error {
-	var m map[LabelName]LabelValue
-	if err := json.Unmarshal(b, &m); err != nil {
-		return err
-	}
-	// encoding/json only unmarshals maps of the form map[string]T. It treats
-	// LabelName as a string and does not call its UnmarshalJSON method.
-	// Thus, we have to replicate the behavior here.
-	for ln := range m {
-		if !ln.IsValid() {
-			return fmt.Errorf("%q is not a valid label name", ln)
-		}
-	}
-	*l = LabelSet(m)
-	return nil
-}
diff --git a/vendor/github.com/prometheus/common/model/metric.go b/vendor/github.com/prometheus/common/model/metric.go
deleted file mode 100644
index 00804b7..0000000
--- a/vendor/github.com/prometheus/common/model/metric.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2013 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"fmt"
-	"regexp"
-	"sort"
-	"strings"
-)
-
-var (
-	// MetricNameRE is a regular expression matching valid metric
-	// names. Note that the IsValidMetricName function performs the same
-	// check but faster than a match with this regular expression.
-	MetricNameRE = regexp.MustCompile(`^[a-zA-Z_:][a-zA-Z0-9_:]*$`)
-)
-
-// A Metric is similar to a LabelSet, but the key difference is that a Metric is
-// a singleton and refers to one and only one stream of samples.
-type Metric LabelSet
-
-// Equal compares the metrics.
-func (m Metric) Equal(o Metric) bool {
-	return LabelSet(m).Equal(LabelSet(o))
-}
-
-// Before compares the metrics' underlying label sets.
-func (m Metric) Before(o Metric) bool {
-	return LabelSet(m).Before(LabelSet(o))
-}
-
-// Clone returns a copy of the Metric.
-func (m Metric) Clone() Metric {
-	clone := make(Metric, len(m))
-	for k, v := range m {
-		clone[k] = v
-	}
-	return clone
-}
-
-func (m Metric) String() string {
-	metricName, hasName := m[MetricNameLabel]
-	numLabels := len(m) - 1
-	if !hasName {
-		numLabels = len(m)
-	}
-	labelStrings := make([]string, 0, numLabels)
-	for label, value := range m {
-		if label != MetricNameLabel {
-			labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value))
-		}
-	}
-
-	switch numLabels {
-	case 0:
-		if hasName {
-			return string(metricName)
-		}
-		return "{}"
-	default:
-		sort.Strings(labelStrings)
-		return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ", "))
-	}
-}
-
-// Fingerprint returns a Metric's Fingerprint.
-func (m Metric) Fingerprint() Fingerprint {
-	return LabelSet(m).Fingerprint()
-}
-
-// FastFingerprint returns a Metric's Fingerprint calculated by a faster hashing
-// algorithm, which is, however, more susceptible to hash collisions.
-func (m Metric) FastFingerprint() Fingerprint {
-	return LabelSet(m).FastFingerprint()
-}
-
-// IsValidMetricName returns true iff name matches the pattern of MetricNameRE.
-// This function, however, does not use MetricNameRE for the check but a much
-// faster hardcoded implementation.
-func IsValidMetricName(n LabelValue) bool {
-	if len(n) == 0 {
-		return false
-	}
-	for i, b := range n {
-		if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0)) {
-			return false
-		}
-	}
-	return true
-}
diff --git a/vendor/github.com/prometheus/common/model/model.go b/vendor/github.com/prometheus/common/model/model.go
deleted file mode 100644
index a7b9691..0000000
--- a/vendor/github.com/prometheus/common/model/model.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2013 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package model contains common data structures that are shared across
-// Prometheus components and libraries.
-package model
diff --git a/vendor/github.com/prometheus/common/model/signature.go b/vendor/github.com/prometheus/common/model/signature.go
deleted file mode 100644
index 8762b13..0000000
--- a/vendor/github.com/prometheus/common/model/signature.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2014 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"sort"
-)
-
-// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is
-// used to separate label names, label values, and other strings from each other
-// when calculating their combined hash value (aka signature aka fingerprint).
-const SeparatorByte byte = 255
-
-var (
-	// cache the signature of an empty label set.
-	emptyLabelSignature = hashNew()
-)
-
-// LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a
-// given label set. (Collisions are possible but unlikely if the number of label
-// sets the function is applied to is small.)
-func LabelsToSignature(labels map[string]string) uint64 {
-	if len(labels) == 0 {
-		return emptyLabelSignature
-	}
-
-	labelNames := make([]string, 0, len(labels))
-	for labelName := range labels {
-		labelNames = append(labelNames, labelName)
-	}
-	sort.Strings(labelNames)
-
-	sum := hashNew()
-	for _, labelName := range labelNames {
-		sum = hashAdd(sum, labelName)
-		sum = hashAddByte(sum, SeparatorByte)
-		sum = hashAdd(sum, labels[labelName])
-		sum = hashAddByte(sum, SeparatorByte)
-	}
-	return sum
-}
-
-// labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as
-// parameter (rather than a label map) and returns a Fingerprint.
-func labelSetToFingerprint(ls LabelSet) Fingerprint {
-	if len(ls) == 0 {
-		return Fingerprint(emptyLabelSignature)
-	}
-
-	labelNames := make(LabelNames, 0, len(ls))
-	for labelName := range ls {
-		labelNames = append(labelNames, labelName)
-	}
-	sort.Sort(labelNames)
-
-	sum := hashNew()
-	for _, labelName := range labelNames {
-		sum = hashAdd(sum, string(labelName))
-		sum = hashAddByte(sum, SeparatorByte)
-		sum = hashAdd(sum, string(ls[labelName]))
-		sum = hashAddByte(sum, SeparatorByte)
-	}
-	return Fingerprint(sum)
-}
-
-// labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a
-// faster and less allocation-heavy hash function, which is more susceptible to
-// create hash collisions. Therefore, collision detection should be applied.
-func labelSetToFastFingerprint(ls LabelSet) Fingerprint {
-	if len(ls) == 0 {
-		return Fingerprint(emptyLabelSignature)
-	}
-
-	var result uint64
-	for labelName, labelValue := range ls {
-		sum := hashNew()
-		sum = hashAdd(sum, string(labelName))
-		sum = hashAddByte(sum, SeparatorByte)
-		sum = hashAdd(sum, string(labelValue))
-		result ^= sum
-	}
-	return Fingerprint(result)
-}
-
-// SignatureForLabels works like LabelsToSignature but takes a Metric as
-// parameter (rather than a label map) and only includes the labels with the
-// specified LabelNames into the signature calculation. The labels passed in
-// will be sorted by this function.
-func SignatureForLabels(m Metric, labels ...LabelName) uint64 {
-	if len(labels) == 0 {
-		return emptyLabelSignature
-	}
-
-	sort.Sort(LabelNames(labels))
-
-	sum := hashNew()
-	for _, label := range labels {
-		sum = hashAdd(sum, string(label))
-		sum = hashAddByte(sum, SeparatorByte)
-		sum = hashAdd(sum, string(m[label]))
-		sum = hashAddByte(sum, SeparatorByte)
-	}
-	return sum
-}
-
-// SignatureWithoutLabels works like LabelsToSignature but takes a Metric as
-// parameter (rather than a label map) and excludes the labels with any of the
-// specified LabelNames from the signature calculation.
-func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 {
-	if len(m) == 0 {
-		return emptyLabelSignature
-	}
-
-	labelNames := make(LabelNames, 0, len(m))
-	for labelName := range m {
-		if _, exclude := labels[labelName]; !exclude {
-			labelNames = append(labelNames, labelName)
-		}
-	}
-	if len(labelNames) == 0 {
-		return emptyLabelSignature
-	}
-	sort.Sort(labelNames)
-
-	sum := hashNew()
-	for _, labelName := range labelNames {
-		sum = hashAdd(sum, string(labelName))
-		sum = hashAddByte(sum, SeparatorByte)
-		sum = hashAdd(sum, string(m[labelName]))
-		sum = hashAddByte(sum, SeparatorByte)
-	}
-	return sum
-}
diff --git a/vendor/github.com/prometheus/common/model/silence.go b/vendor/github.com/prometheus/common/model/silence.go
deleted file mode 100644
index bb99889..0000000
--- a/vendor/github.com/prometheus/common/model/silence.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2015 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"encoding/json"
-	"fmt"
-	"regexp"
-	"time"
-)
-
-// Matcher describes a matches the value of a given label.
-type Matcher struct {
-	Name    LabelName `json:"name"`
-	Value   string    `json:"value"`
-	IsRegex bool      `json:"isRegex"`
-}
-
-func (m *Matcher) UnmarshalJSON(b []byte) error {
-	type plain Matcher
-	if err := json.Unmarshal(b, (*plain)(m)); err != nil {
-		return err
-	}
-
-	if len(m.Name) == 0 {
-		return fmt.Errorf("label name in matcher must not be empty")
-	}
-	if m.IsRegex {
-		if _, err := regexp.Compile(m.Value); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-// Validate returns true iff all fields of the matcher have valid values.
-func (m *Matcher) Validate() error {
-	if !m.Name.IsValid() {
-		return fmt.Errorf("invalid name %q", m.Name)
-	}
-	if m.IsRegex {
-		if _, err := regexp.Compile(m.Value); err != nil {
-			return fmt.Errorf("invalid regular expression %q", m.Value)
-		}
-	} else if !LabelValue(m.Value).IsValid() || len(m.Value) == 0 {
-		return fmt.Errorf("invalid value %q", m.Value)
-	}
-	return nil
-}
-
-// Silence defines the representation of a silence definition in the Prometheus
-// eco-system.
-type Silence struct {
-	ID uint64 `json:"id,omitempty"`
-
-	Matchers []*Matcher `json:"matchers"`
-
-	StartsAt time.Time `json:"startsAt"`
-	EndsAt   time.Time `json:"endsAt"`
-
-	CreatedAt time.Time `json:"createdAt,omitempty"`
-	CreatedBy string    `json:"createdBy"`
-	Comment   string    `json:"comment,omitempty"`
-}
-
-// Validate returns true iff all fields of the silence have valid values.
-func (s *Silence) Validate() error {
-	if len(s.Matchers) == 0 {
-		return fmt.Errorf("at least one matcher required")
-	}
-	for _, m := range s.Matchers {
-		if err := m.Validate(); err != nil {
-			return fmt.Errorf("invalid matcher: %s", err)
-		}
-	}
-	if s.StartsAt.IsZero() {
-		return fmt.Errorf("start time missing")
-	}
-	if s.EndsAt.IsZero() {
-		return fmt.Errorf("end time missing")
-	}
-	if s.EndsAt.Before(s.StartsAt) {
-		return fmt.Errorf("start time must be before end time")
-	}
-	if s.CreatedBy == "" {
-		return fmt.Errorf("creator information missing")
-	}
-	if s.Comment == "" {
-		return fmt.Errorf("comment missing")
-	}
-	if s.CreatedAt.IsZero() {
-		return fmt.Errorf("creation timestamp missing")
-	}
-	return nil
-}
diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go
deleted file mode 100644
index 46259b1..0000000
--- a/vendor/github.com/prometheus/common/model/time.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright 2013 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"fmt"
-	"math"
-	"regexp"
-	"strconv"
-	"strings"
-	"time"
-)
-
-const (
-	// MinimumTick is the minimum supported time resolution. This has to be
-	// at least time.Second in order for the code below to work.
-	minimumTick = time.Millisecond
-	// second is the Time duration equivalent to one second.
-	second = int64(time.Second / minimumTick)
-	// The number of nanoseconds per minimum tick.
-	nanosPerTick = int64(minimumTick / time.Nanosecond)
-
-	// Earliest is the earliest Time representable. Handy for
-	// initializing a high watermark.
-	Earliest = Time(math.MinInt64)
-	// Latest is the latest Time representable. Handy for initializing
-	// a low watermark.
-	Latest = Time(math.MaxInt64)
-)
-
-// Time is the number of milliseconds since the epoch
-// (1970-01-01 00:00 UTC) excluding leap seconds.
-type Time int64
-
-// Interval describes an interval between two timestamps.
-type Interval struct {
-	Start, End Time
-}
-
-// Now returns the current time as a Time.
-func Now() Time {
-	return TimeFromUnixNano(time.Now().UnixNano())
-}
-
-// TimeFromUnix returns the Time equivalent to the Unix Time t
-// provided in seconds.
-func TimeFromUnix(t int64) Time {
-	return Time(t * second)
-}
-
-// TimeFromUnixNano returns the Time equivalent to the Unix Time
-// t provided in nanoseconds.
-func TimeFromUnixNano(t int64) Time {
-	return Time(t / nanosPerTick)
-}
-
-// Equal reports whether two Times represent the same instant.
-func (t Time) Equal(o Time) bool {
-	return t == o
-}
-
-// Before reports whether the Time t is before o.
-func (t Time) Before(o Time) bool {
-	return t < o
-}
-
-// After reports whether the Time t is after o.
-func (t Time) After(o Time) bool {
-	return t > o
-}
-
-// Add returns the Time t + d.
-func (t Time) Add(d time.Duration) Time {
-	return t + Time(d/minimumTick)
-}
-
-// Sub returns the Duration t - o.
-func (t Time) Sub(o Time) time.Duration {
-	return time.Duration(t-o) * minimumTick
-}
-
-// Time returns the time.Time representation of t.
-func (t Time) Time() time.Time {
-	return time.Unix(int64(t)/second, (int64(t)%second)*nanosPerTick)
-}
-
-// Unix returns t as a Unix time, the number of seconds elapsed
-// since January 1, 1970 UTC.
-func (t Time) Unix() int64 {
-	return int64(t) / second
-}
-
-// UnixNano returns t as a Unix time, the number of nanoseconds elapsed
-// since January 1, 1970 UTC.
-func (t Time) UnixNano() int64 {
-	return int64(t) * nanosPerTick
-}
-
-// The number of digits after the dot.
-var dotPrecision = int(math.Log10(float64(second)))
-
-// String returns a string representation of the Time.
-func (t Time) String() string {
-	return strconv.FormatFloat(float64(t)/float64(second), 'f', -1, 64)
-}
-
-// MarshalJSON implements the json.Marshaler interface.
-func (t Time) MarshalJSON() ([]byte, error) {
-	return []byte(t.String()), nil
-}
-
-// UnmarshalJSON implements the json.Unmarshaler interface.
-func (t *Time) UnmarshalJSON(b []byte) error {
-	p := strings.Split(string(b), ".")
-	switch len(p) {
-	case 1:
-		v, err := strconv.ParseInt(string(p[0]), 10, 64)
-		if err != nil {
-			return err
-		}
-		*t = Time(v * second)
-
-	case 2:
-		v, err := strconv.ParseInt(string(p[0]), 10, 64)
-		if err != nil {
-			return err
-		}
-		v *= second
-
-		prec := dotPrecision - len(p[1])
-		if prec < 0 {
-			p[1] = p[1][:dotPrecision]
-		} else if prec > 0 {
-			p[1] = p[1] + strings.Repeat("0", prec)
-		}
-
-		va, err := strconv.ParseInt(p[1], 10, 32)
-		if err != nil {
-			return err
-		}
-
-		*t = Time(v + va)
-
-	default:
-		return fmt.Errorf("invalid time %q", string(b))
-	}
-	return nil
-}
-
-// Duration wraps time.Duration. It is used to parse the custom duration format
-// from YAML.
-// This type should not propagate beyond the scope of input/output processing.
-type Duration time.Duration
-
-// Set implements pflag/flag.Value
-func (d *Duration) Set(s string) error {
-	var err error
-	*d, err = ParseDuration(s)
-	return err
-}
-
-// Type implements pflag.Value
-func (d *Duration) Type() string {
-	return "duration"
-}
-
-var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$")
-
-// ParseDuration parses a string into a time.Duration, assuming that a year
-// always has 365d, a week always has 7d, and a day always has 24h.
-func ParseDuration(durationStr string) (Duration, error) {
-	matches := durationRE.FindStringSubmatch(durationStr)
-	if len(matches) != 3 {
-		return 0, fmt.Errorf("not a valid duration string: %q", durationStr)
-	}
-	var (
-		n, _ = strconv.Atoi(matches[1])
-		dur  = time.Duration(n) * time.Millisecond
-	)
-	switch unit := matches[2]; unit {
-	case "y":
-		dur *= 1000 * 60 * 60 * 24 * 365
-	case "w":
-		dur *= 1000 * 60 * 60 * 24 * 7
-	case "d":
-		dur *= 1000 * 60 * 60 * 24
-	case "h":
-		dur *= 1000 * 60 * 60
-	case "m":
-		dur *= 1000 * 60
-	case "s":
-		dur *= 1000
-	case "ms":
-		// Value already correct
-	default:
-		return 0, fmt.Errorf("invalid time unit in duration string: %q", unit)
-	}
-	return Duration(dur), nil
-}
-
-func (d Duration) String() string {
-	var (
-		ms   = int64(time.Duration(d) / time.Millisecond)
-		unit = "ms"
-	)
-	if ms == 0 {
-		return "0s"
-	}
-	factors := map[string]int64{
-		"y":  1000 * 60 * 60 * 24 * 365,
-		"w":  1000 * 60 * 60 * 24 * 7,
-		"d":  1000 * 60 * 60 * 24,
-		"h":  1000 * 60 * 60,
-		"m":  1000 * 60,
-		"s":  1000,
-		"ms": 1,
-	}
-
-	switch int64(0) {
-	case ms % factors["y"]:
-		unit = "y"
-	case ms % factors["w"]:
-		unit = "w"
-	case ms % factors["d"]:
-		unit = "d"
-	case ms % factors["h"]:
-		unit = "h"
-	case ms % factors["m"]:
-		unit = "m"
-	case ms % factors["s"]:
-		unit = "s"
-	}
-	return fmt.Sprintf("%v%v", ms/factors[unit], unit)
-}
-
-// MarshalYAML implements the yaml.Marshaler interface.
-func (d Duration) MarshalYAML() (interface{}, error) {
-	return d.String(), nil
-}
-
-// UnmarshalYAML implements the yaml.Unmarshaler interface.
-func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {
-	var s string
-	if err := unmarshal(&s); err != nil {
-		return err
-	}
-	dur, err := ParseDuration(s)
-	if err != nil {
-		return err
-	}
-	*d = dur
-	return nil
-}
diff --git a/vendor/github.com/prometheus/common/model/value.go b/vendor/github.com/prometheus/common/model/value.go
deleted file mode 100644
index c9d8fb1..0000000
--- a/vendor/github.com/prometheus/common/model/value.go
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright 2013 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"encoding/json"
-	"fmt"
-	"math"
-	"sort"
-	"strconv"
-	"strings"
-)
-
-var (
-	// ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a
-	// non-existing sample pair. It is a SamplePair with timestamp Earliest and
-	// value 0.0. Note that the natural zero value of SamplePair has a timestamp
-	// of 0, which is possible to appear in a real SamplePair and thus not
-	// suitable to signal a non-existing SamplePair.
-	ZeroSamplePair = SamplePair{Timestamp: Earliest}
-
-	// ZeroSample is the pseudo zero-value of Sample used to signal a
-	// non-existing sample. It is a Sample with timestamp Earliest, value 0.0,
-	// and metric nil. Note that the natural zero value of Sample has a timestamp
-	// of 0, which is possible to appear in a real Sample and thus not suitable
-	// to signal a non-existing Sample.
-	ZeroSample = Sample{Timestamp: Earliest}
-)
-
-// A SampleValue is a representation of a value for a given sample at a given
-// time.
-type SampleValue float64
-
-// MarshalJSON implements json.Marshaler.
-func (v SampleValue) MarshalJSON() ([]byte, error) {
-	return json.Marshal(v.String())
-}
-
-// UnmarshalJSON implements json.Unmarshaler.
-func (v *SampleValue) UnmarshalJSON(b []byte) error {
-	if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
-		return fmt.Errorf("sample value must be a quoted string")
-	}
-	f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64)
-	if err != nil {
-		return err
-	}
-	*v = SampleValue(f)
-	return nil
-}
-
-// Equal returns true if the value of v and o is equal or if both are NaN. Note
-// that v==o is false if both are NaN. If you want the conventional float
-// behavior, use == to compare two SampleValues.
-func (v SampleValue) Equal(o SampleValue) bool {
-	if v == o {
-		return true
-	}
-	return math.IsNaN(float64(v)) && math.IsNaN(float64(o))
-}
-
-func (v SampleValue) String() string {
-	return strconv.FormatFloat(float64(v), 'f', -1, 64)
-}
-
-// SamplePair pairs a SampleValue with a Timestamp.
-type SamplePair struct {
-	Timestamp Time
-	Value     SampleValue
-}
-
-// MarshalJSON implements json.Marshaler.
-func (s SamplePair) MarshalJSON() ([]byte, error) {
-	t, err := json.Marshal(s.Timestamp)
-	if err != nil {
-		return nil, err
-	}
-	v, err := json.Marshal(s.Value)
-	if err != nil {
-		return nil, err
-	}
-	return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil
-}
-
-// UnmarshalJSON implements json.Unmarshaler.
-func (s *SamplePair) UnmarshalJSON(b []byte) error {
-	v := [...]json.Unmarshaler{&s.Timestamp, &s.Value}
-	return json.Unmarshal(b, &v)
-}
-
-// Equal returns true if this SamplePair and o have equal Values and equal
-// Timestamps. The semantics of Value equality is defined by SampleValue.Equal.
-func (s *SamplePair) Equal(o *SamplePair) bool {
-	return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))
-}
-
-func (s SamplePair) String() string {
-	return fmt.Sprintf("%s @[%s]", s.Value, s.Timestamp)
-}
-
-// Sample is a sample pair associated with a metric.
-type Sample struct {
-	Metric    Metric      `json:"metric"`
-	Value     SampleValue `json:"value"`
-	Timestamp Time        `json:"timestamp"`
-}
-
-// Equal compares first the metrics, then the timestamp, then the value. The
-// semantics of value equality is defined by SampleValue.Equal.
-func (s *Sample) Equal(o *Sample) bool {
-	if s == o {
-		return true
-	}
-
-	if !s.Metric.Equal(o.Metric) {
-		return false
-	}
-	if !s.Timestamp.Equal(o.Timestamp) {
-		return false
-	}
-
-	return s.Value.Equal(o.Value)
-}
-
-func (s Sample) String() string {
-	return fmt.Sprintf("%s => %s", s.Metric, SamplePair{
-		Timestamp: s.Timestamp,
-		Value:     s.Value,
-	})
-}
-
-// MarshalJSON implements json.Marshaler.
-func (s Sample) MarshalJSON() ([]byte, error) {
-	v := struct {
-		Metric Metric     `json:"metric"`
-		Value  SamplePair `json:"value"`
-	}{
-		Metric: s.Metric,
-		Value: SamplePair{
-			Timestamp: s.Timestamp,
-			Value:     s.Value,
-		},
-	}
-
-	return json.Marshal(&v)
-}
-
-// UnmarshalJSON implements json.Unmarshaler.
-func (s *Sample) UnmarshalJSON(b []byte) error {
-	v := struct {
-		Metric Metric     `json:"metric"`
-		Value  SamplePair `json:"value"`
-	}{
-		Metric: s.Metric,
-		Value: SamplePair{
-			Timestamp: s.Timestamp,
-			Value:     s.Value,
-		},
-	}
-
-	if err := json.Unmarshal(b, &v); err != nil {
-		return err
-	}
-
-	s.Metric = v.Metric
-	s.Timestamp = v.Value.Timestamp
-	s.Value = v.Value.Value
-
-	return nil
-}
-
-// Samples is a sortable Sample slice. It implements sort.Interface.
-type Samples []*Sample
-
-func (s Samples) Len() int {
-	return len(s)
-}
-
-// Less compares first the metrics, then the timestamp.
-func (s Samples) Less(i, j int) bool {
-	switch {
-	case s[i].Metric.Before(s[j].Metric):
-		return true
-	case s[j].Metric.Before(s[i].Metric):
-		return false
-	case s[i].Timestamp.Before(s[j].Timestamp):
-		return true
-	default:
-		return false
-	}
-}
-
-func (s Samples) Swap(i, j int) {
-	s[i], s[j] = s[j], s[i]
-}
-
-// Equal compares two sets of samples and returns true if they are equal.
-func (s Samples) Equal(o Samples) bool {
-	if len(s) != len(o) {
-		return false
-	}
-
-	for i, sample := range s {
-		if !sample.Equal(o[i]) {
-			return false
-		}
-	}
-	return true
-}
-
-// SampleStream is a stream of Values belonging to an attached COWMetric.
-type SampleStream struct {
-	Metric Metric       `json:"metric"`
-	Values []SamplePair `json:"values"`
-}
-
-func (ss SampleStream) String() string {
-	vals := make([]string, len(ss.Values))
-	for i, v := range ss.Values {
-		vals[i] = v.String()
-	}
-	return fmt.Sprintf("%s =>\n%s", ss.Metric, strings.Join(vals, "\n"))
-}
-
-// Value is a generic interface for values resulting from a query evaluation.
-type Value interface {
-	Type() ValueType
-	String() string
-}
-
-func (Matrix) Type() ValueType  { return ValMatrix }
-func (Vector) Type() ValueType  { return ValVector }
-func (*Scalar) Type() ValueType { return ValScalar }
-func (*String) Type() ValueType { return ValString }
-
-type ValueType int
-
-const (
-	ValNone ValueType = iota
-	ValScalar
-	ValVector
-	ValMatrix
-	ValString
-)
-
-// MarshalJSON implements json.Marshaler.
-func (et ValueType) MarshalJSON() ([]byte, error) {
-	return json.Marshal(et.String())
-}
-
-func (et *ValueType) UnmarshalJSON(b []byte) error {
-	var s string
-	if err := json.Unmarshal(b, &s); err != nil {
-		return err
-	}
-	switch s {
-	case "<ValNone>":
-		*et = ValNone
-	case "scalar":
-		*et = ValScalar
-	case "vector":
-		*et = ValVector
-	case "matrix":
-		*et = ValMatrix
-	case "string":
-		*et = ValString
-	default:
-		return fmt.Errorf("unknown value type %q", s)
-	}
-	return nil
-}
-
-func (e ValueType) String() string {
-	switch e {
-	case ValNone:
-		return "<ValNone>"
-	case ValScalar:
-		return "scalar"
-	case ValVector:
-		return "vector"
-	case ValMatrix:
-		return "matrix"
-	case ValString:
-		return "string"
-	}
-	panic("ValueType.String: unhandled value type")
-}
-
-// Scalar is a scalar value evaluated at the set timestamp.
-type Scalar struct {
-	Value     SampleValue `json:"value"`
-	Timestamp Time        `json:"timestamp"`
-}
-
-func (s Scalar) String() string {
-	return fmt.Sprintf("scalar: %v @[%v]", s.Value, s.Timestamp)
-}
-
-// MarshalJSON implements json.Marshaler.
-func (s Scalar) MarshalJSON() ([]byte, error) {
-	v := strconv.FormatFloat(float64(s.Value), 'f', -1, 64)
-	return json.Marshal([...]interface{}{s.Timestamp, string(v)})
-}
-
-// UnmarshalJSON implements json.Unmarshaler.
-func (s *Scalar) UnmarshalJSON(b []byte) error {
-	var f string
-	v := [...]interface{}{&s.Timestamp, &f}
-
-	if err := json.Unmarshal(b, &v); err != nil {
-		return err
-	}
-
-	value, err := strconv.ParseFloat(f, 64)
-	if err != nil {
-		return fmt.Errorf("error parsing sample value: %s", err)
-	}
-	s.Value = SampleValue(value)
-	return nil
-}
-
-// String is a string value evaluated at the set timestamp.
-type String struct {
-	Value     string `json:"value"`
-	Timestamp Time   `json:"timestamp"`
-}
-
-func (s *String) String() string {
-	return s.Value
-}
-
-// MarshalJSON implements json.Marshaler.
-func (s String) MarshalJSON() ([]byte, error) {
-	return json.Marshal([]interface{}{s.Timestamp, s.Value})
-}
-
-// UnmarshalJSON implements json.Unmarshaler.
-func (s *String) UnmarshalJSON(b []byte) error {
-	v := [...]interface{}{&s.Timestamp, &s.Value}
-	return json.Unmarshal(b, &v)
-}
-
-// Vector is basically only an alias for Samples, but the
-// contract is that in a Vector, all Samples have the same timestamp.
-type Vector []*Sample
-
-func (vec Vector) String() string {
-	entries := make([]string, len(vec))
-	for i, s := range vec {
-		entries[i] = s.String()
-	}
-	return strings.Join(entries, "\n")
-}
-
-func (vec Vector) Len() int      { return len(vec) }
-func (vec Vector) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] }
-
-// Less compares first the metrics, then the timestamp.
-func (vec Vector) Less(i, j int) bool {
-	switch {
-	case vec[i].Metric.Before(vec[j].Metric):
-		return true
-	case vec[j].Metric.Before(vec[i].Metric):
-		return false
-	case vec[i].Timestamp.Before(vec[j].Timestamp):
-		return true
-	default:
-		return false
-	}
-}
-
-// Equal compares two sets of samples and returns true if they are equal.
-func (vec Vector) Equal(o Vector) bool {
-	if len(vec) != len(o) {
-		return false
-	}
-
-	for i, sample := range vec {
-		if !sample.Equal(o[i]) {
-			return false
-		}
-	}
-	return true
-}
-
-// Matrix is a list of time series.
-type Matrix []*SampleStream
-
-func (m Matrix) Len() int           { return len(m) }
-func (m Matrix) Less(i, j int) bool { return m[i].Metric.Before(m[j].Metric) }
-func (m Matrix) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }
-
-func (mat Matrix) String() string {
-	matCp := make(Matrix, len(mat))
-	copy(matCp, mat)
-	sort.Sort(matCp)
-
-	strs := make([]string, len(matCp))
-
-	for i, ss := range matCp {
-		strs[i] = ss.String()
-	}
-
-	return strings.Join(strs, "\n")
-}
diff --git a/vendor/github.com/prometheus/procfs/.gitignore b/vendor/github.com/prometheus/procfs/.gitignore
deleted file mode 100644
index 25e3659..0000000
--- a/vendor/github.com/prometheus/procfs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/fixtures/
diff --git a/vendor/github.com/prometheus/procfs/CONTRIBUTING.md b/vendor/github.com/prometheus/procfs/CONTRIBUTING.md
deleted file mode 100644
index 40503ed..0000000
--- a/vendor/github.com/prometheus/procfs/CONTRIBUTING.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Contributing
-
-Prometheus uses GitHub to manage reviews of pull requests.
-
-* If you have a trivial fix or improvement, go ahead and create a pull request,
-  addressing (with `@...`) the maintainer of this repository (see
-  [MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request.
-
-* If you plan to do something more involved, first discuss your ideas
-  on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers).
-  This will avoid unnecessary work and surely give you and us a good deal
-  of inspiration.
-
-* Relevant coding style guidelines are the [Go Code Review
-  Comments](https://code.google.com/p/go-wiki/wiki/CodeReviewComments)
-  and the _Formatting and style_ section of Peter Bourgon's [Go: Best
-  Practices for Production
-  Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style).
diff --git a/vendor/github.com/prometheus/procfs/LICENSE b/vendor/github.com/prometheus/procfs/LICENSE
deleted file mode 100644
index 261eeb9..0000000
--- a/vendor/github.com/prometheus/procfs/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/prometheus/procfs/MAINTAINERS.md b/vendor/github.com/prometheus/procfs/MAINTAINERS.md
deleted file mode 100644
index 35993c4..0000000
--- a/vendor/github.com/prometheus/procfs/MAINTAINERS.md
+++ /dev/null
@@ -1 +0,0 @@
-* Tobias Schmidt <tobidt@gmail.com>
diff --git a/vendor/github.com/prometheus/procfs/Makefile b/vendor/github.com/prometheus/procfs/Makefile
deleted file mode 100644
index 947d7d8..0000000
--- a/vendor/github.com/prometheus/procfs/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2018 The Prometheus Authors
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-include Makefile.common
-
-%/.unpacked: %.ttar
-	./ttar -C $(dir $*) -x -f $*.ttar
-	touch $@
-
-update_fixtures: fixtures.ttar sysfs/fixtures.ttar
-
-%fixtures.ttar: %/fixtures
-	rm -v $(dir $*)fixtures/.unpacked
-	./ttar -C $(dir $*) -c -f $*fixtures.ttar fixtures/
-
-.PHONY: build
-build:
-
-.PHONY: test
-test: fixtures/.unpacked sysfs/fixtures/.unpacked common-test
diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common
deleted file mode 100644
index 741579e..0000000
--- a/vendor/github.com/prometheus/procfs/Makefile.common
+++ /dev/null
@@ -1,223 +0,0 @@
-# Copyright 2018 The Prometheus Authors
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# A common Makefile that includes rules to be reused in different prometheus projects.
-# !!! Open PRs only against the prometheus/prometheus/Makefile.common repository!
-
-# Example usage :
-# Create the main Makefile in the root project directory.
-# include Makefile.common
-# customTarget:
-# 	@echo ">> Running customTarget"
-#
-
-# Ensure GOBIN is not set during build so that promu is installed to the correct path
-unexport GOBIN
-
-GO           ?= go
-GOFMT        ?= $(GO)fmt
-FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH)))
-GOOPTS       ?=
-
-GO_VERSION        ?= $(shell $(GO) version)
-GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION))
-PRE_GO_111        ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.')
-
-unexport GOVENDOR
-ifeq (, $(PRE_GO_111))
-	ifneq (,$(wildcard go.mod))
-		# Enforce Go modules support just in case the directory is inside GOPATH (and for Travis CI).
-		GO111MODULE := on
-
-		ifneq (,$(wildcard vendor))
-			# Always use the local vendor/ directory to satisfy the dependencies.
-			GOOPTS := $(GOOPTS) -mod=vendor
-		endif
-	endif
-else
-	ifneq (,$(wildcard go.mod))
-		ifneq (,$(wildcard vendor))
-$(warning This repository requires Go >= 1.11 because of Go modules)
-$(warning Some recipes may not work as expected as the current Go runtime is '$(GO_VERSION_NUMBER)')
-		endif
-	else
-		# This repository isn't using Go modules (yet).
-		GOVENDOR := $(FIRST_GOPATH)/bin/govendor
-	endif
-
-	unexport GO111MODULE
-endif
-PROMU        := $(FIRST_GOPATH)/bin/promu
-STATICCHECK  := $(FIRST_GOPATH)/bin/staticcheck
-pkgs          = ./...
-
-GO_VERSION        ?= $(shell $(GO) version)
-GO_BUILD_PLATFORM ?= $(subst /,-,$(lastword $(GO_VERSION)))
-
-PROMU_VERSION ?= 0.2.0
-PROMU_URL     := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
-
-PREFIX                  ?= $(shell pwd)
-BIN_DIR                 ?= $(shell pwd)
-DOCKER_IMAGE_TAG        ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD))
-DOCKER_REPO             ?= prom
-
-.PHONY: all
-all: precheck style staticcheck unused build test
-
-# This rule is used to forward a target like "build" to "common-build".  This
-# allows a new "build" target to be defined in a Makefile which includes this
-# one and override "common-build" without override warnings.
-%: common-% ;
-
-.PHONY: common-style
-common-style:
-	@echo ">> checking code style"
-	@fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \
-	if [ -n "$${fmtRes}" ]; then \
-		echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \
-		echo "Please ensure you are using $$($(GO) version) for formatting code."; \
-		exit 1; \
-	fi
-
-.PHONY: common-check_license
-common-check_license:
-	@echo ">> checking license header"
-	@licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \
-               awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \
-       done); \
-       if [ -n "$${licRes}" ]; then \
-               echo "license header checking failed:"; echo "$${licRes}"; \
-               exit 1; \
-       fi
-
-.PHONY: common-test-short
-common-test-short:
-	@echo ">> running short tests"
-	GO111MODULE=$(GO111MODULE) $(GO) test -short $(GOOPTS) $(pkgs)
-
-.PHONY: common-test
-common-test:
-	@echo ">> running all tests"
-	GO111MODULE=$(GO111MODULE) $(GO) test -race $(GOOPTS) $(pkgs)
-
-.PHONY: common-format
-common-format:
-	@echo ">> formatting code"
-	GO111MODULE=$(GO111MODULE) $(GO) fmt $(GOOPTS) $(pkgs)
-
-.PHONY: common-vet
-common-vet:
-	@echo ">> vetting code"
-	GO111MODULE=$(GO111MODULE) $(GO) vet $(GOOPTS) $(pkgs)
-
-.PHONY: common-staticcheck
-common-staticcheck: $(STATICCHECK)
-	@echo ">> running staticcheck"
-ifdef GO111MODULE
-	GO111MODULE=$(GO111MODULE) $(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" -checks "SA*" $(pkgs)
-else
-	$(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" $(pkgs)
-endif
-
-.PHONY: common-unused
-common-unused: $(GOVENDOR)
-ifdef GOVENDOR
-	@echo ">> running check for unused packages"
-	@$(GOVENDOR) list +unused | grep . && exit 1 || echo 'No unused packages'
-else
-ifdef GO111MODULE
-	@echo ">> running check for unused/missing packages in go.mod"
-	GO111MODULE=$(GO111MODULE) $(GO) mod tidy
-	@git diff --exit-code -- go.sum go.mod
-ifneq (,$(wildcard vendor))
-	@echo ">> running check for unused packages in vendor/"
-	GO111MODULE=$(GO111MODULE) $(GO) mod vendor
-	@git diff --exit-code -- go.sum go.mod vendor/
-endif
-endif
-endif
-
-.PHONY: common-build
-common-build: promu
-	@echo ">> building binaries"
-	GO111MODULE=$(GO111MODULE) $(PROMU) build --prefix $(PREFIX)
-
-.PHONY: common-tarball
-common-tarball: promu
-	@echo ">> building release tarball"
-	$(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR)
-
-.PHONY: common-docker
-common-docker:
-	docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" .
-
-.PHONY: common-docker-publish
-common-docker-publish:
-	docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)"
-
-.PHONY: common-docker-tag-latest
-common-docker-tag-latest:
-	docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):latest"
-
-.PHONY: promu
-promu: $(PROMU)
-
-$(PROMU):
-	curl -s -L $(PROMU_URL) | tar -xvz -C /tmp
-	mkdir -v -p $(FIRST_GOPATH)/bin
-	cp -v /tmp/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(PROMU)
-
-.PHONY: proto
-proto:
-	@echo ">> generating code from proto files"
-	@./scripts/genproto.sh
-
-.PHONY: $(STATICCHECK)
-$(STATICCHECK):
-ifdef GO111MODULE
-# Get staticcheck from a temporary directory to avoid modifying the local go.{mod,sum}.
-# See https://github.com/golang/go/issues/27643.
-# For now, we are using the next branch of staticcheck because master isn't compatible yet with Go modules.
-	tmpModule=$$(mktemp -d 2>&1) && \
-	mkdir -p $${tmpModule}/staticcheck && \
-	cd "$${tmpModule}"/staticcheck && \
-	GO111MODULE=on $(GO) mod init example.com/staticcheck && \
-	GO111MODULE=on GOOS= GOARCH= $(GO) get -u honnef.co/go/tools/cmd/staticcheck@next && \
-	rm -rf $${tmpModule};
-else
-	GOOS= GOARCH= GO111MODULE=off $(GO) get -u honnef.co/go/tools/cmd/staticcheck
-endif
-
-ifdef GOVENDOR
-.PHONY: $(GOVENDOR)
-$(GOVENDOR):
-	GOOS= GOARCH= $(GO) get -u github.com/kardianos/govendor
-endif
-
-.PHONY: precheck
-precheck::
-
-define PRECHECK_COMMAND_template =
-precheck:: $(1)_precheck
-
-
-PRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1)))
-.PHONY: $(1)_precheck
-$(1)_precheck:
-	@if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \
-		echo "Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?"; \
-		exit 1; \
-	fi
-endef
diff --git a/vendor/github.com/prometheus/procfs/NOTICE b/vendor/github.com/prometheus/procfs/NOTICE
deleted file mode 100644
index 53c5e9a..0000000
--- a/vendor/github.com/prometheus/procfs/NOTICE
+++ /dev/null
@@ -1,7 +0,0 @@
-procfs provides functions to retrieve system, kernel and process
-metrics from the pseudo-filesystem proc.
-
-Copyright 2014-2015 The Prometheus Authors
-
-This product includes software developed at
-SoundCloud Ltd. (http://soundcloud.com/).
diff --git a/vendor/github.com/prometheus/procfs/README.md b/vendor/github.com/prometheus/procfs/README.md
deleted file mode 100644
index 2095494..0000000
--- a/vendor/github.com/prometheus/procfs/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# procfs
-
-This procfs package provides functions to retrieve system, kernel and process
-metrics from the pseudo-filesystem proc.
-
-*WARNING*: This package is a work in progress. Its API may still break in
-backwards-incompatible ways without warnings. Use it at your own risk.
-
-[![GoDoc](https://godoc.org/github.com/prometheus/procfs?status.png)](https://godoc.org/github.com/prometheus/procfs)
-[![Build Status](https://travis-ci.org/prometheus/procfs.svg?branch=master)](https://travis-ci.org/prometheus/procfs)
-[![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/procfs)](https://goreportcard.com/report/github.com/prometheus/procfs)
diff --git a/vendor/github.com/prometheus/procfs/buddyinfo.go b/vendor/github.com/prometheus/procfs/buddyinfo.go
deleted file mode 100644
index d3a8268..0000000
--- a/vendor/github.com/prometheus/procfs/buddyinfo.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"os"
-	"strconv"
-	"strings"
-)
-
-// A BuddyInfo is the details parsed from /proc/buddyinfo.
-// The data is comprised of an array of free fragments of each size.
-// The sizes are 2^n*PAGE_SIZE, where n is the array index.
-type BuddyInfo struct {
-	Node  string
-	Zone  string
-	Sizes []float64
-}
-
-// NewBuddyInfo reads the buddyinfo statistics.
-func NewBuddyInfo() ([]BuddyInfo, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return nil, err
-	}
-
-	return fs.NewBuddyInfo()
-}
-
-// NewBuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.
-func (fs FS) NewBuddyInfo() ([]BuddyInfo, error) {
-	file, err := os.Open(fs.Path("buddyinfo"))
-	if err != nil {
-		return nil, err
-	}
-	defer file.Close()
-
-	return parseBuddyInfo(file)
-}
-
-func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) {
-	var (
-		buddyInfo   = []BuddyInfo{}
-		scanner     = bufio.NewScanner(r)
-		bucketCount = -1
-	)
-
-	for scanner.Scan() {
-		var err error
-		line := scanner.Text()
-		parts := strings.Fields(line)
-
-		if len(parts) < 4 {
-			return nil, fmt.Errorf("invalid number of fields when parsing buddyinfo")
-		}
-
-		node := strings.TrimRight(parts[1], ",")
-		zone := strings.TrimRight(parts[3], ",")
-		arraySize := len(parts[4:])
-
-		if bucketCount == -1 {
-			bucketCount = arraySize
-		} else {
-			if bucketCount != arraySize {
-				return nil, fmt.Errorf("mismatch in number of buddyinfo buckets, previous count %d, new count %d", bucketCount, arraySize)
-			}
-		}
-
-		sizes := make([]float64, arraySize)
-		for i := 0; i < arraySize; i++ {
-			sizes[i], err = strconv.ParseFloat(parts[i+4], 64)
-			if err != nil {
-				return nil, fmt.Errorf("invalid value in buddyinfo: %s", err)
-			}
-		}
-
-		buddyInfo = append(buddyInfo, BuddyInfo{node, zone, sizes})
-	}
-
-	return buddyInfo, scanner.Err()
-}
diff --git a/vendor/github.com/prometheus/procfs/doc.go b/vendor/github.com/prometheus/procfs/doc.go
deleted file mode 100644
index e2acd6d..0000000
--- a/vendor/github.com/prometheus/procfs/doc.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 Prometheus Team
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package procfs provides functions to retrieve system, kernel and process
-// metrics from the pseudo-filesystem proc.
-//
-// Example:
-//
-//    package main
-//
-//    import (
-//    	"fmt"
-//    	"log"
-//
-//    	"github.com/prometheus/procfs"
-//    )
-//
-//    func main() {
-//    	p, err := procfs.Self()
-//    	if err != nil {
-//    		log.Fatalf("could not get process: %s", err)
-//    	}
-//
-//    	stat, err := p.NewStat()
-//    	if err != nil {
-//    		log.Fatalf("could not get process stat: %s", err)
-//    	}
-//
-//    	fmt.Printf("command:  %s\n", stat.Comm)
-//    	fmt.Printf("cpu time: %fs\n", stat.CPUTime())
-//    	fmt.Printf("vsize:    %dB\n", stat.VirtualMemory())
-//    	fmt.Printf("rss:      %dB\n", stat.ResidentMemory())
-//    }
-//
-package procfs
diff --git a/vendor/github.com/prometheus/procfs/fixtures.ttar b/vendor/github.com/prometheus/procfs/fixtures.ttar
deleted file mode 100644
index 13c831e..0000000
--- a/vendor/github.com/prometheus/procfs/fixtures.ttar
+++ /dev/null
@@ -1,462 +0,0 @@
-# Archive created by ttar -c -f fixtures.ttar fixtures/
-Directory: fixtures
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/26231
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/cmdline
-Lines: 1
-vimNULLBYTEtest.goNULLBYTE+10NULLBYTEEOF
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/comm
-Lines: 1
-vim
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/cwd
-SymlinkTo: /usr/bin
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/exe
-SymlinkTo: /usr/bin/vim
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/26231/fd
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/fd/0
-SymlinkTo: ../../symlinktargets/abc
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/fd/1
-SymlinkTo: ../../symlinktargets/def
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/fd/10
-SymlinkTo: ../../symlinktargets/xyz
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/fd/2
-SymlinkTo: ../../symlinktargets/ghi
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/fd/3
-SymlinkTo: ../../symlinktargets/uvw
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/io
-Lines: 7
-rchar: 750339
-wchar: 818609
-syscr: 7405
-syscw: 5245
-read_bytes: 1024
-write_bytes: 2048
-cancelled_write_bytes: -1024
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/limits
-Lines: 17
-Limit                     Soft Limit           Hard Limit           Units
-Max cpu time              unlimited            unlimited            seconds
-Max file size             unlimited            unlimited            bytes
-Max data size             unlimited            unlimited            bytes
-Max stack size            8388608              unlimited            bytes
-Max core file size        0                    unlimited            bytes
-Max resident set          unlimited            unlimited            bytes
-Max processes             62898                62898                processes
-Max open files            2048                 4096                 files
-Max locked memory         65536                65536                bytes
-Max address space         8589934592           unlimited            bytes
-Max file locks            unlimited            unlimited            locks
-Max pending signals       62898                62898                signals
-Max msgqueue size         819200               819200               bytes
-Max nice priority         0                    0
-Max realtime priority     0                    0
-Max realtime timeout      unlimited            unlimited            us
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/mountstats
-Lines: 19
-device rootfs mounted on / with fstype rootfs
-device sysfs mounted on /sys with fstype sysfs
-device proc mounted on /proc with fstype proc
-device /dev/sda1 mounted on / with fstype ext4
-device 192.168.1.1:/srv/test mounted on /mnt/nfs/test with fstype nfs4 statvers=1.1
-	opts:	rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none
-	age:	13968
-	caps:	caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255
-	nfsv4:	bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured
-	sec:	flavor=1,pseudoflavor=1
-	events:	52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0
-	bytes:	1207640230 0 0 0 1210214218 0 295483 0
-	RPC iostats version: 1.0  p/v: 100003/4 (nfs)
-	xprt:	tcp 832 0 1 0 11 6428 6428 0 12154 0 24 26 5726
-	per-op statistics
-	        NULL: 0 0 0 0 0 0 0 0
-	        READ: 1298 1298 0 207680 1210292152 6 79386 79407
-	       WRITE: 0 0 0 0 0 0 0 0
-
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/26231/net
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/net/dev
-Lines: 4
-Inter-|   Receive                                                |  Transmit
- face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
-    lo:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
-  eth0:     438       5    0    0    0     0          0         0      648       8    0    0    0     0       0          0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/26231/ns
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/ns/mnt
-SymlinkTo: mnt:[4026531840]
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/ns/net
-SymlinkTo: net:[4026531993]
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/root
-SymlinkTo: /
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26231/stat
-Lines: 1
-26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/26232
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/cmdline
-Lines: 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/comm
-Lines: 1
-ata_sff
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/cwd
-SymlinkTo: /does/not/exist
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/26232/fd
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/fd/0
-SymlinkTo: ../../symlinktargets/abc
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/fd/1
-SymlinkTo: ../../symlinktargets/def
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/fd/2
-SymlinkTo: ../../symlinktargets/ghi
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/fd/3
-SymlinkTo: ../../symlinktargets/uvw
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/fd/4
-SymlinkTo: ../../symlinktargets/xyz
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/limits
-Lines: 17
-Limit                     Soft Limit           Hard Limit           Units     
-Max cpu time              unlimited            unlimited            seconds   
-Max file size             unlimited            unlimited            bytes     
-Max data size             unlimited            unlimited            bytes     
-Max stack size            8388608              unlimited            bytes     
-Max core file size        0                    unlimited            bytes     
-Max resident set          unlimited            unlimited            bytes     
-Max processes             29436                29436                processes 
-Max open files            1024                 4096                 files     
-Max locked memory         65536                65536                bytes     
-Max address space         unlimited            unlimited            bytes     
-Max file locks            unlimited            unlimited            locks     
-Max pending signals       29436                29436                signals   
-Max msgqueue size         819200               819200               bytes     
-Max nice priority         0                    0                    
-Max realtime priority     0                    0                    
-Max realtime timeout      unlimited            unlimited            us        
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/root
-SymlinkTo: /does/not/exist
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26232/stat
-Lines: 1
-33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/26233
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/26233/cmdline
-Lines: 1
-com.github.uiautomatorNULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTEEOF
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/584
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/584/stat
-Lines: 2
-1020 ((a b ) ( c d) ) R 28378 1020 28378 34842 1020 4218880 286 0 0 0 0 0 0 0 20 0 1 0 10839175 10395648 155 18446744073709551615 4194304 4238788 140736466511168 140736466511168 140609271124624 0 0 0 0 0 0 0 17 5 0 0 0 0 0 6336016 6337300 25579520 140736466515030 140736466515061 140736466515061 140736466518002 0
-#!/bin/cat /proc/self/stat
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/buddyinfo
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/buddyinfo/short
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/buddyinfo/short/buddyinfo
-Lines: 3
-Node 0, zone
-Node 0, zone
-Node 0, zone
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/buddyinfo/sizemismatch
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/buddyinfo/sizemismatch/buddyinfo
-Lines: 3
-Node 0, zone      DMA      1      0      1      0      2      1      1      0      1      1      3 
-Node 0, zone    DMA32    759    572    791    475    194     45     12      0      0      0      0      0
-Node 0, zone   Normal   4381   1093    185   1530    567    102      4      0      0      0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/buddyinfo/valid
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/buddyinfo/valid/buddyinfo
-Lines: 3
-Node 0, zone      DMA      1      0      1      0      2      1      1      0      1      1      3 
-Node 0, zone    DMA32    759    572    791    475    194     45     12      0      0      0      0 
-Node 0, zone   Normal   4381   1093    185   1530    567    102      4      0      0      0      0 
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/fs
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/fs/xfs
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/fs/xfs/stat
-Lines: 23
-extent_alloc 92447 97589 92448 93751
-abt 0 0 0 0
-blk_map 1767055 188820 184891 92447 92448 2140766 0
-bmbt 0 0 0 0
-dir 185039 92447 92444 136422
-trans 706 944304 0
-ig 185045 58807 0 126238 0 33637 22
-log 2883 113448 9 17360 739
-push_ail 945014 0 134260 15483 0 3940 464 159985 0 40
-xstrat 92447 0
-rw 107739 94045
-attr 4 0 0 0
-icluster 8677 7849 135802
-vnodes 92601 0 0 0 92444 92444 92444 0
-buf 2666287 7122 2659202 3599 2 7085 0 10297 7085
-abtb2 184941 1277345 13257 13278 0 0 0 0 0 0 0 0 0 0 2746147
-abtc2 345295 2416764 172637 172658 0 0 0 0 0 0 0 0 0 0 21406023
-bmbt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-ibt2 343004 1358467 0 0 0 0 0 0 0 0 0 0 0 0 0
-fibt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-qm 0 0 0 0 0 0 0 0
-xpc 399724544 92823103 86219234
-debug 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/mdstat
-Lines: 26
-Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
-md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9]
-      5853468288 blocks super 1.2 level 6, 64k chunk, algorithm 2 [8/8] [UUUUUUUU]
-      
-md127 : active raid1 sdi2[0] sdj2[1]
-      312319552 blocks [2/2] [UU]
-      
-md0 : active raid1 sdk[2](S) sdi1[0] sdj1[1]
-      248896 blocks [2/2] [UU]
-      
-md4 : inactive raid1 sda3[0] sdb3[1]
-      4883648 blocks [2/2] [UU]
-
-md6 : active raid1 sdb2[2] sda2[0]
-      195310144 blocks [2/1] [U_]
-      [=>...................]  recovery =  8.5% (16775552/195310144) finish=17.0min speed=259783K/sec
-
-md8 : active raid1 sdb1[1] sda1[0]
-      195310144 blocks [2/2] [UU]
-      [=>...................]  resync =  8.5% (16775552/195310144) finish=17.0min speed=259783K/sec
-
-md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1]
-      7813735424 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [U_UU]
-      bitmap: 0/30 pages [0KB], 65536KB chunk
-
-unused devices: <none>
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/net
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/net/dev
-Lines: 6
-Inter-|   Receive                                                |  Transmit
- face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
-vethf345468:     648       8    0    0    0     0          0         0      438       5    0    0    0     0       0          0
-    lo: 1664039048 1566805    0    0    0     0          0         0 1664039048 1566805    0    0    0     0       0          0
-docker0:    2568      38    0    0    0     0          0         0      438       5    0    0    0     0       0          0
-  eth0: 874354587 1036395    0    0    0     0          0         0 563352563  732147    0    0    0     0       0          0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/net/ip_vs
-Lines: 21
-IP Virtual Server version 1.2.1 (size=4096)
-Prot LocalAddress:Port Scheduler Flags
-  -> RemoteAddress:Port Forward Weight ActiveConn InActConn
-TCP  C0A80016:0CEA wlc
-  -> C0A85216:0CEA      Tunnel  100    248        2
-  -> C0A85318:0CEA      Tunnel  100    248        2
-  -> C0A85315:0CEA      Tunnel  100    248        1
-TCP  C0A80039:0CEA wlc
-  -> C0A85416:0CEA      Tunnel  0      0          0
-  -> C0A85215:0CEA      Tunnel  100    1499       0
-  -> C0A83215:0CEA      Tunnel  100    1498       0
-TCP  C0A80037:0CEA wlc
-  -> C0A8321A:0CEA      Tunnel  0      0          0
-  -> C0A83120:0CEA      Tunnel  100    0          0
-TCP  [2620:0000:0000:0000:0000:0000:0000:0001]:0050 sh
-  -> [2620:0000:0000:0000:0000:0000:0000:0002]:0050      Route   1      0          0
-  -> [2620:0000:0000:0000:0000:0000:0000:0003]:0050      Route   1      0          0
-  -> [2620:0000:0000:0000:0000:0000:0000:0004]:0050      Route   1      1          1
-FWM  10001000 wlc
-  -> C0A8321A:0CEA      Route   0      0          1
-  -> C0A83215:0CEA      Route   0      0          2
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/net/ip_vs_stats
-Lines: 6
-   Total Incoming Outgoing         Incoming         Outgoing
-   Conns  Packets  Packets            Bytes            Bytes
- 16AA370 E33656E5        0     51D8C8883AB3                0
-
- Conns/s   Pkts/s   Pkts/s          Bytes/s          Bytes/s
-       4    1FB3C        0          1282A8F                0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/net/rpc
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/net/rpc/nfs
-Lines: 5
-net 18628 0 18628 6
-rpc 4329785 0 4338291
-proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2
-proc3 22 1 4084749 29200 94754 32580 186 47747 7981 8639 0 6356 0 6962 0 7958 0 0 241 4 4 2 39
-proc4 61 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/net/rpc/nfsd
-Lines: 11
-rc 0 6 18622
-fh 0 0 0 0 0
-io 157286400 0
-th 8 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
-ra 32 0 0 0 0 0 0 0 0 0 0 0
-net 18628 0 18628 6
-rpc 18628 0 0 0 0
-proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2
-proc3 22 2 112 0 2719 111 0 0 0 0 0 0 0 0 0 0 0 27 216 0 2 1 0
-proc4 2 2 10853
-proc4ops 72 0 0 0 1098 2 0 0 0 0 8179 5896 0 0 0 0 5900 0 0 2 0 2 0 9609 0 2 150 1272 0 0 0 1236 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/net/xfrm_stat
-Lines: 28
-XfrmInError                     1
-XfrmInBufferError               2
-XfrmInHdrError                  4
-XfrmInNoStates                  3
-XfrmInStateProtoError           40
-XfrmInStateModeError            100
-XfrmInStateSeqError             6000
-XfrmInStateExpired              4
-XfrmInStateMismatch             23451
-XfrmInStateInvalid              55555
-XfrmInTmplMismatch              51
-XfrmInNoPols                    65432
-XfrmInPolBlock                  100
-XfrmInPolError                  10000
-XfrmOutError                    1000000
-XfrmOutBundleGenError           43321
-XfrmOutBundleCheckError         555
-XfrmOutNoStates                 869
-XfrmOutStateProtoError          4542
-XfrmOutStateModeError           4
-XfrmOutStateSeqError            543
-XfrmOutStateExpired             565
-XfrmOutPolBlock                 43456
-XfrmOutPolDead                  7656
-XfrmOutPolError                 1454
-XfrmFwdHdrError                 6654
-XfrmOutStateInvalid             28765
-XfrmAcquireError                24532
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/self
-SymlinkTo: 26231
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/stat
-Lines: 16
-cpu  301854 612 111922 8979004 3552 2 3944 0 0 0
-cpu0 44490 19 21045 1087069 220 1 3410 0 0 0
-cpu1 47869 23 16474 1110787 591 0 46 0 0 0
-cpu2 46504 36 15916 1112321 441 0 326 0 0 0
-cpu3 47054 102 15683 1113230 533 0 60 0 0 0
-cpu4 28413 25 10776 1140321 217 0 8 0 0 0
-cpu5 29271 101 11586 1136270 672 0 30 0 0 0
-cpu6 29152 36 10276 1139721 319 0 29 0 0 0
-cpu7 29098 268 10164 1139282 555 0 31 0 0 0
-intr 8885917 17 0 0 0 0 0 0 0 1 79281 0 0 0 0 0 0 0 231237 0 0 0 0 250586 103 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 223424 190745 13 906 1283803 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-ctxt 38014093
-btime 1418183276
-processes 26442
-procs_running 2
-procs_blocked 1
-softirq 5057579 250191 1481983 1647 211099 186066 0 1783454 622196 12499 508444
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Directory: fixtures/symlinktargets
-Mode: 755
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/symlinktargets/README
-Lines: 2
-This directory contains some empty files that are the symlinks the files in the "fd" directory point to.
-They are otherwise ignored by the tests
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/symlinktargets/abc
-Lines: 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/symlinktargets/def
-Lines: 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/symlinktargets/ghi
-Lines: 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/symlinktargets/uvw
-Lines: 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/symlinktargets/xyz
-Lines: 0
-Mode: 644
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Path: fixtures/.unpacked
-Lines: 0
-Mode: 664
-# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/vendor/github.com/prometheus/procfs/fs.go b/vendor/github.com/prometheus/procfs/fs.go
deleted file mode 100644
index b6c6b2c..0000000
--- a/vendor/github.com/prometheus/procfs/fs.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"fmt"
-	"os"
-	"path"
-
-	"github.com/prometheus/procfs/nfs"
-	"github.com/prometheus/procfs/xfs"
-)
-
-// FS represents the pseudo-filesystem proc, which provides an interface to
-// kernel data structures.
-type FS string
-
-// DefaultMountPoint is the common mount point of the proc filesystem.
-const DefaultMountPoint = "/proc"
-
-// NewFS returns a new FS mounted under the given mountPoint. It will error
-// if the mount point can't be read.
-func NewFS(mountPoint string) (FS, error) {
-	info, err := os.Stat(mountPoint)
-	if err != nil {
-		return "", fmt.Errorf("could not read %s: %s", mountPoint, err)
-	}
-	if !info.IsDir() {
-		return "", fmt.Errorf("mount point %s is not a directory", mountPoint)
-	}
-
-	return FS(mountPoint), nil
-}
-
-// Path returns the path of the given subsystem relative to the procfs root.
-func (fs FS) Path(p ...string) string {
-	return path.Join(append([]string{string(fs)}, p...)...)
-}
-
-// XFSStats retrieves XFS filesystem runtime statistics.
-func (fs FS) XFSStats() (*xfs.Stats, error) {
-	f, err := os.Open(fs.Path("fs/xfs/stat"))
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-
-	return xfs.ParseStats(f)
-}
-
-// NFSClientRPCStats retrieves NFS client RPC statistics.
-func (fs FS) NFSClientRPCStats() (*nfs.ClientRPCStats, error) {
-	f, err := os.Open(fs.Path("net/rpc/nfs"))
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-
-	return nfs.ParseClientRPCStats(f)
-}
-
-// NFSdServerRPCStats retrieves NFS daemon RPC statistics.
-func (fs FS) NFSdServerRPCStats() (*nfs.ServerRPCStats, error) {
-	f, err := os.Open(fs.Path("net/rpc/nfsd"))
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-
-	return nfs.ParseServerRPCStats(f)
-}
diff --git a/vendor/github.com/prometheus/procfs/go.mod b/vendor/github.com/prometheus/procfs/go.mod
deleted file mode 100644
index e89ee6c..0000000
--- a/vendor/github.com/prometheus/procfs/go.mod
+++ /dev/null
@@ -1 +0,0 @@
-module github.com/prometheus/procfs
diff --git a/vendor/github.com/prometheus/procfs/internal/util/parse.go b/vendor/github.com/prometheus/procfs/internal/util/parse.go
deleted file mode 100644
index 2ff228e..0000000
--- a/vendor/github.com/prometheus/procfs/internal/util/parse.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package util
-
-import (
-	"io/ioutil"
-	"strconv"
-	"strings"
-)
-
-// ParseUint32s parses a slice of strings into a slice of uint32s.
-func ParseUint32s(ss []string) ([]uint32, error) {
-	us := make([]uint32, 0, len(ss))
-	for _, s := range ss {
-		u, err := strconv.ParseUint(s, 10, 32)
-		if err != nil {
-			return nil, err
-		}
-
-		us = append(us, uint32(u))
-	}
-
-	return us, nil
-}
-
-// ParseUint64s parses a slice of strings into a slice of uint64s.
-func ParseUint64s(ss []string) ([]uint64, error) {
-	us := make([]uint64, 0, len(ss))
-	for _, s := range ss {
-		u, err := strconv.ParseUint(s, 10, 64)
-		if err != nil {
-			return nil, err
-		}
-
-		us = append(us, u)
-	}
-
-	return us, nil
-}
-
-// ReadUintFromFile reads a file and attempts to parse a uint64 from it.
-func ReadUintFromFile(path string) (uint64, error) {
-	data, err := ioutil.ReadFile(path)
-	if err != nil {
-		return 0, err
-	}
-	return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
-}
diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_linux.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_linux.go
deleted file mode 100644
index df0d567..0000000
--- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_linux.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !windows
-
-package util
-
-import (
-	"bytes"
-	"os"
-	"syscall"
-)
-
-// SysReadFile is a simplified ioutil.ReadFile that invokes syscall.Read directly.
-// https://github.com/prometheus/node_exporter/pull/728/files
-func SysReadFile(file string) (string, error) {
-	f, err := os.Open(file)
-	if err != nil {
-		return "", err
-	}
-	defer f.Close()
-
-	// On some machines, hwmon drivers are broken and return EAGAIN.  This causes
-	// Go's ioutil.ReadFile implementation to poll forever.
-	//
-	// Since we either want to read data or bail immediately, do the simplest
-	// possible read using syscall directly.
-	b := make([]byte, 128)
-	n, err := syscall.Read(int(f.Fd()), b)
-	if err != nil {
-		return "", err
-	}
-
-	return string(bytes.TrimSpace(b[:n])), nil
-}
diff --git a/vendor/github.com/prometheus/procfs/ipvs.go b/vendor/github.com/prometheus/procfs/ipvs.go
deleted file mode 100644
index e36d4a3..0000000
--- a/vendor/github.com/prometheus/procfs/ipvs.go
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"bufio"
-	"encoding/hex"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net"
-	"os"
-	"strconv"
-	"strings"
-)
-
-// IPVSStats holds IPVS statistics, as exposed by the kernel in `/proc/net/ip_vs_stats`.
-type IPVSStats struct {
-	// Total count of connections.
-	Connections uint64
-	// Total incoming packages processed.
-	IncomingPackets uint64
-	// Total outgoing packages processed.
-	OutgoingPackets uint64
-	// Total incoming traffic.
-	IncomingBytes uint64
-	// Total outgoing traffic.
-	OutgoingBytes uint64
-}
-
-// IPVSBackendStatus holds current metrics of one virtual / real address pair.
-type IPVSBackendStatus struct {
-	// The local (virtual) IP address.
-	LocalAddress net.IP
-	// The remote (real) IP address.
-	RemoteAddress net.IP
-	// The local (virtual) port.
-	LocalPort uint16
-	// The remote (real) port.
-	RemotePort uint16
-	// The local firewall mark
-	LocalMark string
-	// The transport protocol (TCP, UDP).
-	Proto string
-	// The current number of active connections for this virtual/real address pair.
-	ActiveConn uint64
-	// The current number of inactive connections for this virtual/real address pair.
-	InactConn uint64
-	// The current weight of this virtual/real address pair.
-	Weight uint64
-}
-
-// NewIPVSStats reads the IPVS statistics.
-func NewIPVSStats() (IPVSStats, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return IPVSStats{}, err
-	}
-
-	return fs.NewIPVSStats()
-}
-
-// NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem.
-func (fs FS) NewIPVSStats() (IPVSStats, error) {
-	file, err := os.Open(fs.Path("net/ip_vs_stats"))
-	if err != nil {
-		return IPVSStats{}, err
-	}
-	defer file.Close()
-
-	return parseIPVSStats(file)
-}
-
-// parseIPVSStats performs the actual parsing of `ip_vs_stats`.
-func parseIPVSStats(file io.Reader) (IPVSStats, error) {
-	var (
-		statContent []byte
-		statLines   []string
-		statFields  []string
-		stats       IPVSStats
-	)
-
-	statContent, err := ioutil.ReadAll(file)
-	if err != nil {
-		return IPVSStats{}, err
-	}
-
-	statLines = strings.SplitN(string(statContent), "\n", 4)
-	if len(statLines) != 4 {
-		return IPVSStats{}, errors.New("ip_vs_stats corrupt: too short")
-	}
-
-	statFields = strings.Fields(statLines[2])
-	if len(statFields) != 5 {
-		return IPVSStats{}, errors.New("ip_vs_stats corrupt: unexpected number of fields")
-	}
-
-	stats.Connections, err = strconv.ParseUint(statFields[0], 16, 64)
-	if err != nil {
-		return IPVSStats{}, err
-	}
-	stats.IncomingPackets, err = strconv.ParseUint(statFields[1], 16, 64)
-	if err != nil {
-		return IPVSStats{}, err
-	}
-	stats.OutgoingPackets, err = strconv.ParseUint(statFields[2], 16, 64)
-	if err != nil {
-		return IPVSStats{}, err
-	}
-	stats.IncomingBytes, err = strconv.ParseUint(statFields[3], 16, 64)
-	if err != nil {
-		return IPVSStats{}, err
-	}
-	stats.OutgoingBytes, err = strconv.ParseUint(statFields[4], 16, 64)
-	if err != nil {
-		return IPVSStats{}, err
-	}
-
-	return stats, nil
-}
-
-// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs.
-func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return []IPVSBackendStatus{}, err
-	}
-
-	return fs.NewIPVSBackendStatus()
-}
-
-// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
-func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
-	file, err := os.Open(fs.Path("net/ip_vs"))
-	if err != nil {
-		return nil, err
-	}
-	defer file.Close()
-
-	return parseIPVSBackendStatus(file)
-}
-
-func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
-	var (
-		status       []IPVSBackendStatus
-		scanner      = bufio.NewScanner(file)
-		proto        string
-		localMark    string
-		localAddress net.IP
-		localPort    uint16
-		err          error
-	)
-
-	for scanner.Scan() {
-		fields := strings.Fields(scanner.Text())
-		if len(fields) == 0 {
-			continue
-		}
-		switch {
-		case fields[0] == "IP" || fields[0] == "Prot" || fields[1] == "RemoteAddress:Port":
-			continue
-		case fields[0] == "TCP" || fields[0] == "UDP":
-			if len(fields) < 2 {
-				continue
-			}
-			proto = fields[0]
-			localMark = ""
-			localAddress, localPort, err = parseIPPort(fields[1])
-			if err != nil {
-				return nil, err
-			}
-		case fields[0] == "FWM":
-			if len(fields) < 2 {
-				continue
-			}
-			proto = fields[0]
-			localMark = fields[1]
-			localAddress = nil
-			localPort = 0
-		case fields[0] == "->":
-			if len(fields) < 6 {
-				continue
-			}
-			remoteAddress, remotePort, err := parseIPPort(fields[1])
-			if err != nil {
-				return nil, err
-			}
-			weight, err := strconv.ParseUint(fields[3], 10, 64)
-			if err != nil {
-				return nil, err
-			}
-			activeConn, err := strconv.ParseUint(fields[4], 10, 64)
-			if err != nil {
-				return nil, err
-			}
-			inactConn, err := strconv.ParseUint(fields[5], 10, 64)
-			if err != nil {
-				return nil, err
-			}
-			status = append(status, IPVSBackendStatus{
-				LocalAddress:  localAddress,
-				LocalPort:     localPort,
-				LocalMark:     localMark,
-				RemoteAddress: remoteAddress,
-				RemotePort:    remotePort,
-				Proto:         proto,
-				Weight:        weight,
-				ActiveConn:    activeConn,
-				InactConn:     inactConn,
-			})
-		}
-	}
-	return status, nil
-}
-
-func parseIPPort(s string) (net.IP, uint16, error) {
-	var (
-		ip  net.IP
-		err error
-	)
-
-	switch len(s) {
-	case 13:
-		ip, err = hex.DecodeString(s[0:8])
-		if err != nil {
-			return nil, 0, err
-		}
-	case 46:
-		ip = net.ParseIP(s[1:40])
-		if ip == nil {
-			return nil, 0, fmt.Errorf("invalid IPv6 address: %s", s[1:40])
-		}
-	default:
-		return nil, 0, fmt.Errorf("unexpected IP:Port: %s", s)
-	}
-
-	portString := s[len(s)-4:]
-	if len(portString) != 4 {
-		return nil, 0, fmt.Errorf("unexpected port string format: %s", portString)
-	}
-	port, err := strconv.ParseUint(portString, 16, 16)
-	if err != nil {
-		return nil, 0, err
-	}
-
-	return ip, uint16(port), nil
-}
diff --git a/vendor/github.com/prometheus/procfs/mdstat.go b/vendor/github.com/prometheus/procfs/mdstat.go
deleted file mode 100644
index 9dc1958..0000000
--- a/vendor/github.com/prometheus/procfs/mdstat.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"fmt"
-	"io/ioutil"
-	"regexp"
-	"strconv"
-	"strings"
-)
-
-var (
-	statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
-	buildlineRE  = regexp.MustCompile(`\((\d+)/\d+\)`)
-)
-
-// MDStat holds info parsed from /proc/mdstat.
-type MDStat struct {
-	// Name of the device.
-	Name string
-	// activity-state of the device.
-	ActivityState string
-	// Number of active disks.
-	DisksActive int64
-	// Total number of disks the device consists of.
-	DisksTotal int64
-	// Number of blocks the device holds.
-	BlocksTotal int64
-	// Number of blocks on the device that are in sync.
-	BlocksSynced int64
-}
-
-// ParseMDStat parses an mdstat-file and returns a struct with the relevant infos.
-func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
-	mdStatusFilePath := fs.Path("mdstat")
-	content, err := ioutil.ReadFile(mdStatusFilePath)
-	if err != nil {
-		return []MDStat{}, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
-	}
-
-	mdStates := []MDStat{}
-	lines := strings.Split(string(content), "\n")
-	for i, l := range lines {
-		if l == "" {
-			continue
-		}
-		if l[0] == ' ' {
-			continue
-		}
-		if strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") {
-			continue
-		}
-
-		mainLine := strings.Split(l, " ")
-		if len(mainLine) < 3 {
-			return mdStates, fmt.Errorf("error parsing mdline: %s", l)
-		}
-		mdName := mainLine[0]
-		activityState := mainLine[2]
-
-		if len(lines) <= i+3 {
-			return mdStates, fmt.Errorf(
-				"error parsing %s: too few lines for md device %s",
-				mdStatusFilePath,
-				mdName,
-			)
-		}
-
-		active, total, size, err := evalStatusline(lines[i+1])
-		if err != nil {
-			return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
-		}
-
-		// j is the line number of the syncing-line.
-		j := i + 2
-		if strings.Contains(lines[i+2], "bitmap") { // skip bitmap line
-			j = i + 3
-		}
-
-		// If device is syncing at the moment, get the number of currently
-		// synced bytes, otherwise that number equals the size of the device.
-		syncedBlocks := size
-		if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") {
-			syncedBlocks, err = evalBuildline(lines[j])
-			if err != nil {
-				return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
-			}
-		}
-
-		mdStates = append(mdStates, MDStat{
-			Name:          mdName,
-			ActivityState: activityState,
-			DisksActive:   active,
-			DisksTotal:    total,
-			BlocksTotal:   size,
-			BlocksSynced:  syncedBlocks,
-		})
-	}
-
-	return mdStates, nil
-}
-
-func evalStatusline(statusline string) (active, total, size int64, err error) {
-	matches := statuslineRE.FindStringSubmatch(statusline)
-	if len(matches) != 4 {
-		return 0, 0, 0, fmt.Errorf("unexpected statusline: %s", statusline)
-	}
-
-	size, err = strconv.ParseInt(matches[1], 10, 64)
-	if err != nil {
-		return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
-	}
-
-	total, err = strconv.ParseInt(matches[2], 10, 64)
-	if err != nil {
-		return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
-	}
-
-	active, err = strconv.ParseInt(matches[3], 10, 64)
-	if err != nil {
-		return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
-	}
-
-	return active, total, size, nil
-}
-
-func evalBuildline(buildline string) (syncedBlocks int64, err error) {
-	matches := buildlineRE.FindStringSubmatch(buildline)
-	if len(matches) != 2 {
-		return 0, fmt.Errorf("unexpected buildline: %s", buildline)
-	}
-
-	syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64)
-	if err != nil {
-		return 0, fmt.Errorf("%s in buildline: %s", err, buildline)
-	}
-
-	return syncedBlocks, nil
-}
diff --git a/vendor/github.com/prometheus/procfs/mountstats.go b/vendor/github.com/prometheus/procfs/mountstats.go
deleted file mode 100644
index 7a8a1e0..0000000
--- a/vendor/github.com/prometheus/procfs/mountstats.go
+++ /dev/null
@@ -1,606 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-// While implementing parsing of /proc/[pid]/mountstats, this blog was used
-// heavily as a reference:
-//   https://utcc.utoronto.ca/~cks/space/blog/linux/NFSMountstatsIndex
-//
-// Special thanks to Chris Siebenmann for all of his posts explaining the
-// various statistics available for NFS.
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"strconv"
-	"strings"
-	"time"
-)
-
-// Constants shared between multiple functions.
-const (
-	deviceEntryLen = 8
-
-	fieldBytesLen  = 8
-	fieldEventsLen = 27
-
-	statVersion10 = "1.0"
-	statVersion11 = "1.1"
-
-	fieldTransport10TCPLen = 10
-	fieldTransport10UDPLen = 7
-
-	fieldTransport11TCPLen = 13
-	fieldTransport11UDPLen = 10
-)
-
-// A Mount is a device mount parsed from /proc/[pid]/mountstats.
-type Mount struct {
-	// Name of the device.
-	Device string
-	// The mount point of the device.
-	Mount string
-	// The filesystem type used by the device.
-	Type string
-	// If available additional statistics related to this Mount.
-	// Use a type assertion to determine if additional statistics are available.
-	Stats MountStats
-}
-
-// A MountStats is a type which contains detailed statistics for a specific
-// type of Mount.
-type MountStats interface {
-	mountStats()
-}
-
-// A MountStatsNFS is a MountStats implementation for NFSv3 and v4 mounts.
-type MountStatsNFS struct {
-	// The version of statistics provided.
-	StatVersion string
-	// The age of the NFS mount.
-	Age time.Duration
-	// Statistics related to byte counters for various operations.
-	Bytes NFSBytesStats
-	// Statistics related to various NFS event occurrences.
-	Events NFSEventsStats
-	// Statistics broken down by filesystem operation.
-	Operations []NFSOperationStats
-	// Statistics about the NFS RPC transport.
-	Transport NFSTransportStats
-}
-
-// mountStats implements MountStats.
-func (m MountStatsNFS) mountStats() {}
-
-// A NFSBytesStats contains statistics about the number of bytes read and written
-// by an NFS client to and from an NFS server.
-type NFSBytesStats struct {
-	// Number of bytes read using the read() syscall.
-	Read uint64
-	// Number of bytes written using the write() syscall.
-	Write uint64
-	// Number of bytes read using the read() syscall in O_DIRECT mode.
-	DirectRead uint64
-	// Number of bytes written using the write() syscall in O_DIRECT mode.
-	DirectWrite uint64
-	// Number of bytes read from the NFS server, in total.
-	ReadTotal uint64
-	// Number of bytes written to the NFS server, in total.
-	WriteTotal uint64
-	// Number of pages read directly via mmap()'d files.
-	ReadPages uint64
-	// Number of pages written directly via mmap()'d files.
-	WritePages uint64
-}
-
-// A NFSEventsStats contains statistics about NFS event occurrences.
-type NFSEventsStats struct {
-	// Number of times cached inode attributes are re-validated from the server.
-	InodeRevalidate uint64
-	// Number of times cached dentry nodes are re-validated from the server.
-	DnodeRevalidate uint64
-	// Number of times an inode cache is cleared.
-	DataInvalidate uint64
-	// Number of times cached inode attributes are invalidated.
-	AttributeInvalidate uint64
-	// Number of times files or directories have been open()'d.
-	VFSOpen uint64
-	// Number of times a directory lookup has occurred.
-	VFSLookup uint64
-	// Number of times permissions have been checked.
-	VFSAccess uint64
-	// Number of updates (and potential writes) to pages.
-	VFSUpdatePage uint64
-	// Number of pages read directly via mmap()'d files.
-	VFSReadPage uint64
-	// Number of times a group of pages have been read.
-	VFSReadPages uint64
-	// Number of pages written directly via mmap()'d files.
-	VFSWritePage uint64
-	// Number of times a group of pages have been written.
-	VFSWritePages uint64
-	// Number of times directory entries have been read with getdents().
-	VFSGetdents uint64
-	// Number of times attributes have been set on inodes.
-	VFSSetattr uint64
-	// Number of pending writes that have been forcefully flushed to the server.
-	VFSFlush uint64
-	// Number of times fsync() has been called on directories and files.
-	VFSFsync uint64
-	// Number of times locking has been attempted on a file.
-	VFSLock uint64
-	// Number of times files have been closed and released.
-	VFSFileRelease uint64
-	// Unknown.  Possibly unused.
-	CongestionWait uint64
-	// Number of times files have been truncated.
-	Truncation uint64
-	// Number of times a file has been grown due to writes beyond its existing end.
-	WriteExtension uint64
-	// Number of times a file was removed while still open by another process.
-	SillyRename uint64
-	// Number of times the NFS server gave less data than expected while reading.
-	ShortRead uint64
-	// Number of times the NFS server wrote less data than expected while writing.
-	ShortWrite uint64
-	// Number of times the NFS server indicated EJUKEBOX; retrieving data from
-	// offline storage.
-	JukeboxDelay uint64
-	// Number of NFS v4.1+ pNFS reads.
-	PNFSRead uint64
-	// Number of NFS v4.1+ pNFS writes.
-	PNFSWrite uint64
-}
-
-// A NFSOperationStats contains statistics for a single operation.
-type NFSOperationStats struct {
-	// The name of the operation.
-	Operation string
-	// Number of requests performed for this operation.
-	Requests uint64
-	// Number of times an actual RPC request has been transmitted for this operation.
-	Transmissions uint64
-	// Number of times a request has had a major timeout.
-	MajorTimeouts uint64
-	// Number of bytes sent for this operation, including RPC headers and payload.
-	BytesSent uint64
-	// Number of bytes received for this operation, including RPC headers and payload.
-	BytesReceived uint64
-	// Duration all requests spent queued for transmission before they were sent.
-	CumulativeQueueTime time.Duration
-	// Duration it took to get a reply back after the request was transmitted.
-	CumulativeTotalResponseTime time.Duration
-	// Duration from when a request was enqueued to when it was completely handled.
-	CumulativeTotalRequestTime time.Duration
-}
-
-// A NFSTransportStats contains statistics for the NFS mount RPC requests and
-// responses.
-type NFSTransportStats struct {
-	// The transport protocol used for the NFS mount.
-	Protocol string
-	// The local port used for the NFS mount.
-	Port uint64
-	// Number of times the client has had to establish a connection from scratch
-	// to the NFS server.
-	Bind uint64
-	// Number of times the client has made a TCP connection to the NFS server.
-	Connect uint64
-	// Duration (in jiffies, a kernel internal unit of time) the NFS mount has
-	// spent waiting for connections to the server to be established.
-	ConnectIdleTime uint64
-	// Duration since the NFS mount last saw any RPC traffic.
-	IdleTime time.Duration
-	// Number of RPC requests for this mount sent to the NFS server.
-	Sends uint64
-	// Number of RPC responses for this mount received from the NFS server.
-	Receives uint64
-	// Number of times the NFS server sent a response with a transaction ID
-	// unknown to this client.
-	BadTransactionIDs uint64
-	// A running counter, incremented on each request as the current difference
-	// ebetween sends and receives.
-	CumulativeActiveRequests uint64
-	// A running counter, incremented on each request by the current backlog
-	// queue size.
-	CumulativeBacklog uint64
-
-	// Stats below only available with stat version 1.1.
-
-	// Maximum number of simultaneously active RPC requests ever used.
-	MaximumRPCSlotsUsed uint64
-	// A running counter, incremented on each request as the current size of the
-	// sending queue.
-	CumulativeSendingQueue uint64
-	// A running counter, incremented on each request as the current size of the
-	// pending queue.
-	CumulativePendingQueue uint64
-}
-
-// parseMountStats parses a /proc/[pid]/mountstats file and returns a slice
-// of Mount structures containing detailed information about each mount.
-// If available, statistics for each mount are parsed as well.
-func parseMountStats(r io.Reader) ([]*Mount, error) {
-	const (
-		device            = "device"
-		statVersionPrefix = "statvers="
-
-		nfs3Type = "nfs"
-		nfs4Type = "nfs4"
-	)
-
-	var mounts []*Mount
-
-	s := bufio.NewScanner(r)
-	for s.Scan() {
-		// Only look for device entries in this function
-		ss := strings.Fields(string(s.Bytes()))
-		if len(ss) == 0 || ss[0] != device {
-			continue
-		}
-
-		m, err := parseMount(ss)
-		if err != nil {
-			return nil, err
-		}
-
-		// Does this mount also possess statistics information?
-		if len(ss) > deviceEntryLen {
-			// Only NFSv3 and v4 are supported for parsing statistics
-			if m.Type != nfs3Type && m.Type != nfs4Type {
-				return nil, fmt.Errorf("cannot parse MountStats for fstype %q", m.Type)
-			}
-
-			statVersion := strings.TrimPrefix(ss[8], statVersionPrefix)
-
-			stats, err := parseMountStatsNFS(s, statVersion)
-			if err != nil {
-				return nil, err
-			}
-
-			m.Stats = stats
-		}
-
-		mounts = append(mounts, m)
-	}
-
-	return mounts, s.Err()
-}
-
-// parseMount parses an entry in /proc/[pid]/mountstats in the format:
-//   device [device] mounted on [mount] with fstype [type]
-func parseMount(ss []string) (*Mount, error) {
-	if len(ss) < deviceEntryLen {
-		return nil, fmt.Errorf("invalid device entry: %v", ss)
-	}
-
-	// Check for specific words appearing at specific indices to ensure
-	// the format is consistent with what we expect
-	format := []struct {
-		i int
-		s string
-	}{
-		{i: 0, s: "device"},
-		{i: 2, s: "mounted"},
-		{i: 3, s: "on"},
-		{i: 5, s: "with"},
-		{i: 6, s: "fstype"},
-	}
-
-	for _, f := range format {
-		if ss[f.i] != f.s {
-			return nil, fmt.Errorf("invalid device entry: %v", ss)
-		}
-	}
-
-	return &Mount{
-		Device: ss[1],
-		Mount:  ss[4],
-		Type:   ss[7],
-	}, nil
-}
-
-// parseMountStatsNFS parses a MountStatsNFS by scanning additional information
-// related to NFS statistics.
-func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, error) {
-	// Field indicators for parsing specific types of data
-	const (
-		fieldAge        = "age:"
-		fieldBytes      = "bytes:"
-		fieldEvents     = "events:"
-		fieldPerOpStats = "per-op"
-		fieldTransport  = "xprt:"
-	)
-
-	stats := &MountStatsNFS{
-		StatVersion: statVersion,
-	}
-
-	for s.Scan() {
-		ss := strings.Fields(string(s.Bytes()))
-		if len(ss) == 0 {
-			break
-		}
-		if len(ss) < 2 {
-			return nil, fmt.Errorf("not enough information for NFS stats: %v", ss)
-		}
-
-		switch ss[0] {
-		case fieldAge:
-			// Age integer is in seconds
-			d, err := time.ParseDuration(ss[1] + "s")
-			if err != nil {
-				return nil, err
-			}
-
-			stats.Age = d
-		case fieldBytes:
-			bstats, err := parseNFSBytesStats(ss[1:])
-			if err != nil {
-				return nil, err
-			}
-
-			stats.Bytes = *bstats
-		case fieldEvents:
-			estats, err := parseNFSEventsStats(ss[1:])
-			if err != nil {
-				return nil, err
-			}
-
-			stats.Events = *estats
-		case fieldTransport:
-			if len(ss) < 3 {
-				return nil, fmt.Errorf("not enough information for NFS transport stats: %v", ss)
-			}
-
-			tstats, err := parseNFSTransportStats(ss[1:], statVersion)
-			if err != nil {
-				return nil, err
-			}
-
-			stats.Transport = *tstats
-		}
-
-		// When encountering "per-operation statistics", we must break this
-		// loop and parse them separately to ensure we can terminate parsing
-		// before reaching another device entry; hence why this 'if' statement
-		// is not just another switch case
-		if ss[0] == fieldPerOpStats {
-			break
-		}
-	}
-
-	if err := s.Err(); err != nil {
-		return nil, err
-	}
-
-	// NFS per-operation stats appear last before the next device entry
-	perOpStats, err := parseNFSOperationStats(s)
-	if err != nil {
-		return nil, err
-	}
-
-	stats.Operations = perOpStats
-
-	return stats, nil
-}
-
-// parseNFSBytesStats parses a NFSBytesStats line using an input set of
-// integer fields.
-func parseNFSBytesStats(ss []string) (*NFSBytesStats, error) {
-	if len(ss) != fieldBytesLen {
-		return nil, fmt.Errorf("invalid NFS bytes stats: %v", ss)
-	}
-
-	ns := make([]uint64, 0, fieldBytesLen)
-	for _, s := range ss {
-		n, err := strconv.ParseUint(s, 10, 64)
-		if err != nil {
-			return nil, err
-		}
-
-		ns = append(ns, n)
-	}
-
-	return &NFSBytesStats{
-		Read:        ns[0],
-		Write:       ns[1],
-		DirectRead:  ns[2],
-		DirectWrite: ns[3],
-		ReadTotal:   ns[4],
-		WriteTotal:  ns[5],
-		ReadPages:   ns[6],
-		WritePages:  ns[7],
-	}, nil
-}
-
-// parseNFSEventsStats parses a NFSEventsStats line using an input set of
-// integer fields.
-func parseNFSEventsStats(ss []string) (*NFSEventsStats, error) {
-	if len(ss) != fieldEventsLen {
-		return nil, fmt.Errorf("invalid NFS events stats: %v", ss)
-	}
-
-	ns := make([]uint64, 0, fieldEventsLen)
-	for _, s := range ss {
-		n, err := strconv.ParseUint(s, 10, 64)
-		if err != nil {
-			return nil, err
-		}
-
-		ns = append(ns, n)
-	}
-
-	return &NFSEventsStats{
-		InodeRevalidate:     ns[0],
-		DnodeRevalidate:     ns[1],
-		DataInvalidate:      ns[2],
-		AttributeInvalidate: ns[3],
-		VFSOpen:             ns[4],
-		VFSLookup:           ns[5],
-		VFSAccess:           ns[6],
-		VFSUpdatePage:       ns[7],
-		VFSReadPage:         ns[8],
-		VFSReadPages:        ns[9],
-		VFSWritePage:        ns[10],
-		VFSWritePages:       ns[11],
-		VFSGetdents:         ns[12],
-		VFSSetattr:          ns[13],
-		VFSFlush:            ns[14],
-		VFSFsync:            ns[15],
-		VFSLock:             ns[16],
-		VFSFileRelease:      ns[17],
-		CongestionWait:      ns[18],
-		Truncation:          ns[19],
-		WriteExtension:      ns[20],
-		SillyRename:         ns[21],
-		ShortRead:           ns[22],
-		ShortWrite:          ns[23],
-		JukeboxDelay:        ns[24],
-		PNFSRead:            ns[25],
-		PNFSWrite:           ns[26],
-	}, nil
-}
-
-// parseNFSOperationStats parses a slice of NFSOperationStats by scanning
-// additional information about per-operation statistics until an empty
-// line is reached.
-func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
-	const (
-		// Number of expected fields in each per-operation statistics set
-		numFields = 9
-	)
-
-	var ops []NFSOperationStats
-
-	for s.Scan() {
-		ss := strings.Fields(string(s.Bytes()))
-		if len(ss) == 0 {
-			// Must break when reading a blank line after per-operation stats to
-			// enable top-level function to parse the next device entry
-			break
-		}
-
-		if len(ss) != numFields {
-			return nil, fmt.Errorf("invalid NFS per-operations stats: %v", ss)
-		}
-
-		// Skip string operation name for integers
-		ns := make([]uint64, 0, numFields-1)
-		for _, st := range ss[1:] {
-			n, err := strconv.ParseUint(st, 10, 64)
-			if err != nil {
-				return nil, err
-			}
-
-			ns = append(ns, n)
-		}
-
-		ops = append(ops, NFSOperationStats{
-			Operation:                   strings.TrimSuffix(ss[0], ":"),
-			Requests:                    ns[0],
-			Transmissions:               ns[1],
-			MajorTimeouts:               ns[2],
-			BytesSent:                   ns[3],
-			BytesReceived:               ns[4],
-			CumulativeQueueTime:         time.Duration(ns[5]) * time.Millisecond,
-			CumulativeTotalResponseTime: time.Duration(ns[6]) * time.Millisecond,
-			CumulativeTotalRequestTime:  time.Duration(ns[7]) * time.Millisecond,
-		})
-	}
-
-	return ops, s.Err()
-}
-
-// parseNFSTransportStats parses a NFSTransportStats line using an input set of
-// integer fields matched to a specific stats version.
-func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats, error) {
-	// Extract the protocol field. It is the only string value in the line
-	protocol := ss[0]
-	ss = ss[1:]
-
-	switch statVersion {
-	case statVersion10:
-		var expectedLength int
-		if protocol == "tcp" {
-			expectedLength = fieldTransport10TCPLen
-		} else if protocol == "udp" {
-			expectedLength = fieldTransport10UDPLen
-		} else {
-			return nil, fmt.Errorf("invalid NFS protocol \"%s\" in stats 1.0 statement: %v", protocol, ss)
-		}
-		if len(ss) != expectedLength {
-			return nil, fmt.Errorf("invalid NFS transport stats 1.0 statement: %v", ss)
-		}
-	case statVersion11:
-		var expectedLength int
-		if protocol == "tcp" {
-			expectedLength = fieldTransport11TCPLen
-		} else if protocol == "udp" {
-			expectedLength = fieldTransport11UDPLen
-		} else {
-			return nil, fmt.Errorf("invalid NFS protocol \"%s\" in stats 1.1 statement: %v", protocol, ss)
-		}
-		if len(ss) != expectedLength {
-			return nil, fmt.Errorf("invalid NFS transport stats 1.1 statement: %v", ss)
-		}
-	default:
-		return nil, fmt.Errorf("unrecognized NFS transport stats version: %q", statVersion)
-	}
-
-	// Allocate enough for v1.1 stats since zero value for v1.1 stats will be okay
-	// in a v1.0 response. Since the stat length is bigger for TCP stats, we use
-	// the TCP length here.
-	//
-	// Note: slice length must be set to length of v1.1 stats to avoid a panic when
-	// only v1.0 stats are present.
-	// See: https://github.com/prometheus/node_exporter/issues/571.
-	ns := make([]uint64, fieldTransport11TCPLen)
-	for i, s := range ss {
-		n, err := strconv.ParseUint(s, 10, 64)
-		if err != nil {
-			return nil, err
-		}
-
-		ns[i] = n
-	}
-
-	// The fields differ depending on the transport protocol (TCP or UDP)
-	// From https://utcc.utoronto.ca/%7Ecks/space/blog/linux/NFSMountstatsXprt
-	//
-	// For the udp RPC transport there is no connection count, connect idle time,
-	// or idle time (fields #3, #4, and #5); all other fields are the same. So
-	// we set them to 0 here.
-	if protocol == "udp" {
-		ns = append(ns[:2], append(make([]uint64, 3), ns[2:]...)...)
-	}
-
-	return &NFSTransportStats{
-		Protocol:                 protocol,
-		Port:                     ns[0],
-		Bind:                     ns[1],
-		Connect:                  ns[2],
-		ConnectIdleTime:          ns[3],
-		IdleTime:                 time.Duration(ns[4]) * time.Second,
-		Sends:                    ns[5],
-		Receives:                 ns[6],
-		BadTransactionIDs:        ns[7],
-		CumulativeActiveRequests: ns[8],
-		CumulativeBacklog:        ns[9],
-		MaximumRPCSlotsUsed:      ns[10],
-		CumulativeSendingQueue:   ns[11],
-		CumulativePendingQueue:   ns[12],
-	}, nil
-}
diff --git a/vendor/github.com/prometheus/procfs/net_dev.go b/vendor/github.com/prometheus/procfs/net_dev.go
deleted file mode 100644
index 3f25233..0000000
--- a/vendor/github.com/prometheus/procfs/net_dev.go
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"bufio"
-	"errors"
-	"os"
-	"sort"
-	"strconv"
-	"strings"
-)
-
-// NetDevLine is single line parsed from /proc/net/dev or /proc/[pid]/net/dev.
-type NetDevLine struct {
-	Name         string `json:"name"`          // The name of the interface.
-	RxBytes      uint64 `json:"rx_bytes"`      // Cumulative count of bytes received.
-	RxPackets    uint64 `json:"rx_packets"`    // Cumulative count of packets received.
-	RxErrors     uint64 `json:"rx_errors"`     // Cumulative count of receive errors encountered.
-	RxDropped    uint64 `json:"rx_dropped"`    // Cumulative count of packets dropped while receiving.
-	RxFIFO       uint64 `json:"rx_fifo"`       // Cumulative count of FIFO buffer errors.
-	RxFrame      uint64 `json:"rx_frame"`      // Cumulative count of packet framing errors.
-	RxCompressed uint64 `json:"rx_compressed"` // Cumulative count of compressed packets received by the device driver.
-	RxMulticast  uint64 `json:"rx_multicast"`  // Cumulative count of multicast frames received by the device driver.
-	TxBytes      uint64 `json:"tx_bytes"`      // Cumulative count of bytes transmitted.
-	TxPackets    uint64 `json:"tx_packets"`    // Cumulative count of packets transmitted.
-	TxErrors     uint64 `json:"tx_errors"`     // Cumulative count of transmit errors encountered.
-	TxDropped    uint64 `json:"tx_dropped"`    // Cumulative count of packets dropped while transmitting.
-	TxFIFO       uint64 `json:"tx_fifo"`       // Cumulative count of FIFO buffer errors.
-	TxCollisions uint64 `json:"tx_collisions"` // Cumulative count of collisions detected on the interface.
-	TxCarrier    uint64 `json:"tx_carrier"`    // Cumulative count of carrier losses detected by the device driver.
-	TxCompressed uint64 `json:"tx_compressed"` // Cumulative count of compressed packets transmitted by the device driver.
-}
-
-// NetDev is parsed from /proc/net/dev or /proc/[pid]/net/dev. The map keys
-// are interface names.
-type NetDev map[string]NetDevLine
-
-// NewNetDev returns kernel/system statistics read from /proc/net/dev.
-func NewNetDev() (NetDev, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return nil, err
-	}
-
-	return fs.NewNetDev()
-}
-
-// NewNetDev returns kernel/system statistics read from /proc/net/dev.
-func (fs FS) NewNetDev() (NetDev, error) {
-	return newNetDev(fs.Path("net/dev"))
-}
-
-// NewNetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
-func (p Proc) NewNetDev() (NetDev, error) {
-	return newNetDev(p.path("net/dev"))
-}
-
-// newNetDev creates a new NetDev from the contents of the given file.
-func newNetDev(file string) (NetDev, error) {
-	f, err := os.Open(file)
-	if err != nil {
-		return NetDev{}, err
-	}
-	defer f.Close()
-
-	nd := NetDev{}
-	s := bufio.NewScanner(f)
-	for n := 0; s.Scan(); n++ {
-		// Skip the 2 header lines.
-		if n < 2 {
-			continue
-		}
-
-		line, err := nd.parseLine(s.Text())
-		if err != nil {
-			return nd, err
-		}
-
-		nd[line.Name] = *line
-	}
-
-	return nd, s.Err()
-}
-
-// parseLine parses a single line from the /proc/net/dev file. Header lines
-// must be filtered prior to calling this method.
-func (nd NetDev) parseLine(rawLine string) (*NetDevLine, error) {
-	parts := strings.SplitN(rawLine, ":", 2)
-	if len(parts) != 2 {
-		return nil, errors.New("invalid net/dev line, missing colon")
-	}
-	fields := strings.Fields(strings.TrimSpace(parts[1]))
-
-	var err error
-	line := &NetDevLine{}
-
-	// Interface Name
-	line.Name = strings.TrimSpace(parts[0])
-	if line.Name == "" {
-		return nil, errors.New("invalid net/dev line, empty interface name")
-	}
-
-	// RX
-	line.RxBytes, err = strconv.ParseUint(fields[0], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.RxPackets, err = strconv.ParseUint(fields[1], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.RxErrors, err = strconv.ParseUint(fields[2], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.RxDropped, err = strconv.ParseUint(fields[3], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.RxFIFO, err = strconv.ParseUint(fields[4], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.RxFrame, err = strconv.ParseUint(fields[5], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.RxCompressed, err = strconv.ParseUint(fields[6], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.RxMulticast, err = strconv.ParseUint(fields[7], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-
-	// TX
-	line.TxBytes, err = strconv.ParseUint(fields[8], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.TxPackets, err = strconv.ParseUint(fields[9], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.TxErrors, err = strconv.ParseUint(fields[10], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.TxDropped, err = strconv.ParseUint(fields[11], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.TxFIFO, err = strconv.ParseUint(fields[12], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.TxCollisions, err = strconv.ParseUint(fields[13], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.TxCarrier, err = strconv.ParseUint(fields[14], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	line.TxCompressed, err = strconv.ParseUint(fields[15], 10, 64)
-	if err != nil {
-		return nil, err
-	}
-
-	return line, nil
-}
-
-// Total aggregates the values across interfaces and returns a new NetDevLine.
-// The Name field will be a sorted comma separated list of interface names.
-func (nd NetDev) Total() NetDevLine {
-	total := NetDevLine{}
-
-	names := make([]string, 0, len(nd))
-	for _, ifc := range nd {
-		names = append(names, ifc.Name)
-		total.RxBytes += ifc.RxBytes
-		total.RxPackets += ifc.RxPackets
-		total.RxPackets += ifc.RxPackets
-		total.RxErrors += ifc.RxErrors
-		total.RxDropped += ifc.RxDropped
-		total.RxFIFO += ifc.RxFIFO
-		total.RxFrame += ifc.RxFrame
-		total.RxCompressed += ifc.RxCompressed
-		total.RxMulticast += ifc.RxMulticast
-		total.TxBytes += ifc.TxBytes
-		total.TxPackets += ifc.TxPackets
-		total.TxErrors += ifc.TxErrors
-		total.TxDropped += ifc.TxDropped
-		total.TxFIFO += ifc.TxFIFO
-		total.TxCollisions += ifc.TxCollisions
-		total.TxCarrier += ifc.TxCarrier
-		total.TxCompressed += ifc.TxCompressed
-	}
-	sort.Strings(names)
-	total.Name = strings.Join(names, ", ")
-
-	return total
-}
diff --git a/vendor/github.com/prometheus/procfs/nfs/nfs.go b/vendor/github.com/prometheus/procfs/nfs/nfs.go
deleted file mode 100644
index 651bf68..0000000
--- a/vendor/github.com/prometheus/procfs/nfs/nfs.go
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package nfs implements parsing of /proc/net/rpc/nfsd.
-// Fields are documented in https://www.svennd.be/nfsd-stats-explained-procnetrpcnfsd/
-package nfs
-
-// ReplyCache models the "rc" line.
-type ReplyCache struct {
-	Hits    uint64
-	Misses  uint64
-	NoCache uint64
-}
-
-// FileHandles models the "fh" line.
-type FileHandles struct {
-	Stale        uint64
-	TotalLookups uint64
-	AnonLookups  uint64
-	DirNoCache   uint64
-	NoDirNoCache uint64
-}
-
-// InputOutput models the "io" line.
-type InputOutput struct {
-	Read  uint64
-	Write uint64
-}
-
-// Threads models the "th" line.
-type Threads struct {
-	Threads uint64
-	FullCnt uint64
-}
-
-// ReadAheadCache models the "ra" line.
-type ReadAheadCache struct {
-	CacheSize      uint64
-	CacheHistogram []uint64
-	NotFound       uint64
-}
-
-// Network models the "net" line.
-type Network struct {
-	NetCount   uint64
-	UDPCount   uint64
-	TCPCount   uint64
-	TCPConnect uint64
-}
-
-// ClientRPC models the nfs "rpc" line.
-type ClientRPC struct {
-	RPCCount        uint64
-	Retransmissions uint64
-	AuthRefreshes   uint64
-}
-
-// ServerRPC models the nfsd "rpc" line.
-type ServerRPC struct {
-	RPCCount uint64
-	BadCnt   uint64
-	BadFmt   uint64
-	BadAuth  uint64
-	BadcInt  uint64
-}
-
-// V2Stats models the "proc2" line.
-type V2Stats struct {
-	Null     uint64
-	GetAttr  uint64
-	SetAttr  uint64
-	Root     uint64
-	Lookup   uint64
-	ReadLink uint64
-	Read     uint64
-	WrCache  uint64
-	Write    uint64
-	Create   uint64
-	Remove   uint64
-	Rename   uint64
-	Link     uint64
-	SymLink  uint64
-	MkDir    uint64
-	RmDir    uint64
-	ReadDir  uint64
-	FsStat   uint64
-}
-
-// V3Stats models the "proc3" line.
-type V3Stats struct {
-	Null        uint64
-	GetAttr     uint64
-	SetAttr     uint64
-	Lookup      uint64
-	Access      uint64
-	ReadLink    uint64
-	Read        uint64
-	Write       uint64
-	Create      uint64
-	MkDir       uint64
-	SymLink     uint64
-	MkNod       uint64
-	Remove      uint64
-	RmDir       uint64
-	Rename      uint64
-	Link        uint64
-	ReadDir     uint64
-	ReadDirPlus uint64
-	FsStat      uint64
-	FsInfo      uint64
-	PathConf    uint64
-	Commit      uint64
-}
-
-// ClientV4Stats models the nfs "proc4" line.
-type ClientV4Stats struct {
-	Null               uint64
-	Read               uint64
-	Write              uint64
-	Commit             uint64
-	Open               uint64
-	OpenConfirm        uint64
-	OpenNoattr         uint64
-	OpenDowngrade      uint64
-	Close              uint64
-	Setattr            uint64
-	FsInfo             uint64
-	Renew              uint64
-	SetClientID        uint64
-	SetClientIDConfirm uint64
-	Lock               uint64
-	Lockt              uint64
-	Locku              uint64
-	Access             uint64
-	Getattr            uint64
-	Lookup             uint64
-	LookupRoot         uint64
-	Remove             uint64
-	Rename             uint64
-	Link               uint64
-	Symlink            uint64
-	Create             uint64
-	Pathconf           uint64
-	StatFs             uint64
-	ReadLink           uint64
-	ReadDir            uint64
-	ServerCaps         uint64
-	DelegReturn        uint64
-	GetACL             uint64
-	SetACL             uint64
-	FsLocations        uint64
-	ReleaseLockowner   uint64
-	Secinfo            uint64
-	FsidPresent        uint64
-	ExchangeID         uint64
-	CreateSession      uint64
-	DestroySession     uint64
-	Sequence           uint64
-	GetLeaseTime       uint64
-	ReclaimComplete    uint64
-	LayoutGet          uint64
-	GetDeviceInfo      uint64
-	LayoutCommit       uint64
-	LayoutReturn       uint64
-	SecinfoNoName      uint64
-	TestStateID        uint64
-	FreeStateID        uint64
-	GetDeviceList      uint64
-	BindConnToSession  uint64
-	DestroyClientID    uint64
-	Seek               uint64
-	Allocate           uint64
-	DeAllocate         uint64
-	LayoutStats        uint64
-	Clone              uint64
-}
-
-// ServerV4Stats models the nfsd "proc4" line.
-type ServerV4Stats struct {
-	Null     uint64
-	Compound uint64
-}
-
-// V4Ops models the "proc4ops" line: NFSv4 operations
-// Variable list, see:
-// v4.0 https://tools.ietf.org/html/rfc3010 (38 operations)
-// v4.1 https://tools.ietf.org/html/rfc5661 (58 operations)
-// v4.2 https://tools.ietf.org/html/draft-ietf-nfsv4-minorversion2-41 (71 operations)
-type V4Ops struct {
-	//Values       uint64 // Variable depending on v4.x sub-version. TODO: Will this always at least include the fields in this struct?
-	Op0Unused    uint64
-	Op1Unused    uint64
-	Op2Future    uint64
-	Access       uint64
-	Close        uint64
-	Commit       uint64
-	Create       uint64
-	DelegPurge   uint64
-	DelegReturn  uint64
-	GetAttr      uint64
-	GetFH        uint64
-	Link         uint64
-	Lock         uint64
-	Lockt        uint64
-	Locku        uint64
-	Lookup       uint64
-	LookupRoot   uint64
-	Nverify      uint64
-	Open         uint64
-	OpenAttr     uint64
-	OpenConfirm  uint64
-	OpenDgrd     uint64
-	PutFH        uint64
-	PutPubFH     uint64
-	PutRootFH    uint64
-	Read         uint64
-	ReadDir      uint64
-	ReadLink     uint64
-	Remove       uint64
-	Rename       uint64
-	Renew        uint64
-	RestoreFH    uint64
-	SaveFH       uint64
-	SecInfo      uint64
-	SetAttr      uint64
-	Verify       uint64
-	Write        uint64
-	RelLockOwner uint64
-}
-
-// ClientRPCStats models all stats from /proc/net/rpc/nfs.
-type ClientRPCStats struct {
-	Network       Network
-	ClientRPC     ClientRPC
-	V2Stats       V2Stats
-	V3Stats       V3Stats
-	ClientV4Stats ClientV4Stats
-}
-
-// ServerRPCStats models all stats from /proc/net/rpc/nfsd.
-type ServerRPCStats struct {
-	ReplyCache     ReplyCache
-	FileHandles    FileHandles
-	InputOutput    InputOutput
-	Threads        Threads
-	ReadAheadCache ReadAheadCache
-	Network        Network
-	ServerRPC      ServerRPC
-	V2Stats        V2Stats
-	V3Stats        V3Stats
-	ServerV4Stats  ServerV4Stats
-	V4Ops          V4Ops
-}
diff --git a/vendor/github.com/prometheus/procfs/nfs/parse.go b/vendor/github.com/prometheus/procfs/nfs/parse.go
deleted file mode 100644
index 95a83cc..0000000
--- a/vendor/github.com/prometheus/procfs/nfs/parse.go
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package nfs
-
-import (
-	"fmt"
-)
-
-func parseReplyCache(v []uint64) (ReplyCache, error) {
-	if len(v) != 3 {
-		return ReplyCache{}, fmt.Errorf("invalid ReplyCache line %q", v)
-	}
-
-	return ReplyCache{
-		Hits:    v[0],
-		Misses:  v[1],
-		NoCache: v[2],
-	}, nil
-}
-
-func parseFileHandles(v []uint64) (FileHandles, error) {
-	if len(v) != 5 {
-		return FileHandles{}, fmt.Errorf("invalid FileHandles, line %q", v)
-	}
-
-	return FileHandles{
-		Stale:        v[0],
-		TotalLookups: v[1],
-		AnonLookups:  v[2],
-		DirNoCache:   v[3],
-		NoDirNoCache: v[4],
-	}, nil
-}
-
-func parseInputOutput(v []uint64) (InputOutput, error) {
-	if len(v) != 2 {
-		return InputOutput{}, fmt.Errorf("invalid InputOutput line %q", v)
-	}
-
-	return InputOutput{
-		Read:  v[0],
-		Write: v[1],
-	}, nil
-}
-
-func parseThreads(v []uint64) (Threads, error) {
-	if len(v) != 2 {
-		return Threads{}, fmt.Errorf("invalid Threads line %q", v)
-	}
-
-	return Threads{
-		Threads: v[0],
-		FullCnt: v[1],
-	}, nil
-}
-
-func parseReadAheadCache(v []uint64) (ReadAheadCache, error) {
-	if len(v) != 12 {
-		return ReadAheadCache{}, fmt.Errorf("invalid ReadAheadCache line %q", v)
-	}
-
-	return ReadAheadCache{
-		CacheSize:      v[0],
-		CacheHistogram: v[1:11],
-		NotFound:       v[11],
-	}, nil
-}
-
-func parseNetwork(v []uint64) (Network, error) {
-	if len(v) != 4 {
-		return Network{}, fmt.Errorf("invalid Network line %q", v)
-	}
-
-	return Network{
-		NetCount:   v[0],
-		UDPCount:   v[1],
-		TCPCount:   v[2],
-		TCPConnect: v[3],
-	}, nil
-}
-
-func parseServerRPC(v []uint64) (ServerRPC, error) {
-	if len(v) != 5 {
-		return ServerRPC{}, fmt.Errorf("invalid RPC line %q", v)
-	}
-
-	return ServerRPC{
-		RPCCount: v[0],
-		BadCnt:   v[1],
-		BadFmt:   v[2],
-		BadAuth:  v[3],
-		BadcInt:  v[4],
-	}, nil
-}
-
-func parseClientRPC(v []uint64) (ClientRPC, error) {
-	if len(v) != 3 {
-		return ClientRPC{}, fmt.Errorf("invalid RPC line %q", v)
-	}
-
-	return ClientRPC{
-		RPCCount:        v[0],
-		Retransmissions: v[1],
-		AuthRefreshes:   v[2],
-	}, nil
-}
-
-func parseV2Stats(v []uint64) (V2Stats, error) {
-	values := int(v[0])
-	if len(v[1:]) != values || values != 18 {
-		return V2Stats{}, fmt.Errorf("invalid V2Stats line %q", v)
-	}
-
-	return V2Stats{
-		Null:     v[1],
-		GetAttr:  v[2],
-		SetAttr:  v[3],
-		Root:     v[4],
-		Lookup:   v[5],
-		ReadLink: v[6],
-		Read:     v[7],
-		WrCache:  v[8],
-		Write:    v[9],
-		Create:   v[10],
-		Remove:   v[11],
-		Rename:   v[12],
-		Link:     v[13],
-		SymLink:  v[14],
-		MkDir:    v[15],
-		RmDir:    v[16],
-		ReadDir:  v[17],
-		FsStat:   v[18],
-	}, nil
-}
-
-func parseV3Stats(v []uint64) (V3Stats, error) {
-	values := int(v[0])
-	if len(v[1:]) != values || values != 22 {
-		return V3Stats{}, fmt.Errorf("invalid V3Stats line %q", v)
-	}
-
-	return V3Stats{
-		Null:        v[1],
-		GetAttr:     v[2],
-		SetAttr:     v[3],
-		Lookup:      v[4],
-		Access:      v[5],
-		ReadLink:    v[6],
-		Read:        v[7],
-		Write:       v[8],
-		Create:      v[9],
-		MkDir:       v[10],
-		SymLink:     v[11],
-		MkNod:       v[12],
-		Remove:      v[13],
-		RmDir:       v[14],
-		Rename:      v[15],
-		Link:        v[16],
-		ReadDir:     v[17],
-		ReadDirPlus: v[18],
-		FsStat:      v[19],
-		FsInfo:      v[20],
-		PathConf:    v[21],
-		Commit:      v[22],
-	}, nil
-}
-
-func parseClientV4Stats(v []uint64) (ClientV4Stats, error) {
-	values := int(v[0])
-	if len(v[1:]) != values {
-		return ClientV4Stats{}, fmt.Errorf("invalid ClientV4Stats line %q", v)
-	}
-
-	// This function currently supports mapping 59 NFS v4 client stats.  Older
-	// kernels may emit fewer stats, so we must detect this and pad out the
-	// values to match the expected slice size.
-	if values < 59 {
-		newValues := make([]uint64, 60)
-		copy(newValues, v)
-		v = newValues
-	}
-
-	return ClientV4Stats{
-		Null:               v[1],
-		Read:               v[2],
-		Write:              v[3],
-		Commit:             v[4],
-		Open:               v[5],
-		OpenConfirm:        v[6],
-		OpenNoattr:         v[7],
-		OpenDowngrade:      v[8],
-		Close:              v[9],
-		Setattr:            v[10],
-		FsInfo:             v[11],
-		Renew:              v[12],
-		SetClientID:        v[13],
-		SetClientIDConfirm: v[14],
-		Lock:               v[15],
-		Lockt:              v[16],
-		Locku:              v[17],
-		Access:             v[18],
-		Getattr:            v[19],
-		Lookup:             v[20],
-		LookupRoot:         v[21],
-		Remove:             v[22],
-		Rename:             v[23],
-		Link:               v[24],
-		Symlink:            v[25],
-		Create:             v[26],
-		Pathconf:           v[27],
-		StatFs:             v[28],
-		ReadLink:           v[29],
-		ReadDir:            v[30],
-		ServerCaps:         v[31],
-		DelegReturn:        v[32],
-		GetACL:             v[33],
-		SetACL:             v[34],
-		FsLocations:        v[35],
-		ReleaseLockowner:   v[36],
-		Secinfo:            v[37],
-		FsidPresent:        v[38],
-		ExchangeID:         v[39],
-		CreateSession:      v[40],
-		DestroySession:     v[41],
-		Sequence:           v[42],
-		GetLeaseTime:       v[43],
-		ReclaimComplete:    v[44],
-		LayoutGet:          v[45],
-		GetDeviceInfo:      v[46],
-		LayoutCommit:       v[47],
-		LayoutReturn:       v[48],
-		SecinfoNoName:      v[49],
-		TestStateID:        v[50],
-		FreeStateID:        v[51],
-		GetDeviceList:      v[52],
-		BindConnToSession:  v[53],
-		DestroyClientID:    v[54],
-		Seek:               v[55],
-		Allocate:           v[56],
-		DeAllocate:         v[57],
-		LayoutStats:        v[58],
-		Clone:              v[59],
-	}, nil
-}
-
-func parseServerV4Stats(v []uint64) (ServerV4Stats, error) {
-	values := int(v[0])
-	if len(v[1:]) != values || values != 2 {
-		return ServerV4Stats{}, fmt.Errorf("invalid V4Stats line %q", v)
-	}
-
-	return ServerV4Stats{
-		Null:     v[1],
-		Compound: v[2],
-	}, nil
-}
-
-func parseV4Ops(v []uint64) (V4Ops, error) {
-	values := int(v[0])
-	if len(v[1:]) != values || values < 39 {
-		return V4Ops{}, fmt.Errorf("invalid V4Ops line %q", v)
-	}
-
-	stats := V4Ops{
-		Op0Unused:    v[1],
-		Op1Unused:    v[2],
-		Op2Future:    v[3],
-		Access:       v[4],
-		Close:        v[5],
-		Commit:       v[6],
-		Create:       v[7],
-		DelegPurge:   v[8],
-		DelegReturn:  v[9],
-		GetAttr:      v[10],
-		GetFH:        v[11],
-		Link:         v[12],
-		Lock:         v[13],
-		Lockt:        v[14],
-		Locku:        v[15],
-		Lookup:       v[16],
-		LookupRoot:   v[17],
-		Nverify:      v[18],
-		Open:         v[19],
-		OpenAttr:     v[20],
-		OpenConfirm:  v[21],
-		OpenDgrd:     v[22],
-		PutFH:        v[23],
-		PutPubFH:     v[24],
-		PutRootFH:    v[25],
-		Read:         v[26],
-		ReadDir:      v[27],
-		ReadLink:     v[28],
-		Remove:       v[29],
-		Rename:       v[30],
-		Renew:        v[31],
-		RestoreFH:    v[32],
-		SaveFH:       v[33],
-		SecInfo:      v[34],
-		SetAttr:      v[35],
-		Verify:       v[36],
-		Write:        v[37],
-		RelLockOwner: v[38],
-	}
-
-	return stats, nil
-}
diff --git a/vendor/github.com/prometheus/procfs/nfs/parse_nfs.go b/vendor/github.com/prometheus/procfs/nfs/parse_nfs.go
deleted file mode 100644
index c0d3a5a..0000000
--- a/vendor/github.com/prometheus/procfs/nfs/parse_nfs.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package nfs
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"strings"
-
-	"github.com/prometheus/procfs/internal/util"
-)
-
-// ParseClientRPCStats returns stats read from /proc/net/rpc/nfs
-func ParseClientRPCStats(r io.Reader) (*ClientRPCStats, error) {
-	stats := &ClientRPCStats{}
-
-	scanner := bufio.NewScanner(r)
-	for scanner.Scan() {
-		line := scanner.Text()
-		parts := strings.Fields(scanner.Text())
-		// require at least <key> <value>
-		if len(parts) < 2 {
-			return nil, fmt.Errorf("invalid NFS metric line %q", line)
-		}
-
-		values, err := util.ParseUint64s(parts[1:])
-		if err != nil {
-			return nil, fmt.Errorf("error parsing NFS metric line: %s", err)
-		}
-
-		switch metricLine := parts[0]; metricLine {
-		case "net":
-			stats.Network, err = parseNetwork(values)
-		case "rpc":
-			stats.ClientRPC, err = parseClientRPC(values)
-		case "proc2":
-			stats.V2Stats, err = parseV2Stats(values)
-		case "proc3":
-			stats.V3Stats, err = parseV3Stats(values)
-		case "proc4":
-			stats.ClientV4Stats, err = parseClientV4Stats(values)
-		default:
-			return nil, fmt.Errorf("unknown NFS metric line %q", metricLine)
-		}
-		if err != nil {
-			return nil, fmt.Errorf("errors parsing NFS metric line: %s", err)
-		}
-	}
-
-	if err := scanner.Err(); err != nil {
-		return nil, fmt.Errorf("error scanning NFS file: %s", err)
-	}
-
-	return stats, nil
-}
diff --git a/vendor/github.com/prometheus/procfs/nfs/parse_nfsd.go b/vendor/github.com/prometheus/procfs/nfs/parse_nfsd.go
deleted file mode 100644
index 57bb4a3..0000000
--- a/vendor/github.com/prometheus/procfs/nfs/parse_nfsd.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package nfs
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"strings"
-
-	"github.com/prometheus/procfs/internal/util"
-)
-
-// ParseServerRPCStats returns stats read from /proc/net/rpc/nfsd
-func ParseServerRPCStats(r io.Reader) (*ServerRPCStats, error) {
-	stats := &ServerRPCStats{}
-
-	scanner := bufio.NewScanner(r)
-	for scanner.Scan() {
-		line := scanner.Text()
-		parts := strings.Fields(scanner.Text())
-		// require at least <key> <value>
-		if len(parts) < 2 {
-			return nil, fmt.Errorf("invalid NFSd metric line %q", line)
-		}
-		label := parts[0]
-
-		var values []uint64
-		var err error
-		if label == "th" {
-			if len(parts) < 3 {
-				return nil, fmt.Errorf("invalid NFSd th metric line %q", line)
-			}
-			values, err = util.ParseUint64s(parts[1:3])
-		} else {
-			values, err = util.ParseUint64s(parts[1:])
-		}
-		if err != nil {
-			return nil, fmt.Errorf("error parsing NFSd metric line: %s", err)
-		}
-
-		switch metricLine := parts[0]; metricLine {
-		case "rc":
-			stats.ReplyCache, err = parseReplyCache(values)
-		case "fh":
-			stats.FileHandles, err = parseFileHandles(values)
-		case "io":
-			stats.InputOutput, err = parseInputOutput(values)
-		case "th":
-			stats.Threads, err = parseThreads(values)
-		case "ra":
-			stats.ReadAheadCache, err = parseReadAheadCache(values)
-		case "net":
-			stats.Network, err = parseNetwork(values)
-		case "rpc":
-			stats.ServerRPC, err = parseServerRPC(values)
-		case "proc2":
-			stats.V2Stats, err = parseV2Stats(values)
-		case "proc3":
-			stats.V3Stats, err = parseV3Stats(values)
-		case "proc4":
-			stats.ServerV4Stats, err = parseServerV4Stats(values)
-		case "proc4ops":
-			stats.V4Ops, err = parseV4Ops(values)
-		default:
-			return nil, fmt.Errorf("unknown NFSd metric line %q", metricLine)
-		}
-		if err != nil {
-			return nil, fmt.Errorf("errors parsing NFSd metric line: %s", err)
-		}
-	}
-
-	if err := scanner.Err(); err != nil {
-		return nil, fmt.Errorf("error scanning NFSd file: %s", err)
-	}
-
-	return stats, nil
-}
diff --git a/vendor/github.com/prometheus/procfs/proc.go b/vendor/github.com/prometheus/procfs/proc.go
deleted file mode 100644
index 06bed0e..0000000
--- a/vendor/github.com/prometheus/procfs/proc.go
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"bytes"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"strconv"
-	"strings"
-)
-
-// Proc provides information about a running process.
-type Proc struct {
-	// The process ID.
-	PID int
-
-	fs FS
-}
-
-// Procs represents a list of Proc structs.
-type Procs []Proc
-
-func (p Procs) Len() int           { return len(p) }
-func (p Procs) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-func (p Procs) Less(i, j int) bool { return p[i].PID < p[j].PID }
-
-// Self returns a process for the current process read via /proc/self.
-func Self() (Proc, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return Proc{}, err
-	}
-	return fs.Self()
-}
-
-// NewProc returns a process for the given pid under /proc.
-func NewProc(pid int) (Proc, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return Proc{}, err
-	}
-	return fs.NewProc(pid)
-}
-
-// AllProcs returns a list of all currently available processes under /proc.
-func AllProcs() (Procs, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return Procs{}, err
-	}
-	return fs.AllProcs()
-}
-
-// Self returns a process for the current process.
-func (fs FS) Self() (Proc, error) {
-	p, err := os.Readlink(fs.Path("self"))
-	if err != nil {
-		return Proc{}, err
-	}
-	pid, err := strconv.Atoi(strings.Replace(p, string(fs), "", -1))
-	if err != nil {
-		return Proc{}, err
-	}
-	return fs.NewProc(pid)
-}
-
-// NewProc returns a process for the given pid.
-func (fs FS) NewProc(pid int) (Proc, error) {
-	if _, err := os.Stat(fs.Path(strconv.Itoa(pid))); err != nil {
-		return Proc{}, err
-	}
-	return Proc{PID: pid, fs: fs}, nil
-}
-
-// AllProcs returns a list of all currently available processes.
-func (fs FS) AllProcs() (Procs, error) {
-	d, err := os.Open(fs.Path())
-	if err != nil {
-		return Procs{}, err
-	}
-	defer d.Close()
-
-	names, err := d.Readdirnames(-1)
-	if err != nil {
-		return Procs{}, fmt.Errorf("could not read %s: %s", d.Name(), err)
-	}
-
-	p := Procs{}
-	for _, n := range names {
-		pid, err := strconv.ParseInt(n, 10, 64)
-		if err != nil {
-			continue
-		}
-		p = append(p, Proc{PID: int(pid), fs: fs})
-	}
-
-	return p, nil
-}
-
-// CmdLine returns the command line of a process.
-func (p Proc) CmdLine() ([]string, error) {
-	f, err := os.Open(p.path("cmdline"))
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-
-	data, err := ioutil.ReadAll(f)
-	if err != nil {
-		return nil, err
-	}
-
-	if len(data) < 1 {
-		return []string{}, nil
-	}
-
-	return strings.Split(string(bytes.TrimRight(data, string("\x00"))), string(byte(0))), nil
-}
-
-// Comm returns the command name of a process.
-func (p Proc) Comm() (string, error) {
-	f, err := os.Open(p.path("comm"))
-	if err != nil {
-		return "", err
-	}
-	defer f.Close()
-
-	data, err := ioutil.ReadAll(f)
-	if err != nil {
-		return "", err
-	}
-
-	return strings.TrimSpace(string(data)), nil
-}
-
-// Executable returns the absolute path of the executable command of a process.
-func (p Proc) Executable() (string, error) {
-	exe, err := os.Readlink(p.path("exe"))
-	if os.IsNotExist(err) {
-		return "", nil
-	}
-
-	return exe, err
-}
-
-// Cwd returns the absolute path to the current working directory of the process.
-func (p Proc) Cwd() (string, error) {
-	wd, err := os.Readlink(p.path("cwd"))
-	if os.IsNotExist(err) {
-		return "", nil
-	}
-
-	return wd, err
-}
-
-// RootDir returns the absolute path to the process's root directory (as set by chroot)
-func (p Proc) RootDir() (string, error) {
-	rdir, err := os.Readlink(p.path("root"))
-	if os.IsNotExist(err) {
-		return "", nil
-	}
-
-	return rdir, err
-}
-
-// FileDescriptors returns the currently open file descriptors of a process.
-func (p Proc) FileDescriptors() ([]uintptr, error) {
-	names, err := p.fileDescriptors()
-	if err != nil {
-		return nil, err
-	}
-
-	fds := make([]uintptr, len(names))
-	for i, n := range names {
-		fd, err := strconv.ParseInt(n, 10, 32)
-		if err != nil {
-			return nil, fmt.Errorf("could not parse fd %s: %s", n, err)
-		}
-		fds[i] = uintptr(fd)
-	}
-
-	return fds, nil
-}
-
-// FileDescriptorTargets returns the targets of all file descriptors of a process.
-// If a file descriptor is not a symlink to a file (like a socket), that value will be the empty string.
-func (p Proc) FileDescriptorTargets() ([]string, error) {
-	names, err := p.fileDescriptors()
-	if err != nil {
-		return nil, err
-	}
-
-	targets := make([]string, len(names))
-
-	for i, name := range names {
-		target, err := os.Readlink(p.path("fd", name))
-		if err == nil {
-			targets[i] = target
-		}
-	}
-
-	return targets, nil
-}
-
-// FileDescriptorsLen returns the number of currently open file descriptors of
-// a process.
-func (p Proc) FileDescriptorsLen() (int, error) {
-	fds, err := p.fileDescriptors()
-	if err != nil {
-		return 0, err
-	}
-
-	return len(fds), nil
-}
-
-// MountStats retrieves statistics and configuration for mount points in a
-// process's namespace.
-func (p Proc) MountStats() ([]*Mount, error) {
-	f, err := os.Open(p.path("mountstats"))
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-
-	return parseMountStats(f)
-}
-
-func (p Proc) fileDescriptors() ([]string, error) {
-	d, err := os.Open(p.path("fd"))
-	if err != nil {
-		return nil, err
-	}
-	defer d.Close()
-
-	names, err := d.Readdirnames(-1)
-	if err != nil {
-		return nil, fmt.Errorf("could not read %s: %s", d.Name(), err)
-	}
-
-	return names, nil
-}
-
-func (p Proc) path(pa ...string) string {
-	return p.fs.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...)
-}
diff --git a/vendor/github.com/prometheus/procfs/proc_io.go b/vendor/github.com/prometheus/procfs/proc_io.go
deleted file mode 100644
index 0251c83..0000000
--- a/vendor/github.com/prometheus/procfs/proc_io.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-)
-
-// ProcIO models the content of /proc/<pid>/io.
-type ProcIO struct {
-	// Chars read.
-	RChar uint64
-	// Chars written.
-	WChar uint64
-	// Read syscalls.
-	SyscR uint64
-	// Write syscalls.
-	SyscW uint64
-	// Bytes read.
-	ReadBytes uint64
-	// Bytes written.
-	WriteBytes uint64
-	// Bytes written, but taking into account truncation. See
-	// Documentation/filesystems/proc.txt in the kernel sources for
-	// detailed explanation.
-	CancelledWriteBytes int64
-}
-
-// NewIO creates a new ProcIO instance from a given Proc instance.
-func (p Proc) NewIO() (ProcIO, error) {
-	pio := ProcIO{}
-
-	f, err := os.Open(p.path("io"))
-	if err != nil {
-		return pio, err
-	}
-	defer f.Close()
-
-	data, err := ioutil.ReadAll(f)
-	if err != nil {
-		return pio, err
-	}
-
-	ioFormat := "rchar: %d\nwchar: %d\nsyscr: %d\nsyscw: %d\n" +
-		"read_bytes: %d\nwrite_bytes: %d\n" +
-		"cancelled_write_bytes: %d\n"
-
-	_, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR,
-		&pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes)
-
-	return pio, err
-}
diff --git a/vendor/github.com/prometheus/procfs/proc_limits.go b/vendor/github.com/prometheus/procfs/proc_limits.go
deleted file mode 100644
index f04ba6f..0000000
--- a/vendor/github.com/prometheus/procfs/proc_limits.go
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"bufio"
-	"fmt"
-	"os"
-	"regexp"
-	"strconv"
-)
-
-// ProcLimits represents the soft limits for each of the process's resource
-// limits. For more information see getrlimit(2):
-// http://man7.org/linux/man-pages/man2/getrlimit.2.html.
-type ProcLimits struct {
-	// CPU time limit in seconds.
-	CPUTime int64
-	// Maximum size of files that the process may create.
-	FileSize int64
-	// Maximum size of the process's data segment (initialized data,
-	// uninitialized data, and heap).
-	DataSize int64
-	// Maximum size of the process stack in bytes.
-	StackSize int64
-	// Maximum size of a core file.
-	CoreFileSize int64
-	// Limit of the process's resident set in pages.
-	ResidentSet int64
-	// Maximum number of processes that can be created for the real user ID of
-	// the calling process.
-	Processes int64
-	// Value one greater than the maximum file descriptor number that can be
-	// opened by this process.
-	OpenFiles int64
-	// Maximum number of bytes of memory that may be locked into RAM.
-	LockedMemory int64
-	// Maximum size of the process's virtual memory address space in bytes.
-	AddressSpace int64
-	// Limit on the combined number of flock(2) locks and fcntl(2) leases that
-	// this process may establish.
-	FileLocks int64
-	// Limit of signals that may be queued for the real user ID of the calling
-	// process.
-	PendingSignals int64
-	// Limit on the number of bytes that can be allocated for POSIX message
-	// queues for the real user ID of the calling process.
-	MsqqueueSize int64
-	// Limit of the nice priority set using setpriority(2) or nice(2).
-	NicePriority int64
-	// Limit of the real-time priority set using sched_setscheduler(2) or
-	// sched_setparam(2).
-	RealtimePriority int64
-	// Limit (in microseconds) on the amount of CPU time that a process
-	// scheduled under a real-time scheduling policy may consume without making
-	// a blocking system call.
-	RealtimeTimeout int64
-}
-
-const (
-	limitsFields    = 3
-	limitsUnlimited = "unlimited"
-)
-
-var (
-	limitsDelimiter = regexp.MustCompile("  +")
-)
-
-// NewLimits returns the current soft limits of the process.
-func (p Proc) NewLimits() (ProcLimits, error) {
-	f, err := os.Open(p.path("limits"))
-	if err != nil {
-		return ProcLimits{}, err
-	}
-	defer f.Close()
-
-	var (
-		l = ProcLimits{}
-		s = bufio.NewScanner(f)
-	)
-	for s.Scan() {
-		fields := limitsDelimiter.Split(s.Text(), limitsFields)
-		if len(fields) != limitsFields {
-			return ProcLimits{}, fmt.Errorf(
-				"couldn't parse %s line %s", f.Name(), s.Text())
-		}
-
-		switch fields[0] {
-		case "Max cpu time":
-			l.CPUTime, err = parseInt(fields[1])
-		case "Max file size":
-			l.FileSize, err = parseInt(fields[1])
-		case "Max data size":
-			l.DataSize, err = parseInt(fields[1])
-		case "Max stack size":
-			l.StackSize, err = parseInt(fields[1])
-		case "Max core file size":
-			l.CoreFileSize, err = parseInt(fields[1])
-		case "Max resident set":
-			l.ResidentSet, err = parseInt(fields[1])
-		case "Max processes":
-			l.Processes, err = parseInt(fields[1])
-		case "Max open files":
-			l.OpenFiles, err = parseInt(fields[1])
-		case "Max locked memory":
-			l.LockedMemory, err = parseInt(fields[1])
-		case "Max address space":
-			l.AddressSpace, err = parseInt(fields[1])
-		case "Max file locks":
-			l.FileLocks, err = parseInt(fields[1])
-		case "Max pending signals":
-			l.PendingSignals, err = parseInt(fields[1])
-		case "Max msgqueue size":
-			l.MsqqueueSize, err = parseInt(fields[1])
-		case "Max nice priority":
-			l.NicePriority, err = parseInt(fields[1])
-		case "Max realtime priority":
-			l.RealtimePriority, err = parseInt(fields[1])
-		case "Max realtime timeout":
-			l.RealtimeTimeout, err = parseInt(fields[1])
-		}
-		if err != nil {
-			return ProcLimits{}, err
-		}
-	}
-
-	return l, s.Err()
-}
-
-func parseInt(s string) (int64, error) {
-	if s == limitsUnlimited {
-		return -1, nil
-	}
-	i, err := strconv.ParseInt(s, 10, 64)
-	if err != nil {
-		return 0, fmt.Errorf("couldn't parse value %s: %s", s, err)
-	}
-	return i, nil
-}
diff --git a/vendor/github.com/prometheus/procfs/proc_ns.go b/vendor/github.com/prometheus/procfs/proc_ns.go
deleted file mode 100644
index d06c26e..0000000
--- a/vendor/github.com/prometheus/procfs/proc_ns.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"fmt"
-	"os"
-	"strconv"
-	"strings"
-)
-
-// Namespace represents a single namespace of a process.
-type Namespace struct {
-	Type  string // Namespace type.
-	Inode uint32 // Inode number of the namespace. If two processes are in the same namespace their inodes will match.
-}
-
-// Namespaces contains all of the namespaces that the process is contained in.
-type Namespaces map[string]Namespace
-
-// NewNamespaces reads from /proc/[pid/ns/* to get the namespaces of which the
-// process is a member.
-func (p Proc) NewNamespaces() (Namespaces, error) {
-	d, err := os.Open(p.path("ns"))
-	if err != nil {
-		return nil, err
-	}
-	defer d.Close()
-
-	names, err := d.Readdirnames(-1)
-	if err != nil {
-		return nil, fmt.Errorf("failed to read contents of ns dir: %v", err)
-	}
-
-	ns := make(Namespaces, len(names))
-	for _, name := range names {
-		target, err := os.Readlink(p.path("ns", name))
-		if err != nil {
-			return nil, err
-		}
-
-		fields := strings.SplitN(target, ":", 2)
-		if len(fields) != 2 {
-			return nil, fmt.Errorf("failed to parse namespace type and inode from '%v'", target)
-		}
-
-		typ := fields[0]
-		inode, err := strconv.ParseUint(strings.Trim(fields[1], "[]"), 10, 32)
-		if err != nil {
-			return nil, fmt.Errorf("failed to parse inode from '%v': %v", fields[1], err)
-		}
-
-		ns[name] = Namespace{typ, uint32(inode)}
-	}
-
-	return ns, nil
-}
diff --git a/vendor/github.com/prometheus/procfs/proc_stat.go b/vendor/github.com/prometheus/procfs/proc_stat.go
deleted file mode 100644
index 3cf2a9f..0000000
--- a/vendor/github.com/prometheus/procfs/proc_stat.go
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"bytes"
-	"fmt"
-	"io/ioutil"
-	"os"
-)
-
-// Originally, this USER_HZ value was dynamically retrieved via a sysconf call
-// which required cgo. However, that caused a lot of problems regarding
-// cross-compilation. Alternatives such as running a binary to determine the
-// value, or trying to derive it in some other way were all problematic.  After
-// much research it was determined that USER_HZ is actually hardcoded to 100 on
-// all Go-supported platforms as of the time of this writing. This is why we
-// decided to hardcode it here as well. It is not impossible that there could
-// be systems with exceptions, but they should be very exotic edge cases, and
-// in that case, the worst outcome will be two misreported metrics.
-//
-// See also the following discussions:
-//
-// - https://github.com/prometheus/node_exporter/issues/52
-// - https://github.com/prometheus/procfs/pull/2
-// - http://stackoverflow.com/questions/17410841/how-does-user-hz-solve-the-jiffy-scaling-issue
-const userHZ = 100
-
-// ProcStat provides status information about the process,
-// read from /proc/[pid]/stat.
-type ProcStat struct {
-	// The process ID.
-	PID int
-	// The filename of the executable.
-	Comm string
-	// The process state.
-	State string
-	// The PID of the parent of this process.
-	PPID int
-	// The process group ID of the process.
-	PGRP int
-	// The session ID of the process.
-	Session int
-	// The controlling terminal of the process.
-	TTY int
-	// The ID of the foreground process group of the controlling terminal of
-	// the process.
-	TPGID int
-	// The kernel flags word of the process.
-	Flags uint
-	// The number of minor faults the process has made which have not required
-	// loading a memory page from disk.
-	MinFlt uint
-	// The number of minor faults that the process's waited-for children have
-	// made.
-	CMinFlt uint
-	// The number of major faults the process has made which have required
-	// loading a memory page from disk.
-	MajFlt uint
-	// The number of major faults that the process's waited-for children have
-	// made.
-	CMajFlt uint
-	// Amount of time that this process has been scheduled in user mode,
-	// measured in clock ticks.
-	UTime uint
-	// Amount of time that this process has been scheduled in kernel mode,
-	// measured in clock ticks.
-	STime uint
-	// Amount of time that this process's waited-for children have been
-	// scheduled in user mode, measured in clock ticks.
-	CUTime uint
-	// Amount of time that this process's waited-for children have been
-	// scheduled in kernel mode, measured in clock ticks.
-	CSTime uint
-	// For processes running a real-time scheduling policy, this is the negated
-	// scheduling priority, minus one.
-	Priority int
-	// The nice value, a value in the range 19 (low priority) to -20 (high
-	// priority).
-	Nice int
-	// Number of threads in this process.
-	NumThreads int
-	// The time the process started after system boot, the value is expressed
-	// in clock ticks.
-	Starttime uint64
-	// Virtual memory size in bytes.
-	VSize int
-	// Resident set size in pages.
-	RSS int
-
-	fs FS
-}
-
-// NewStat returns the current status information of the process.
-func (p Proc) NewStat() (ProcStat, error) {
-	f, err := os.Open(p.path("stat"))
-	if err != nil {
-		return ProcStat{}, err
-	}
-	defer f.Close()
-
-	data, err := ioutil.ReadAll(f)
-	if err != nil {
-		return ProcStat{}, err
-	}
-
-	var (
-		ignore int
-
-		s = ProcStat{PID: p.PID, fs: p.fs}
-		l = bytes.Index(data, []byte("("))
-		r = bytes.LastIndex(data, []byte(")"))
-	)
-
-	if l < 0 || r < 0 {
-		return ProcStat{}, fmt.Errorf(
-			"unexpected format, couldn't extract comm: %s",
-			data,
-		)
-	}
-
-	s.Comm = string(data[l+1 : r])
-	_, err = fmt.Fscan(
-		bytes.NewBuffer(data[r+2:]),
-		&s.State,
-		&s.PPID,
-		&s.PGRP,
-		&s.Session,
-		&s.TTY,
-		&s.TPGID,
-		&s.Flags,
-		&s.MinFlt,
-		&s.CMinFlt,
-		&s.MajFlt,
-		&s.CMajFlt,
-		&s.UTime,
-		&s.STime,
-		&s.CUTime,
-		&s.CSTime,
-		&s.Priority,
-		&s.Nice,
-		&s.NumThreads,
-		&ignore,
-		&s.Starttime,
-		&s.VSize,
-		&s.RSS,
-	)
-	if err != nil {
-		return ProcStat{}, err
-	}
-
-	return s, nil
-}
-
-// VirtualMemory returns the virtual memory size in bytes.
-func (s ProcStat) VirtualMemory() int {
-	return s.VSize
-}
-
-// ResidentMemory returns the resident memory size in bytes.
-func (s ProcStat) ResidentMemory() int {
-	return s.RSS * os.Getpagesize()
-}
-
-// StartTime returns the unix timestamp of the process in seconds.
-func (s ProcStat) StartTime() (float64, error) {
-	stat, err := s.fs.NewStat()
-	if err != nil {
-		return 0, err
-	}
-	return float64(stat.BootTime) + (float64(s.Starttime) / userHZ), nil
-}
-
-// CPUTime returns the total CPU user and system time in seconds.
-func (s ProcStat) CPUTime() float64 {
-	return float64(s.UTime+s.STime) / userHZ
-}
diff --git a/vendor/github.com/prometheus/procfs/stat.go b/vendor/github.com/prometheus/procfs/stat.go
deleted file mode 100644
index 61eb6b0..0000000
--- a/vendor/github.com/prometheus/procfs/stat.go
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2018 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"os"
-	"strconv"
-	"strings"
-)
-
-// CPUStat shows how much time the cpu spend in various stages.
-type CPUStat struct {
-	User      float64
-	Nice      float64
-	System    float64
-	Idle      float64
-	Iowait    float64
-	IRQ       float64
-	SoftIRQ   float64
-	Steal     float64
-	Guest     float64
-	GuestNice float64
-}
-
-// SoftIRQStat represent the softirq statistics as exported in the procfs stat file.
-// A nice introduction can be found at https://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-9.html
-// It is possible to get per-cpu stats by reading /proc/softirqs
-type SoftIRQStat struct {
-	Hi          uint64
-	Timer       uint64
-	NetTx       uint64
-	NetRx       uint64
-	Block       uint64
-	BlockIoPoll uint64
-	Tasklet     uint64
-	Sched       uint64
-	Hrtimer     uint64
-	Rcu         uint64
-}
-
-// Stat represents kernel/system statistics.
-type Stat struct {
-	// Boot time in seconds since the Epoch.
-	BootTime uint64
-	// Summed up cpu statistics.
-	CPUTotal CPUStat
-	// Per-CPU statistics.
-	CPU []CPUStat
-	// Number of times interrupts were handled, which contains numbered and unnumbered IRQs.
-	IRQTotal uint64
-	// Number of times a numbered IRQ was triggered.
-	IRQ []uint64
-	// Number of times a context switch happened.
-	ContextSwitches uint64
-	// Number of times a process was created.
-	ProcessCreated uint64
-	// Number of processes currently running.
-	ProcessesRunning uint64
-	// Number of processes currently blocked (waiting for IO).
-	ProcessesBlocked uint64
-	// Number of times a softirq was scheduled.
-	SoftIRQTotal uint64
-	// Detailed softirq statistics.
-	SoftIRQ SoftIRQStat
-}
-
-// NewStat returns kernel/system statistics read from /proc/stat.
-func NewStat() (Stat, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return Stat{}, err
-	}
-
-	return fs.NewStat()
-}
-
-// Parse a cpu statistics line and returns the CPUStat struct plus the cpu id (or -1 for the overall sum).
-func parseCPUStat(line string) (CPUStat, int64, error) {
-	cpuStat := CPUStat{}
-	var cpu string
-
-	count, err := fmt.Sscanf(line, "%s %f %f %f %f %f %f %f %f %f %f",
-		&cpu,
-		&cpuStat.User, &cpuStat.Nice, &cpuStat.System, &cpuStat.Idle,
-		&cpuStat.Iowait, &cpuStat.IRQ, &cpuStat.SoftIRQ, &cpuStat.Steal,
-		&cpuStat.Guest, &cpuStat.GuestNice)
-
-	if err != nil && err != io.EOF {
-		return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu): %s", line, err)
-	}
-	if count == 0 {
-		return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu): 0 elements parsed", line)
-	}
-
-	cpuStat.User /= userHZ
-	cpuStat.Nice /= userHZ
-	cpuStat.System /= userHZ
-	cpuStat.Idle /= userHZ
-	cpuStat.Iowait /= userHZ
-	cpuStat.IRQ /= userHZ
-	cpuStat.SoftIRQ /= userHZ
-	cpuStat.Steal /= userHZ
-	cpuStat.Guest /= userHZ
-	cpuStat.GuestNice /= userHZ
-
-	if cpu == "cpu" {
-		return cpuStat, -1, nil
-	}
-
-	cpuID, err := strconv.ParseInt(cpu[3:], 10, 64)
-	if err != nil {
-		return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu/cpuid): %s", line, err)
-	}
-
-	return cpuStat, cpuID, nil
-}
-
-// Parse a softirq line.
-func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) {
-	softIRQStat := SoftIRQStat{}
-	var total uint64
-	var prefix string
-
-	_, err := fmt.Sscanf(line, "%s %d %d %d %d %d %d %d %d %d %d %d",
-		&prefix, &total,
-		&softIRQStat.Hi, &softIRQStat.Timer, &softIRQStat.NetTx, &softIRQStat.NetRx,
-		&softIRQStat.Block, &softIRQStat.BlockIoPoll,
-		&softIRQStat.Tasklet, &softIRQStat.Sched,
-		&softIRQStat.Hrtimer, &softIRQStat.Rcu)
-
-	if err != nil {
-		return SoftIRQStat{}, 0, fmt.Errorf("couldn't parse %s (softirq): %s", line, err)
-	}
-
-	return softIRQStat, total, nil
-}
-
-// NewStat returns an information about current kernel/system statistics.
-func (fs FS) NewStat() (Stat, error) {
-	// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
-
-	f, err := os.Open(fs.Path("stat"))
-	if err != nil {
-		return Stat{}, err
-	}
-	defer f.Close()
-
-	stat := Stat{}
-
-	scanner := bufio.NewScanner(f)
-	for scanner.Scan() {
-		line := scanner.Text()
-		parts := strings.Fields(scanner.Text())
-		// require at least <key> <value>
-		if len(parts) < 2 {
-			continue
-		}
-		switch {
-		case parts[0] == "btime":
-			if stat.BootTime, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
-				return Stat{}, fmt.Errorf("couldn't parse %s (btime): %s", parts[1], err)
-			}
-		case parts[0] == "intr":
-			if stat.IRQTotal, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
-				return Stat{}, fmt.Errorf("couldn't parse %s (intr): %s", parts[1], err)
-			}
-			numberedIRQs := parts[2:]
-			stat.IRQ = make([]uint64, len(numberedIRQs))
-			for i, count := range numberedIRQs {
-				if stat.IRQ[i], err = strconv.ParseUint(count, 10, 64); err != nil {
-					return Stat{}, fmt.Errorf("couldn't parse %s (intr%d): %s", count, i, err)
-				}
-			}
-		case parts[0] == "ctxt":
-			if stat.ContextSwitches, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
-				return Stat{}, fmt.Errorf("couldn't parse %s (ctxt): %s", parts[1], err)
-			}
-		case parts[0] == "processes":
-			if stat.ProcessCreated, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
-				return Stat{}, fmt.Errorf("couldn't parse %s (processes): %s", parts[1], err)
-			}
-		case parts[0] == "procs_running":
-			if stat.ProcessesRunning, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
-				return Stat{}, fmt.Errorf("couldn't parse %s (procs_running): %s", parts[1], err)
-			}
-		case parts[0] == "procs_blocked":
-			if stat.ProcessesBlocked, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
-				return Stat{}, fmt.Errorf("couldn't parse %s (procs_blocked): %s", parts[1], err)
-			}
-		case parts[0] == "softirq":
-			softIRQStats, total, err := parseSoftIRQStat(line)
-			if err != nil {
-				return Stat{}, err
-			}
-			stat.SoftIRQTotal = total
-			stat.SoftIRQ = softIRQStats
-		case strings.HasPrefix(parts[0], "cpu"):
-			cpuStat, cpuID, err := parseCPUStat(line)
-			if err != nil {
-				return Stat{}, err
-			}
-			if cpuID == -1 {
-				stat.CPUTotal = cpuStat
-			} else {
-				for int64(len(stat.CPU)) <= cpuID {
-					stat.CPU = append(stat.CPU, CPUStat{})
-				}
-				stat.CPU[cpuID] = cpuStat
-			}
-		}
-	}
-
-	if err := scanner.Err(); err != nil {
-		return Stat{}, fmt.Errorf("couldn't parse %s: %s", f.Name(), err)
-	}
-
-	return stat, nil
-}
diff --git a/vendor/github.com/prometheus/procfs/ttar b/vendor/github.com/prometheus/procfs/ttar
deleted file mode 100755
index b0171a1..0000000
--- a/vendor/github.com/prometheus/procfs/ttar
+++ /dev/null
@@ -1,389 +0,0 @@
-#!/usr/bin/env bash
-
-# Purpose: plain text tar format
-# Limitations: - only suitable for text files, directories, and symlinks
-#              - stores only filename, content, and mode
-#              - not designed for untrusted input
-#
-# Note: must work with bash version 3.2 (macOS)
-
-# Copyright 2017 Roger Luethi
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -o errexit -o nounset
-
-# Sanitize environment (for instance, standard sorting of glob matches)
-export LC_ALL=C
-
-path=""
-CMD=""
-ARG_STRING="$*"
-
-#------------------------------------------------------------------------------
-# Not all sed implementations can work on null bytes. In order to make ttar
-# work out of the box on macOS, use Python as a stream editor.
-
-USE_PYTHON=0
-
-PYTHON_CREATE_FILTER=$(cat << 'PCF'
-#!/usr/bin/env python
-
-import re
-import sys
-
-for line in sys.stdin:
-    line = re.sub(r'EOF', r'\EOF', line)
-    line = re.sub(r'NULLBYTE', r'\NULLBYTE', line)
-    line = re.sub('\x00', r'NULLBYTE', line)
-    sys.stdout.write(line)
-PCF
-)
-
-PYTHON_EXTRACT_FILTER=$(cat << 'PEF'
-#!/usr/bin/env python
-
-import re
-import sys
-
-for line in sys.stdin:
-    line = re.sub(r'(?<!\\)NULLBYTE', '\x00', line)
-    line = re.sub(r'\\NULLBYTE', 'NULLBYTE', line)
-    line = re.sub(r'([^\\])EOF', r'\1', line)
-    line = re.sub(r'\\EOF', 'EOF', line)
-    sys.stdout.write(line)
-PEF
-)
-
-function test_environment {
-    if [[ "$(echo "a" | sed 's/a/\x0/' | wc -c)" -ne 2 ]]; then
-        echo "WARNING sed unable to handle null bytes, using Python (slow)."
-        if ! which python >/dev/null; then
-            echo "ERROR Python not found. Aborting."
-            exit 2
-        fi
-        USE_PYTHON=1
-    fi
-}
-
-#------------------------------------------------------------------------------
-
-function usage {
-    bname=$(basename "$0")
-    cat << USAGE
-Usage:   $bname [-C <DIR>] -c -f <ARCHIVE> <FILE...> (create archive)
-         $bname            -t -f <ARCHIVE>           (list archive contents)
-         $bname [-C <DIR>] -x -f <ARCHIVE>           (extract archive)
-
-Options:
-         -C <DIR>                                    (change directory)
-         -v                                          (verbose)
-
-Example: Change to sysfs directory, create ttar file from fixtures directory
-         $bname -C sysfs -c -f sysfs/fixtures.ttar fixtures/
-USAGE
-exit "$1"
-}
-
-function vecho {
-    if [ "${VERBOSE:-}" == "yes" ]; then
-        echo >&7 "$@"
-    fi
-}
-
-function set_cmd {
-    if [ -n "$CMD" ]; then
-        echo "ERROR: more than one command given"
-        echo
-        usage 2
-    fi
-    CMD=$1
-}
-
-unset VERBOSE
-
-while getopts :cf:htxvC: opt; do
-    case $opt in
-        c)
-            set_cmd "create"
-            ;;
-        f)
-            ARCHIVE=$OPTARG
-            ;;
-        h)
-            usage 0
-            ;;
-        t)
-            set_cmd "list"
-            ;;
-        x)
-            set_cmd "extract"
-            ;;
-        v)
-            VERBOSE=yes
-            exec 7>&1
-            ;;
-        C)
-            CDIR=$OPTARG
-            ;;
-        *)
-            echo >&2 "ERROR: invalid option -$OPTARG"
-            echo
-            usage 1
-            ;;
-    esac
-done
-
-# Remove processed options from arguments
-shift $(( OPTIND - 1 ));
-
-if [ "${CMD:-}" == "" ]; then
-    echo >&2 "ERROR: no command given"
-    echo
-    usage 1
-elif [ "${ARCHIVE:-}" == "" ]; then
-    echo >&2 "ERROR: no archive name given"
-    echo
-    usage 1
-fi
-
-function list {
-    local path=""
-    local size=0
-    local line_no=0
-    local ttar_file=$1
-    if [ -n "${2:-}" ]; then
-        echo >&2 "ERROR: too many arguments."
-        echo
-        usage 1
-    fi
-    if [ ! -e "$ttar_file" ]; then
-        echo >&2 "ERROR: file not found ($ttar_file)"
-        echo
-        usage 1
-    fi
-    while read -r line; do
-        line_no=$(( line_no + 1 ))
-        if [ $size -gt 0 ]; then
-            size=$(( size - 1 ))
-            continue
-        fi
-        if [[ $line =~ ^Path:\ (.*)$ ]]; then
-            path=${BASH_REMATCH[1]}
-        elif [[ $line =~ ^Lines:\ (.*)$ ]]; then
-            size=${BASH_REMATCH[1]}
-            echo "$path"
-        elif [[ $line =~ ^Directory:\ (.*)$ ]]; then
-            path=${BASH_REMATCH[1]}
-            echo "$path/"
-        elif [[ $line =~ ^SymlinkTo:\ (.*)$ ]]; then
-            echo  "$path -> ${BASH_REMATCH[1]}"
-        fi
-    done < "$ttar_file"
-}
-
-function extract {
-    local path=""
-    local size=0
-    local line_no=0
-    local ttar_file=$1
-    if [ -n "${2:-}" ]; then
-        echo >&2 "ERROR: too many arguments."
-        echo
-        usage 1
-    fi
-    if [ ! -e "$ttar_file" ]; then
-        echo >&2 "ERROR: file not found ($ttar_file)"
-        echo
-        usage 1
-    fi
-    while IFS= read -r line; do
-        line_no=$(( line_no + 1 ))
-        local eof_without_newline
-        if [ "$size" -gt 0 ]; then
-            if [[ "$line" =~ [^\\]EOF ]]; then
-                # An EOF not preceeded by a backslash indicates that the line
-                # does not end with a newline
-                eof_without_newline=1
-            else
-                eof_without_newline=0
-            fi
-            # Replace NULLBYTE with null byte if at beginning of line
-            # Replace NULLBYTE with null byte unless preceeded by backslash
-            # Remove one backslash in front of NULLBYTE (if any)
-            # Remove EOF unless preceeded by backslash
-            # Remove one backslash in front of EOF
-            if [ $USE_PYTHON -eq 1 ]; then
-                echo -n "$line" | python -c "$PYTHON_EXTRACT_FILTER" >> "$path"
-            else
-                # The repeated pattern makes up for sed's lack of negative
-                # lookbehind assertions (for consecutive null bytes).
-                echo -n "$line" | \
-                    sed -e 's/^NULLBYTE/\x0/g;
-                            s/\([^\\]\)NULLBYTE/\1\x0/g;
-                            s/\([^\\]\)NULLBYTE/\1\x0/g;
-                            s/\\NULLBYTE/NULLBYTE/g;
-                            s/\([^\\]\)EOF/\1/g;
-                            s/\\EOF/EOF/g;
-                    ' >> "$path"
-            fi
-            if [[ "$eof_without_newline" -eq 0 ]]; then
-                echo >> "$path"
-            fi
-            size=$(( size - 1 ))
-            continue
-        fi
-        if [[ $line =~ ^Path:\ (.*)$ ]]; then
-            path=${BASH_REMATCH[1]}
-            if [ -e "$path" ] || [ -L "$path" ]; then
-                rm "$path"
-            fi
-        elif [[ $line =~ ^Lines:\ (.*)$ ]]; then
-            size=${BASH_REMATCH[1]}
-            # Create file even if it is zero-length.
-            touch "$path"
-            vecho "    $path"
-        elif [[ $line =~ ^Mode:\ (.*)$ ]]; then
-            mode=${BASH_REMATCH[1]}
-            chmod "$mode" "$path"
-            vecho "$mode"
-        elif [[ $line =~ ^Directory:\ (.*)$ ]]; then
-            path=${BASH_REMATCH[1]}
-            mkdir -p "$path"
-            vecho "    $path/"
-        elif [[ $line =~ ^SymlinkTo:\ (.*)$ ]]; then
-            ln -s "${BASH_REMATCH[1]}" "$path"
-            vecho "    $path -> ${BASH_REMATCH[1]}"
-        elif [[ $line =~ ^# ]]; then
-            # Ignore comments between files
-            continue
-        else
-            echo >&2 "ERROR: Unknown keyword on line $line_no: $line"
-            exit 1
-        fi
-    done < "$ttar_file"
-}
-
-function div {
-    echo "# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" \
-         "- - - - - -"
-}
-
-function get_mode {
-    local mfile=$1
-    if [ -z "${STAT_OPTION:-}" ]; then
-        if stat -c '%a' "$mfile" >/dev/null 2>&1; then
-            # GNU stat
-            STAT_OPTION='-c'
-            STAT_FORMAT='%a'
-        else
-            # BSD stat
-            STAT_OPTION='-f'
-            # Octal output, user/group/other (omit file type, sticky bit)
-            STAT_FORMAT='%OLp'
-        fi
-    fi
-    stat "${STAT_OPTION}" "${STAT_FORMAT}" "$mfile"
-}
-
-function _create {
-    shopt -s nullglob
-    local mode
-    local eof_without_newline
-    while (( "$#" )); do
-        file=$1
-        if [ -L "$file" ]; then
-            echo "Path: $file"
-            symlinkTo=$(readlink "$file")
-            echo "SymlinkTo: $symlinkTo"
-            vecho "    $file -> $symlinkTo"
-            div
-        elif [ -d "$file" ]; then
-            # Strip trailing slash (if there is one)
-            file=${file%/}
-            echo "Directory: $file"
-            mode=$(get_mode "$file")
-            echo "Mode: $mode"
-            vecho "$mode $file/"
-            div
-            # Find all files and dirs, including hidden/dot files
-            for x in "$file/"{*,.[^.]*}; do
-                _create "$x"
-            done
-        elif [ -f "$file" ]; then
-            echo "Path: $file"
-            lines=$(wc -l "$file"|awk '{print $1}')
-            eof_without_newline=0
-            if [[ "$(wc -c "$file"|awk '{print $1}')" -gt 0 ]] && \
-                    [[ "$(tail -c 1 "$file" | wc -l)" -eq 0 ]]; then
-                eof_without_newline=1
-                lines=$((lines+1))
-            fi
-            echo "Lines: $lines"
-            # Add backslash in front of EOF
-            # Add backslash in front of NULLBYTE
-            # Replace null byte with NULLBYTE
-            if [ $USE_PYTHON -eq 1 ]; then
-                < "$file" python -c "$PYTHON_CREATE_FILTER"
-            else
-                < "$file" \
-                    sed 's/EOF/\\EOF/g;
-                         s/NULLBYTE/\\NULLBYTE/g;
-                         s/\x0/NULLBYTE/g;
-                    '
-            fi
-            if [[ "$eof_without_newline" -eq 1 ]]; then
-                # Finish line with EOF to indicate that the original line did
-                # not end with a linefeed
-                echo "EOF"
-            fi
-            mode=$(get_mode "$file")
-            echo "Mode: $mode"
-            vecho "$mode $file"
-            div
-        else
-            echo >&2 "ERROR: file not found ($file in $(pwd))"
-            exit 2
-        fi
-        shift
-    done
-}
-
-function create {
-    ttar_file=$1
-    shift
-    if [ -z "${1:-}" ]; then
-        echo >&2 "ERROR: missing arguments."
-        echo
-        usage 1
-    fi
-    if [ -e "$ttar_file" ]; then
-        rm "$ttar_file"
-    fi
-    exec > "$ttar_file"
-    echo "# Archive created by ttar $ARG_STRING"
-    _create "$@"
-}
-
-test_environment
-
-if [ -n "${CDIR:-}" ]; then
-    if [[ "$ARCHIVE" != /* ]]; then
-        # Relative path: preserve the archive's location before changing
-        # directory
-        ARCHIVE="$(pwd)/$ARCHIVE"
-    fi
-    cd "$CDIR"
-fi
-
-"$CMD" "$ARCHIVE" "$@"
diff --git a/vendor/github.com/prometheus/procfs/xfrm.go b/vendor/github.com/prometheus/procfs/xfrm.go
deleted file mode 100644
index 8f1508f..0000000
--- a/vendor/github.com/prometheus/procfs/xfrm.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2017 Prometheus Team
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package procfs
-
-import (
-	"bufio"
-	"fmt"
-	"os"
-	"strconv"
-	"strings"
-)
-
-// XfrmStat models the contents of /proc/net/xfrm_stat.
-type XfrmStat struct {
-	// All errors which are not matched by other
-	XfrmInError int
-	// No buffer is left
-	XfrmInBufferError int
-	// Header Error
-	XfrmInHdrError int
-	// No state found
-	// i.e. either inbound SPI, address, or IPSEC protocol at SA is wrong
-	XfrmInNoStates int
-	// Transformation protocol specific error
-	// e.g. SA Key is wrong
-	XfrmInStateProtoError int
-	// Transformation mode specific error
-	XfrmInStateModeError int
-	// Sequence error
-	// e.g. sequence number is out of window
-	XfrmInStateSeqError int
-	// State is expired
-	XfrmInStateExpired int
-	// State has mismatch option
-	// e.g. UDP encapsulation type is mismatched
-	XfrmInStateMismatch int
-	// State is invalid
-	XfrmInStateInvalid int
-	// No matching template for states
-	// e.g. Inbound SAs are correct but SP rule is wrong
-	XfrmInTmplMismatch int
-	// No policy is found for states
-	// e.g. Inbound SAs are correct but no SP is found
-	XfrmInNoPols int
-	// Policy discards
-	XfrmInPolBlock int
-	// Policy error
-	XfrmInPolError int
-	// All errors which are not matched by others
-	XfrmOutError int
-	// Bundle generation error
-	XfrmOutBundleGenError int
-	// Bundle check error
-	XfrmOutBundleCheckError int
-	// No state was found
-	XfrmOutNoStates int
-	// Transformation protocol specific error
-	XfrmOutStateProtoError int
-	// Transportation mode specific error
-	XfrmOutStateModeError int
-	// Sequence error
-	// i.e sequence number overflow
-	XfrmOutStateSeqError int
-	// State is expired
-	XfrmOutStateExpired int
-	// Policy discads
-	XfrmOutPolBlock int
-	// Policy is dead
-	XfrmOutPolDead int
-	// Policy Error
-	XfrmOutPolError     int
-	XfrmFwdHdrError     int
-	XfrmOutStateInvalid int
-	XfrmAcquireError    int
-}
-
-// NewXfrmStat reads the xfrm_stat statistics.
-func NewXfrmStat() (XfrmStat, error) {
-	fs, err := NewFS(DefaultMountPoint)
-	if err != nil {
-		return XfrmStat{}, err
-	}
-
-	return fs.NewXfrmStat()
-}
-
-// NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem.
-func (fs FS) NewXfrmStat() (XfrmStat, error) {
-	file, err := os.Open(fs.Path("net/xfrm_stat"))
-	if err != nil {
-		return XfrmStat{}, err
-	}
-	defer file.Close()
-
-	var (
-		x = XfrmStat{}
-		s = bufio.NewScanner(file)
-	)
-
-	for s.Scan() {
-		fields := strings.Fields(s.Text())
-
-		if len(fields) != 2 {
-			return XfrmStat{}, fmt.Errorf(
-				"couldn't parse %s line %s", file.Name(), s.Text())
-		}
-
-		name := fields[0]
-		value, err := strconv.Atoi(fields[1])
-		if err != nil {
-			return XfrmStat{}, err
-		}
-
-		switch name {
-		case "XfrmInError":
-			x.XfrmInError = value
-		case "XfrmInBufferError":
-			x.XfrmInBufferError = value
-		case "XfrmInHdrError":
-			x.XfrmInHdrError = value
-		case "XfrmInNoStates":
-			x.XfrmInNoStates = value
-		case "XfrmInStateProtoError":
-			x.XfrmInStateProtoError = value
-		case "XfrmInStateModeError":
-			x.XfrmInStateModeError = value
-		case "XfrmInStateSeqError":
-			x.XfrmInStateSeqError = value
-		case "XfrmInStateExpired":
-			x.XfrmInStateExpired = value
-		case "XfrmInStateInvalid":
-			x.XfrmInStateInvalid = value
-		case "XfrmInTmplMismatch":
-			x.XfrmInTmplMismatch = value
-		case "XfrmInNoPols":
-			x.XfrmInNoPols = value
-		case "XfrmInPolBlock":
-			x.XfrmInPolBlock = value
-		case "XfrmInPolError":
-			x.XfrmInPolError = value
-		case "XfrmOutError":
-			x.XfrmOutError = value
-		case "XfrmInStateMismatch":
-			x.XfrmInStateMismatch = value
-		case "XfrmOutBundleGenError":
-			x.XfrmOutBundleGenError = value
-		case "XfrmOutBundleCheckError":
-			x.XfrmOutBundleCheckError = value
-		case "XfrmOutNoStates":
-			x.XfrmOutNoStates = value
-		case "XfrmOutStateProtoError":
-			x.XfrmOutStateProtoError = value
-		case "XfrmOutStateModeError":
-			x.XfrmOutStateModeError = value
-		case "XfrmOutStateSeqError":
-			x.XfrmOutStateSeqError = value
-		case "XfrmOutStateExpired":
-			x.XfrmOutStateExpired = value
-		case "XfrmOutPolBlock":
-			x.XfrmOutPolBlock = value
-		case "XfrmOutPolDead":
-			x.XfrmOutPolDead = value
-		case "XfrmOutPolError":
-			x.XfrmOutPolError = value
-		case "XfrmFwdHdrError":
-			x.XfrmFwdHdrError = value
-		case "XfrmOutStateInvalid":
-			x.XfrmOutStateInvalid = value
-		case "XfrmAcquireError":
-			x.XfrmAcquireError = value
-		}
-
-	}
-
-	return x, s.Err()
-}
diff --git a/vendor/github.com/prometheus/procfs/xfs/parse.go b/vendor/github.com/prometheus/procfs/xfs/parse.go
deleted file mode 100644
index b3d8634..0000000
--- a/vendor/github.com/prometheus/procfs/xfs/parse.go
+++ /dev/null
@@ -1,330 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package xfs
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"strings"
-
-	"github.com/prometheus/procfs/internal/util"
-)
-
-// ParseStats parses a Stats from an input io.Reader, using the format
-// found in /proc/fs/xfs/stat.
-func ParseStats(r io.Reader) (*Stats, error) {
-	const (
-		// Fields parsed into stats structures.
-		fieldExtentAlloc = "extent_alloc"
-		fieldAbt         = "abt"
-		fieldBlkMap      = "blk_map"
-		fieldBmbt        = "bmbt"
-		fieldDir         = "dir"
-		fieldTrans       = "trans"
-		fieldIg          = "ig"
-		fieldLog         = "log"
-		fieldRw          = "rw"
-		fieldAttr        = "attr"
-		fieldIcluster    = "icluster"
-		fieldVnodes      = "vnodes"
-		fieldBuf         = "buf"
-		fieldXpc         = "xpc"
-
-		// Unimplemented at this time due to lack of documentation.
-		// fieldPushAil = "push_ail"
-		// fieldXstrat  = "xstrat"
-		// fieldAbtb2   = "abtb2"
-		// fieldAbtc2   = "abtc2"
-		// fieldBmbt2   = "bmbt2"
-		// fieldIbt2    = "ibt2"
-		// fieldFibt2   = "fibt2"
-		// fieldQm      = "qm"
-		// fieldDebug   = "debug"
-	)
-
-	var xfss Stats
-
-	s := bufio.NewScanner(r)
-	for s.Scan() {
-		// Expect at least a string label and a single integer value, ex:
-		//   - abt 0
-		//   - rw 1 2
-		ss := strings.Fields(string(s.Bytes()))
-		if len(ss) < 2 {
-			continue
-		}
-		label := ss[0]
-
-		// Extended precision counters are uint64 values.
-		if label == fieldXpc {
-			us, err := util.ParseUint64s(ss[1:])
-			if err != nil {
-				return nil, err
-			}
-
-			xfss.ExtendedPrecision, err = extendedPrecisionStats(us)
-			if err != nil {
-				return nil, err
-			}
-
-			continue
-		}
-
-		// All other counters are uint32 values.
-		us, err := util.ParseUint32s(ss[1:])
-		if err != nil {
-			return nil, err
-		}
-
-		switch label {
-		case fieldExtentAlloc:
-			xfss.ExtentAllocation, err = extentAllocationStats(us)
-		case fieldAbt:
-			xfss.AllocationBTree, err = btreeStats(us)
-		case fieldBlkMap:
-			xfss.BlockMapping, err = blockMappingStats(us)
-		case fieldBmbt:
-			xfss.BlockMapBTree, err = btreeStats(us)
-		case fieldDir:
-			xfss.DirectoryOperation, err = directoryOperationStats(us)
-		case fieldTrans:
-			xfss.Transaction, err = transactionStats(us)
-		case fieldIg:
-			xfss.InodeOperation, err = inodeOperationStats(us)
-		case fieldLog:
-			xfss.LogOperation, err = logOperationStats(us)
-		case fieldRw:
-			xfss.ReadWrite, err = readWriteStats(us)
-		case fieldAttr:
-			xfss.AttributeOperation, err = attributeOperationStats(us)
-		case fieldIcluster:
-			xfss.InodeClustering, err = inodeClusteringStats(us)
-		case fieldVnodes:
-			xfss.Vnode, err = vnodeStats(us)
-		case fieldBuf:
-			xfss.Buffer, err = bufferStats(us)
-		}
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	return &xfss, s.Err()
-}
-
-// extentAllocationStats builds an ExtentAllocationStats from a slice of uint32s.
-func extentAllocationStats(us []uint32) (ExtentAllocationStats, error) {
-	if l := len(us); l != 4 {
-		return ExtentAllocationStats{}, fmt.Errorf("incorrect number of values for XFS extent allocation stats: %d", l)
-	}
-
-	return ExtentAllocationStats{
-		ExtentsAllocated: us[0],
-		BlocksAllocated:  us[1],
-		ExtentsFreed:     us[2],
-		BlocksFreed:      us[3],
-	}, nil
-}
-
-// btreeStats builds a BTreeStats from a slice of uint32s.
-func btreeStats(us []uint32) (BTreeStats, error) {
-	if l := len(us); l != 4 {
-		return BTreeStats{}, fmt.Errorf("incorrect number of values for XFS btree stats: %d", l)
-	}
-
-	return BTreeStats{
-		Lookups:         us[0],
-		Compares:        us[1],
-		RecordsInserted: us[2],
-		RecordsDeleted:  us[3],
-	}, nil
-}
-
-// BlockMappingStat builds a BlockMappingStats from a slice of uint32s.
-func blockMappingStats(us []uint32) (BlockMappingStats, error) {
-	if l := len(us); l != 7 {
-		return BlockMappingStats{}, fmt.Errorf("incorrect number of values for XFS block mapping stats: %d", l)
-	}
-
-	return BlockMappingStats{
-		Reads:                us[0],
-		Writes:               us[1],
-		Unmaps:               us[2],
-		ExtentListInsertions: us[3],
-		ExtentListDeletions:  us[4],
-		ExtentListLookups:    us[5],
-		ExtentListCompares:   us[6],
-	}, nil
-}
-
-// DirectoryOperationStats builds a DirectoryOperationStats from a slice of uint32s.
-func directoryOperationStats(us []uint32) (DirectoryOperationStats, error) {
-	if l := len(us); l != 4 {
-		return DirectoryOperationStats{}, fmt.Errorf("incorrect number of values for XFS directory operation stats: %d", l)
-	}
-
-	return DirectoryOperationStats{
-		Lookups:  us[0],
-		Creates:  us[1],
-		Removes:  us[2],
-		Getdents: us[3],
-	}, nil
-}
-
-// TransactionStats builds a TransactionStats from a slice of uint32s.
-func transactionStats(us []uint32) (TransactionStats, error) {
-	if l := len(us); l != 3 {
-		return TransactionStats{}, fmt.Errorf("incorrect number of values for XFS transaction stats: %d", l)
-	}
-
-	return TransactionStats{
-		Sync:  us[0],
-		Async: us[1],
-		Empty: us[2],
-	}, nil
-}
-
-// InodeOperationStats builds an InodeOperationStats from a slice of uint32s.
-func inodeOperationStats(us []uint32) (InodeOperationStats, error) {
-	if l := len(us); l != 7 {
-		return InodeOperationStats{}, fmt.Errorf("incorrect number of values for XFS inode operation stats: %d", l)
-	}
-
-	return InodeOperationStats{
-		Attempts:        us[0],
-		Found:           us[1],
-		Recycle:         us[2],
-		Missed:          us[3],
-		Duplicate:       us[4],
-		Reclaims:        us[5],
-		AttributeChange: us[6],
-	}, nil
-}
-
-// LogOperationStats builds a LogOperationStats from a slice of uint32s.
-func logOperationStats(us []uint32) (LogOperationStats, error) {
-	if l := len(us); l != 5 {
-		return LogOperationStats{}, fmt.Errorf("incorrect number of values for XFS log operation stats: %d", l)
-	}
-
-	return LogOperationStats{
-		Writes:            us[0],
-		Blocks:            us[1],
-		NoInternalBuffers: us[2],
-		Force:             us[3],
-		ForceSleep:        us[4],
-	}, nil
-}
-
-// ReadWriteStats builds a ReadWriteStats from a slice of uint32s.
-func readWriteStats(us []uint32) (ReadWriteStats, error) {
-	if l := len(us); l != 2 {
-		return ReadWriteStats{}, fmt.Errorf("incorrect number of values for XFS read write stats: %d", l)
-	}
-
-	return ReadWriteStats{
-		Read:  us[0],
-		Write: us[1],
-	}, nil
-}
-
-// AttributeOperationStats builds an AttributeOperationStats from a slice of uint32s.
-func attributeOperationStats(us []uint32) (AttributeOperationStats, error) {
-	if l := len(us); l != 4 {
-		return AttributeOperationStats{}, fmt.Errorf("incorrect number of values for XFS attribute operation stats: %d", l)
-	}
-
-	return AttributeOperationStats{
-		Get:    us[0],
-		Set:    us[1],
-		Remove: us[2],
-		List:   us[3],
-	}, nil
-}
-
-// InodeClusteringStats builds an InodeClusteringStats from a slice of uint32s.
-func inodeClusteringStats(us []uint32) (InodeClusteringStats, error) {
-	if l := len(us); l != 3 {
-		return InodeClusteringStats{}, fmt.Errorf("incorrect number of values for XFS inode clustering stats: %d", l)
-	}
-
-	return InodeClusteringStats{
-		Iflush:     us[0],
-		Flush:      us[1],
-		FlushInode: us[2],
-	}, nil
-}
-
-// VnodeStats builds a VnodeStats from a slice of uint32s.
-func vnodeStats(us []uint32) (VnodeStats, error) {
-	// The attribute "Free" appears to not be available on older XFS
-	// stats versions.  Therefore, 7 or 8 elements may appear in
-	// this slice.
-	l := len(us)
-	if l != 7 && l != 8 {
-		return VnodeStats{}, fmt.Errorf("incorrect number of values for XFS vnode stats: %d", l)
-	}
-
-	s := VnodeStats{
-		Active:   us[0],
-		Allocate: us[1],
-		Get:      us[2],
-		Hold:     us[3],
-		Release:  us[4],
-		Reclaim:  us[5],
-		Remove:   us[6],
-	}
-
-	// Skip adding free, unless it is present. The zero value will
-	// be used in place of an actual count.
-	if l == 7 {
-		return s, nil
-	}
-
-	s.Free = us[7]
-	return s, nil
-}
-
-// BufferStats builds a BufferStats from a slice of uint32s.
-func bufferStats(us []uint32) (BufferStats, error) {
-	if l := len(us); l != 9 {
-		return BufferStats{}, fmt.Errorf("incorrect number of values for XFS buffer stats: %d", l)
-	}
-
-	return BufferStats{
-		Get:             us[0],
-		Create:          us[1],
-		GetLocked:       us[2],
-		GetLockedWaited: us[3],
-		BusyLocked:      us[4],
-		MissLocked:      us[5],
-		PageRetries:     us[6],
-		PageFound:       us[7],
-		GetRead:         us[8],
-	}, nil
-}
-
-// ExtendedPrecisionStats builds an ExtendedPrecisionStats from a slice of uint32s.
-func extendedPrecisionStats(us []uint64) (ExtendedPrecisionStats, error) {
-	if l := len(us); l != 3 {
-		return ExtendedPrecisionStats{}, fmt.Errorf("incorrect number of values for XFS extended precision stats: %d", l)
-	}
-
-	return ExtendedPrecisionStats{
-		FlushBytes: us[0],
-		WriteBytes: us[1],
-		ReadBytes:  us[2],
-	}, nil
-}
diff --git a/vendor/github.com/prometheus/procfs/xfs/xfs.go b/vendor/github.com/prometheus/procfs/xfs/xfs.go
deleted file mode 100644
index d86794b..0000000
--- a/vendor/github.com/prometheus/procfs/xfs/xfs.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package xfs provides access to statistics exposed by the XFS filesystem.
-package xfs
-
-// Stats contains XFS filesystem runtime statistics, parsed from
-// /proc/fs/xfs/stat.
-//
-// The names and meanings of each statistic were taken from
-// http://xfs.org/index.php/Runtime_Stats and xfs_stats.h in the Linux
-// kernel source. Most counters are uint32s (same data types used in
-// xfs_stats.h), but some of the "extended precision stats" are uint64s.
-type Stats struct {
-	// The name of the filesystem used to source these statistics.
-	// If empty, this indicates aggregated statistics for all XFS
-	// filesystems on the host.
-	Name string
-
-	ExtentAllocation   ExtentAllocationStats
-	AllocationBTree    BTreeStats
-	BlockMapping       BlockMappingStats
-	BlockMapBTree      BTreeStats
-	DirectoryOperation DirectoryOperationStats
-	Transaction        TransactionStats
-	InodeOperation     InodeOperationStats
-	LogOperation       LogOperationStats
-	ReadWrite          ReadWriteStats
-	AttributeOperation AttributeOperationStats
-	InodeClustering    InodeClusteringStats
-	Vnode              VnodeStats
-	Buffer             BufferStats
-	ExtendedPrecision  ExtendedPrecisionStats
-}
-
-// ExtentAllocationStats contains statistics regarding XFS extent allocations.
-type ExtentAllocationStats struct {
-	ExtentsAllocated uint32
-	BlocksAllocated  uint32
-	ExtentsFreed     uint32
-	BlocksFreed      uint32
-}
-
-// BTreeStats contains statistics regarding an XFS internal B-tree.
-type BTreeStats struct {
-	Lookups         uint32
-	Compares        uint32
-	RecordsInserted uint32
-	RecordsDeleted  uint32
-}
-
-// BlockMappingStats contains statistics regarding XFS block maps.
-type BlockMappingStats struct {
-	Reads                uint32
-	Writes               uint32
-	Unmaps               uint32
-	ExtentListInsertions uint32
-	ExtentListDeletions  uint32
-	ExtentListLookups    uint32
-	ExtentListCompares   uint32
-}
-
-// DirectoryOperationStats contains statistics regarding XFS directory entries.
-type DirectoryOperationStats struct {
-	Lookups  uint32
-	Creates  uint32
-	Removes  uint32
-	Getdents uint32
-}
-
-// TransactionStats contains statistics regarding XFS metadata transactions.
-type TransactionStats struct {
-	Sync  uint32
-	Async uint32
-	Empty uint32
-}
-
-// InodeOperationStats contains statistics regarding XFS inode operations.
-type InodeOperationStats struct {
-	Attempts        uint32
-	Found           uint32
-	Recycle         uint32
-	Missed          uint32
-	Duplicate       uint32
-	Reclaims        uint32
-	AttributeChange uint32
-}
-
-// LogOperationStats contains statistics regarding the XFS log buffer.
-type LogOperationStats struct {
-	Writes            uint32
-	Blocks            uint32
-	NoInternalBuffers uint32
-	Force             uint32
-	ForceSleep        uint32
-}
-
-// ReadWriteStats contains statistics regarding the number of read and write
-// system calls for XFS filesystems.
-type ReadWriteStats struct {
-	Read  uint32
-	Write uint32
-}
-
-// AttributeOperationStats contains statistics regarding manipulation of
-// XFS extended file attributes.
-type AttributeOperationStats struct {
-	Get    uint32
-	Set    uint32
-	Remove uint32
-	List   uint32
-}
-
-// InodeClusteringStats contains statistics regarding XFS inode clustering
-// operations.
-type InodeClusteringStats struct {
-	Iflush     uint32
-	Flush      uint32
-	FlushInode uint32
-}
-
-// VnodeStats contains statistics regarding XFS vnode operations.
-type VnodeStats struct {
-	Active   uint32
-	Allocate uint32
-	Get      uint32
-	Hold     uint32
-	Release  uint32
-	Reclaim  uint32
-	Remove   uint32
-	Free     uint32
-}
-
-// BufferStats contains statistics regarding XFS read/write I/O buffers.
-type BufferStats struct {
-	Get             uint32
-	Create          uint32
-	GetLocked       uint32
-	GetLockedWaited uint32
-	BusyLocked      uint32
-	MissLocked      uint32
-	PageRetries     uint32
-	PageFound       uint32
-	GetRead         uint32
-}
-
-// ExtendedPrecisionStats contains high precision counters used to track the
-// total number of bytes read, written, or flushed, during XFS operations.
-type ExtendedPrecisionStats struct {
-	FlushBytes uint64
-	WriteBytes uint64
-	ReadBytes  uint64
-}
diff --git a/vendor/github.com/sirupsen/logrus/.gitignore b/vendor/github.com/sirupsen/logrus/.gitignore
deleted file mode 100644
index 6b7d7d1..0000000
--- a/vendor/github.com/sirupsen/logrus/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-logrus
-vendor
diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml
deleted file mode 100644
index a8f1545..0000000
--- a/vendor/github.com/sirupsen/logrus/.travis.yml
+++ /dev/null
@@ -1,52 +0,0 @@
-language: go
-go_import_path: github.com/sirupsen/logrus
-env:
-  - GOMAXPROCS=4 GORACE=halt_on_error=1
-matrix:
-  include:
-    - go: 1.10.x
-      install:
-        - go get github.com/stretchr/testify/assert
-        - go get golang.org/x/crypto/ssh/terminal
-        - go get golang.org/x/sys/unix
-        - go get golang.org/x/sys/windows
-      script:
-        - go test -race -v ./...
-    - go: 1.11.x
-      env: GO111MODULE=on
-      install:
-        - go mod download
-      script:
-        - go test -race -v ./...
-    - go: 1.11.x
-      env: GO111MODULE=off
-      install:
-        - go get github.com/stretchr/testify/assert
-        - go get golang.org/x/crypto/ssh/terminal
-        - go get golang.org/x/sys/unix
-        - go get golang.org/x/sys/windows
-      script:
-        - go test -race -v ./...
-    - go: 1.10.x
-      install:
-        - go get github.com/stretchr/testify/assert
-        - go get golang.org/x/crypto/ssh/terminal
-        - go get golang.org/x/sys/unix
-        - go get golang.org/x/sys/windows
-      script:
-        - go test -race -v -tags appengine ./...
-    - go: 1.11.x
-      env: GO111MODULE=on
-      install:
-        - go mod download
-      script:
-        - go test -race -v -tags appengine ./...
-    - go: 1.11.x
-      env: GO111MODULE=off
-      install:
-        - go get github.com/stretchr/testify/assert
-        - go get golang.org/x/crypto/ssh/terminal
-        - go get golang.org/x/sys/unix
-        - go get golang.org/x/sys/windows
-      script:
-        - go test -race -v -tags appengine ./...
diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md
deleted file mode 100644
index cb85d9f..0000000
--- a/vendor/github.com/sirupsen/logrus/CHANGELOG.md
+++ /dev/null
@@ -1,165 +0,0 @@
-# 1.2.0
-This new release introduces:
-  * A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued
-  * A new trace level named `Trace` whose level is below `Debug`
-  * A configurable exit function to be called upon a Fatal trace
-  * The `Level` object now implements `encoding.TextUnmarshaler` interface
-
-# 1.1.1
-This is a bug fix release.
-  * fix the build break on Solaris
-  * don't drop a whole trace in JSONFormatter when a field param is a function pointer which can not be serialized
-
-# 1.1.0
-This new release introduces:
-  * several fixes:
-    * a fix for a race condition on entry formatting
-    * proper cleanup of previously used entries before putting them back in the pool
-    * the extra new line at the end of message in text formatter has been removed
-  * a new global public API to check if a level is activated: IsLevelEnabled
-  * the following methods have been added to the Logger object
-    * IsLevelEnabled
-    * SetFormatter
-    * SetOutput
-    * ReplaceHooks
-  * introduction of go module
-  * an indent configuration for the json formatter
-  * output colour support for windows
-  * the field sort function is now configurable for text formatter
-  * the CLICOLOR and CLICOLOR\_FORCE environment variable support in text formater
-
-# 1.0.6
-
-This new release introduces:
-  * a new api WithTime which allows to easily force the time of the log entry
-    which is mostly useful for logger wrapper
-  * a fix reverting the immutability of the entry given as parameter to the hooks
-    a new configuration field of the json formatter in order to put all the fields
-    in a nested dictionnary
-  * a new SetOutput method in the Logger
-  * a new configuration of the textformatter to configure the name of the default keys
-  * a new configuration of the text formatter to disable the level truncation
-
-# 1.0.5
-
-* Fix hooks race (#707)
-* Fix panic deadlock (#695)
-
-# 1.0.4
-
-* Fix race when adding hooks (#612)
-* Fix terminal check in AppEngine (#635)
-
-# 1.0.3
-
-* Replace example files with testable examples
-
-# 1.0.2
-
-* bug: quote non-string values in text formatter (#583)
-* Make (*Logger) SetLevel a public method
-
-# 1.0.1
-
-* bug: fix escaping in text formatter (#575)
-
-# 1.0.0
-
-* Officially changed name to lower-case
-* bug: colors on Windows 10 (#541)
-* bug: fix race in accessing level (#512)
-
-# 0.11.5
-
-* feature: add writer and writerlevel to entry (#372)
-
-# 0.11.4
-
-* bug: fix undefined variable on solaris (#493)
-
-# 0.11.3
-
-* formatter: configure quoting of empty values (#484)
-* formatter: configure quoting character (default is `"`) (#484)
-* bug: fix not importing io correctly in non-linux environments (#481)
-
-# 0.11.2
-
-* bug: fix windows terminal detection (#476)
-
-# 0.11.1
-
-* bug: fix tty detection with custom out (#471)
-
-# 0.11.0
-
-* performance: Use bufferpool to allocate (#370)
-* terminal: terminal detection for app-engine (#343)
-* feature: exit handler (#375)
-
-# 0.10.0
-
-* feature: Add a test hook (#180)
-* feature: `ParseLevel` is now case-insensitive (#326)
-* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
-* performance: avoid re-allocations on `WithFields` (#335)
-
-# 0.9.0
-
-* logrus/text_formatter: don't emit empty msg
-* logrus/hooks/airbrake: move out of main repository
-* logrus/hooks/sentry: move out of main repository
-* logrus/hooks/papertrail: move out of main repository
-* logrus/hooks/bugsnag: move out of main repository
-* logrus/core: run tests with `-race`
-* logrus/core: detect TTY based on `stderr`
-* logrus/core: support `WithError` on logger
-* logrus/core: Solaris support
-
-# 0.8.7
-
-* logrus/core: fix possible race (#216)
-* logrus/doc: small typo fixes and doc improvements
-
-
-# 0.8.6
-
-* hooks/raven: allow passing an initialized client
-
-# 0.8.5
-
-* logrus/core: revert #208
-
-# 0.8.4
-
-* formatter/text: fix data race (#218)
-
-# 0.8.3
-
-* logrus/core: fix entry log level (#208)
-* logrus/core: improve performance of text formatter by 40%
-* logrus/core: expose `LevelHooks` type
-* logrus/core: add support for DragonflyBSD and NetBSD
-* formatter/text: print structs more verbosely
-
-# 0.8.2
-
-* logrus: fix more Fatal family functions
-
-# 0.8.1
-
-* logrus: fix not exiting on `Fatalf` and `Fatalln`
-
-# 0.8.0
-
-* logrus: defaults to stderr instead of stdout
-* hooks/sentry: add special field for `*http.Request`
-* formatter/text: ignore Windows for colors
-
-# 0.7.3
-
-* formatter/\*: allow configuration of timestamp layout
-
-# 0.7.2
-
-* formatter/text: Add configuration option for time format (#158)
diff --git a/vendor/github.com/sirupsen/logrus/LICENSE b/vendor/github.com/sirupsen/logrus/LICENSE
deleted file mode 100644
index f090cb4..0000000
--- a/vendor/github.com/sirupsen/logrus/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 Simon Eskildsen
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md
deleted file mode 100644
index 3987310..0000000
--- a/vendor/github.com/sirupsen/logrus/README.md
+++ /dev/null
@@ -1,494 +0,0 @@
-# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>&nbsp;[![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus)&nbsp;[![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus)
-
-Logrus is a structured logger for Go (golang), completely API compatible with
-the standard library logger.
-
-**Seeing weird case-sensitive problems?** It's in the past been possible to
-import Logrus as both upper- and lower-case. Due to the Go package environment,
-this caused issues in the community and we needed a standard. Some environments
-experienced problems with the upper-case variant, so the lower-case was decided.
-Everything using `logrus` will need to use the lower-case:
-`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
-
-To fix Glide, see [these
-comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
-For an in-depth explanation of the casing issue, see [this
-comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
-
-**Are you interested in assisting in maintaining Logrus?** Currently I have a
-lot of obligations, and I am unable to provide Logrus with the maintainership it
-needs. If you'd like to help, please reach out to me at `simon at author's
-username dot com`.
-
-Nicely color-coded in development (when a TTY is attached, otherwise just
-plain text):
-
-![Colored](http://i.imgur.com/PY7qMwd.png)
-
-With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash
-or Splunk:
-
-```json
-{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
-ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
-
-{"level":"warning","msg":"The group's number increased tremendously!",
-"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
-
-{"animal":"walrus","level":"info","msg":"A giant walrus appears!",
-"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
-
-{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.",
-"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
-
-{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,
-"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
-```
-
-With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not
-attached, the output is compatible with the
-[logfmt](http://godoc.org/github.com/kr/logfmt) format:
-
-```text
-time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
-time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
-time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
-time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
-time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
-time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
-```
-To ensure this behaviour even if a TTY is attached, set your formatter as follows:
-
-```go
-	log.SetFormatter(&log.TextFormatter{
-		DisableColors: true,
-		FullTimestamp: true,
-	})
-```
-
-#### Logging Method Name
-
-If you wish to add the calling method as a field, instruct the logger via:
-```go
-log.SetReportCaller(true)
-```
-This adds the caller as 'method' like so:
-
-```json
-{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by",
-"time":"2014-03-10 19:57:38.562543129 -0400 EDT"}
-```
-
-```text
-time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin
-```
-Note that this does add measurable overhead - the cost will depend on the version of Go, but is
-between 20 and 40% in recent tests with 1.6 and 1.7.  You can validate this in your
-environment via benchmarks: 
-```
-go test -bench=.*CallerTracing
-```
-
-
-#### Case-sensitivity
-
-The organization's name was changed to lower-case--and this will not be changed
-back. If you are getting import conflicts due to case sensitivity, please use
-the lower-case import: `github.com/sirupsen/logrus`.
-
-#### Example
-
-The simplest way to use Logrus is simply the package-level exported logger:
-
-```go
-package main
-
-import (
-  log "github.com/sirupsen/logrus"
-)
-
-func main() {
-  log.WithFields(log.Fields{
-    "animal": "walrus",
-  }).Info("A walrus appears")
-}
-```
-
-Note that it's completely api-compatible with the stdlib logger, so you can
-replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"`
-and you'll now have the flexibility of Logrus. You can customize it all you
-want:
-
-```go
-package main
-
-import (
-  "os"
-  log "github.com/sirupsen/logrus"
-)
-
-func init() {
-  // Log as JSON instead of the default ASCII formatter.
-  log.SetFormatter(&log.JSONFormatter{})
-
-  // Output to stdout instead of the default stderr
-  // Can be any io.Writer, see below for File example
-  log.SetOutput(os.Stdout)
-
-  // Only log the warning severity or above.
-  log.SetLevel(log.WarnLevel)
-}
-
-func main() {
-  log.WithFields(log.Fields{
-    "animal": "walrus",
-    "size":   10,
-  }).Info("A group of walrus emerges from the ocean")
-
-  log.WithFields(log.Fields{
-    "omg":    true,
-    "number": 122,
-  }).Warn("The group's number increased tremendously!")
-
-  log.WithFields(log.Fields{
-    "omg":    true,
-    "number": 100,
-  }).Fatal("The ice breaks!")
-
-  // A common pattern is to re-use fields between logging statements by re-using
-  // the logrus.Entry returned from WithFields()
-  contextLogger := log.WithFields(log.Fields{
-    "common": "this is a common field",
-    "other": "I also should be logged always",
-  })
-
-  contextLogger.Info("I'll be logged with common and other field")
-  contextLogger.Info("Me too")
-}
-```
-
-For more advanced usage such as logging to multiple locations from the same
-application, you can also create an instance of the `logrus` Logger:
-
-```go
-package main
-
-import (
-  "os"
-  "github.com/sirupsen/logrus"
-)
-
-// Create a new instance of the logger. You can have any number of instances.
-var log = logrus.New()
-
-func main() {
-  // The API for setting attributes is a little different than the package level
-  // exported logger. See Godoc.
-  log.Out = os.Stdout
-
-  // You could set this to any `io.Writer` such as a file
-  // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
-  // if err == nil {
-  //  log.Out = file
-  // } else {
-  //  log.Info("Failed to log to file, using default stderr")
-  // }
-
-  log.WithFields(logrus.Fields{
-    "animal": "walrus",
-    "size":   10,
-  }).Info("A group of walrus emerges from the ocean")
-}
-```
-
-#### Fields
-
-Logrus encourages careful, structured logging through logging fields instead of
-long, unparseable error messages. For example, instead of: `log.Fatalf("Failed
-to send event %s to topic %s with key %d")`, you should log the much more
-discoverable:
-
-```go
-log.WithFields(log.Fields{
-  "event": event,
-  "topic": topic,
-  "key": key,
-}).Fatal("Failed to send event")
-```
-
-We've found this API forces you to think about logging in a way that produces
-much more useful logging messages. We've been in countless situations where just
-a single added field to a log statement that was already there would've saved us
-hours. The `WithFields` call is optional.
-
-In general, with Logrus using any of the `printf`-family functions should be
-seen as a hint you should add a field, however, you can still use the
-`printf`-family functions with Logrus.
-
-#### Default Fields
-
-Often it's helpful to have fields _always_ attached to log statements in an
-application or parts of one. For example, you may want to always log the
-`request_id` and `user_ip` in the context of a request. Instead of writing
-`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on
-every line, you can create a `logrus.Entry` to pass around instead:
-
-```go
-requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
-requestLogger.Info("something happened on that request") # will log request_id and user_ip
-requestLogger.Warn("something not great happened")
-```
-
-#### Hooks
-
-You can add hooks for logging levels. For example to send errors to an exception
-tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to
-multiple places simultaneously, e.g. syslog.
-
-Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
-`init`:
-
-```go
-import (
-  log "github.com/sirupsen/logrus"
-  "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake"
-  logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
-  "log/syslog"
-)
-
-func init() {
-
-  // Use the Airbrake hook to report errors that have Error severity or above to
-  // an exception tracker. You can create custom hooks, see the Hooks section.
-  log.AddHook(airbrake.NewHook(123, "xyz", "production"))
-
-  hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
-  if err != nil {
-    log.Error("Unable to connect to local syslog daemon")
-  } else {
-    log.AddHook(hook)
-  }
-}
-```
-Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
-
-A list of currently known of service hook can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)
-
-
-#### Level logging
-
-Logrus has seven logging levels: Trace, Debug, Info, Warning, Error, Fatal and Panic.
-
-```go
-log.Trace("Something very low level.")
-log.Debug("Useful debugging information.")
-log.Info("Something noteworthy happened!")
-log.Warn("You should probably take a look at this.")
-log.Error("Something failed but I'm not quitting.")
-// Calls os.Exit(1) after logging
-log.Fatal("Bye.")
-// Calls panic() after logging
-log.Panic("I'm bailing.")
-```
-
-You can set the logging level on a `Logger`, then it will only log entries with
-that severity or anything above it:
-
-```go
-// Will log anything that is info or above (warn, error, fatal, panic). Default.
-log.SetLevel(log.InfoLevel)
-```
-
-It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose
-environment if your application has that.
-
-#### Entries
-
-Besides the fields added with `WithField` or `WithFields` some fields are
-automatically added to all logging events:
-
-1. `time`. The timestamp when the entry was created.
-2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
-   the `AddFields` call. E.g. `Failed to send event.`
-3. `level`. The logging level. E.g. `info`.
-
-#### Environments
-
-Logrus has no notion of environment.
-
-If you wish for hooks and formatters to only be used in specific environments,
-you should handle that yourself. For example, if your application has a global
-variable `Environment`, which is a string representation of the environment you
-could do:
-
-```go
-import (
-  log "github.com/sirupsen/logrus"
-)
-
-init() {
-  // do something here to set environment depending on an environment variable
-  // or command-line flag
-  if Environment == "production" {
-    log.SetFormatter(&log.JSONFormatter{})
-  } else {
-    // The TextFormatter is default, you don't actually have to do this.
-    log.SetFormatter(&log.TextFormatter{})
-  }
-}
-```
-
-This configuration is how `logrus` was intended to be used, but JSON in
-production is mostly only useful if you do log aggregation with tools like
-Splunk or Logstash.
-
-#### Formatters
-
-The built-in logging formatters are:
-
-* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
-  without colors.
-  * *Note:* to force colored output when there is no TTY, set the `ForceColors`
-    field to `true`.  To force no colored output even if there is a TTY  set the
-    `DisableColors` field to `true`. For Windows, see
-    [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
-  * When colors are enabled, levels are truncated to 4 characters by default. To disable
-    truncation set the `DisableLevelTruncation` field to `true`.
-  * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter).
-* `logrus.JSONFormatter`. Logs fields as JSON.
-  * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter).
-
-Third party logging formatters:
-
-* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine.
-* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html).
-* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
-* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
-* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
-
-You can define your formatter by implementing the `Formatter` interface,
-requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
-`Fields` type (`map[string]interface{}`) with all your fields as well as the
-default ones (see Entries section above):
-
-```go
-type MyJSONFormatter struct {
-}
-
-log.SetFormatter(new(MyJSONFormatter))
-
-func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
-  // Note this doesn't include Time, Level and Message which are available on
-  // the Entry. Consult `godoc` on information about those fields or read the
-  // source of the official loggers.
-  serialized, err := json.Marshal(entry.Data)
-    if err != nil {
-      return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
-    }
-  return append(serialized, '\n'), nil
-}
-```
-
-#### Logger as an `io.Writer`
-
-Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
-
-```go
-w := logger.Writer()
-defer w.Close()
-
-srv := http.Server{
-    // create a stdlib log.Logger that writes to
-    // logrus.Logger.
-    ErrorLog: log.New(w, "", 0),
-}
-```
-
-Each line written to that writer will be printed the usual way, using formatters
-and hooks. The level for those entries is `info`.
-
-This means that we can override the standard library logger easily:
-
-```go
-logger := logrus.New()
-logger.Formatter = &logrus.JSONFormatter{}
-
-// Use logrus for standard log output
-// Note that `log` here references stdlib's log
-// Not logrus imported under the name `log`.
-log.SetOutput(logger.Writer())
-```
-
-#### Rotation
-
-Log rotation is not provided with Logrus. Log rotation should be done by an
-external program (like `logrotate(8)`) that can compress and delete old log
-entries. It should not be a feature of the application-level logger.
-
-#### Tools
-
-| Tool | Description |
-| ---- | ----------- |
-|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.|
-|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
-
-#### Testing
-
-Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:
-
-* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook
-* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
-
-```go
-import(
-  "github.com/sirupsen/logrus"
-  "github.com/sirupsen/logrus/hooks/test"
-  "github.com/stretchr/testify/assert"
-  "testing"
-)
-
-func TestSomething(t*testing.T){
-  logger, hook := test.NewNullLogger()
-  logger.Error("Helloerror")
-
-  assert.Equal(t, 1, len(hook.Entries))
-  assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level)
-  assert.Equal(t, "Helloerror", hook.LastEntry().Message)
-
-  hook.Reset()
-  assert.Nil(t, hook.LastEntry())
-}
-```
-
-#### Fatal handlers
-
-Logrus can register one or more functions that will be called when any `fatal`
-level message is logged. The registered handlers will be executed before
-logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need
-to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.
-
-```
-...
-handler := func() {
-  // gracefully shutdown something...
-}
-logrus.RegisterExitHandler(handler)
-...
-```
-
-#### Thread safety
-
-By default, Logger is protected by a mutex for concurrent writes. The mutex is held when calling hooks and writing logs.
-If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
-
-Situation when locking is not needed includes:
-
-* You have no hooks registered, or hooks calling is already thread-safe.
-
-* Writing to logger.Out is already thread-safe, for example:
-
-  1) logger.Out is protected by locks.
-
-  2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing)
-
-     (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)
diff --git a/vendor/github.com/sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go
deleted file mode 100644
index 8af9063..0000000
--- a/vendor/github.com/sirupsen/logrus/alt_exit.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package logrus
-
-// The following code was sourced and modified from the
-// https://github.com/tebeka/atexit package governed by the following license:
-//
-// Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of
-// this software and associated documentation files (the "Software"), to deal in
-// the Software without restriction, including without limitation the rights to
-// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-// the Software, and to permit persons to whom the Software is furnished to do so,
-// subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-import (
-	"fmt"
-	"os"
-)
-
-var handlers = []func(){}
-
-func runHandler(handler func()) {
-	defer func() {
-		if err := recover(); err != nil {
-			fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err)
-		}
-	}()
-
-	handler()
-}
-
-func runHandlers() {
-	for _, handler := range handlers {
-		runHandler(handler)
-	}
-}
-
-// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code)
-func Exit(code int) {
-	runHandlers()
-	os.Exit(code)
-}
-
-// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
-// all handlers. The handlers will also be invoked when any Fatal log entry is
-// made.
-//
-// This method is useful when a caller wishes to use logrus to log a fatal
-// message but also needs to gracefully shutdown. An example usecase could be
-// closing database connections, or sending a alert that the application is
-// closing.
-func RegisterExitHandler(handler func()) {
-	handlers = append(handlers, handler)
-}
diff --git a/vendor/github.com/sirupsen/logrus/appveyor.yml b/vendor/github.com/sirupsen/logrus/appveyor.yml
deleted file mode 100644
index 96c2ce1..0000000
--- a/vendor/github.com/sirupsen/logrus/appveyor.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-version: "{build}"
-platform: x64
-clone_folder: c:\gopath\src\github.com\sirupsen\logrus
-environment:  
-  GOPATH: c:\gopath
-branches:  
-  only:
-    - master
-install:  
-  - set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
-  - go version
-build_script:  
-  - go get -t
-  - go test
diff --git a/vendor/github.com/sirupsen/logrus/doc.go b/vendor/github.com/sirupsen/logrus/doc.go
deleted file mode 100644
index da67aba..0000000
--- a/vendor/github.com/sirupsen/logrus/doc.go
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-Package logrus is a structured logger for Go, completely API compatible with the standard library logger.
-
-
-The simplest way to use Logrus is simply the package-level exported logger:
-
-  package main
-
-  import (
-    log "github.com/sirupsen/logrus"
-  )
-
-  func main() {
-    log.WithFields(log.Fields{
-      "animal": "walrus",
-      "number": 1,
-      "size":   10,
-    }).Info("A walrus appears")
-  }
-
-Output:
-  time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
-
-For a full guide visit https://github.com/sirupsen/logrus
-*/
-package logrus
diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go
deleted file mode 100644
index df6d188..0000000
--- a/vendor/github.com/sirupsen/logrus/entry.go
+++ /dev/null
@@ -1,393 +0,0 @@
-package logrus
-
-import (
-	"bytes"
-	"fmt"
-	"os"
-	"reflect"
-	"runtime"
-	"strings"
-	"sync"
-	"time"
-)
-
-var (
-	bufferPool *sync.Pool
-
-	// qualified package name, cached at first use
-	logrusPackage string
-
-	// Positions in the call stack when tracing to report the calling method
-	minimumCallerDepth int
-
-	// Used for caller information initialisation
-	callerInitOnce sync.Once
-)
-
-const (
-	maximumCallerDepth int = 25
-	knownLogrusFrames  int = 4
-)
-
-func init() {
-	bufferPool = &sync.Pool{
-		New: func() interface{} {
-			return new(bytes.Buffer)
-		},
-	}
-
-	// start at the bottom of the stack before the package-name cache is primed
-	minimumCallerDepth = 1
-}
-
-// Defines the key when adding errors using WithError.
-var ErrorKey = "error"
-
-// An entry is the final or intermediate Logrus logging entry. It contains all
-// the fields passed with WithField{,s}. It's finally logged when Trace, Debug,
-// Info, Warn, Error, Fatal or Panic is called on it. These objects can be
-// reused and passed around as much as you wish to avoid field duplication.
-type Entry struct {
-	Logger *Logger
-
-	// Contains all the fields set by the user.
-	Data Fields
-
-	// Time at which the log entry was created
-	Time time.Time
-
-	// Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic
-	// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
-	Level Level
-
-	// Calling method, with package name
-	Caller *runtime.Frame
-
-	// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
-	Message string
-
-	// When formatter is called in entry.log(), a Buffer may be set to entry
-	Buffer *bytes.Buffer
-
-	// err may contain a field formatting error
-	err string
-}
-
-func NewEntry(logger *Logger) *Entry {
-	return &Entry{
-		Logger: logger,
-		// Default is three fields, plus one optional.  Give a little extra room.
-		Data: make(Fields, 6),
-	}
-}
-
-// Returns the string representation from the reader and ultimately the
-// formatter.
-func (entry *Entry) String() (string, error) {
-	serialized, err := entry.Logger.Formatter.Format(entry)
-	if err != nil {
-		return "", err
-	}
-	str := string(serialized)
-	return str, nil
-}
-
-// Add an error as single field (using the key defined in ErrorKey) to the Entry.
-func (entry *Entry) WithError(err error) *Entry {
-	return entry.WithField(ErrorKey, err)
-}
-
-// Add a single field to the Entry.
-func (entry *Entry) WithField(key string, value interface{}) *Entry {
-	return entry.WithFields(Fields{key: value})
-}
-
-// Add a map of fields to the Entry.
-func (entry *Entry) WithFields(fields Fields) *Entry {
-	data := make(Fields, len(entry.Data)+len(fields))
-	for k, v := range entry.Data {
-		data[k] = v
-	}
-	fieldErr := entry.err
-	for k, v := range fields {
-		isErrField := false
-		if t := reflect.TypeOf(v); t != nil {
-			switch t.Kind() {
-			case reflect.Func:
-				isErrField = true
-			case reflect.Ptr:
-				isErrField = t.Elem().Kind() == reflect.Func
-			}
-		}
-		if isErrField {
-			tmp := fmt.Sprintf("can not add field %q", k)
-			if fieldErr != "" {
-				fieldErr = entry.err + ", " + tmp
-			} else {
-				fieldErr = tmp
-			}
-		} else {
-			data[k] = v
-		}
-	}
-	return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr}
-}
-
-// Overrides the time of the Entry.
-func (entry *Entry) WithTime(t time.Time) *Entry {
-	return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err}
-}
-
-// getPackageName reduces a fully qualified function name to the package name
-// There really ought to be to be a better way...
-func getPackageName(f string) string {
-	for {
-		lastPeriod := strings.LastIndex(f, ".")
-		lastSlash := strings.LastIndex(f, "/")
-		if lastPeriod > lastSlash {
-			f = f[:lastPeriod]
-		} else {
-			break
-		}
-	}
-
-	return f
-}
-
-// getCaller retrieves the name of the first non-logrus calling function
-func getCaller() *runtime.Frame {
-	// Restrict the lookback frames to avoid runaway lookups
-	pcs := make([]uintptr, maximumCallerDepth)
-	depth := runtime.Callers(minimumCallerDepth, pcs)
-	frames := runtime.CallersFrames(pcs[:depth])
-
-	// cache this package's fully-qualified name
-	callerInitOnce.Do(func() {
-		logrusPackage = getPackageName(runtime.FuncForPC(pcs[0]).Name())
-
-		// now that we have the cache, we can skip a minimum count of known-logrus functions
-		// XXX this is dubious, the number of frames may vary store an entry in a logger interface
-		minimumCallerDepth = knownLogrusFrames
-	})
-
-	for f, again := frames.Next(); again; f, again = frames.Next() {
-		pkg := getPackageName(f.Function)
-
-		// If the caller isn't part of this package, we're done
-		if pkg != logrusPackage {
-			return &f
-		}
-	}
-
-	// if we got here, we failed to find the caller's context
-	return nil
-}
-
-func (entry Entry) HasCaller() (has bool) {
-	return entry.Logger != nil &&
-		entry.Logger.ReportCaller &&
-		entry.Caller != nil
-}
-
-// This function is not declared with a pointer value because otherwise
-// race conditions will occur when using multiple goroutines
-func (entry Entry) log(level Level, msg string) {
-	var buffer *bytes.Buffer
-
-	// Default to now, but allow users to override if they want.
-	//
-	// We don't have to worry about polluting future calls to Entry#log()
-	// with this assignment because this function is declared with a
-	// non-pointer receiver.
-	if entry.Time.IsZero() {
-		entry.Time = time.Now()
-	}
-
-	entry.Level = level
-	entry.Message = msg
-	if entry.Logger.ReportCaller {
-		entry.Caller = getCaller()
-	}
-
-	entry.fireHooks()
-
-	buffer = bufferPool.Get().(*bytes.Buffer)
-	buffer.Reset()
-	defer bufferPool.Put(buffer)
-	entry.Buffer = buffer
-
-	entry.write()
-
-	entry.Buffer = nil
-
-	// To avoid Entry#log() returning a value that only would make sense for
-	// panic() to use in Entry#Panic(), we avoid the allocation by checking
-	// directly here.
-	if level <= PanicLevel {
-		panic(&entry)
-	}
-}
-
-func (entry *Entry) fireHooks() {
-	entry.Logger.mu.Lock()
-	defer entry.Logger.mu.Unlock()
-	err := entry.Logger.Hooks.Fire(entry.Level, entry)
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
-	}
-}
-
-func (entry *Entry) write() {
-	entry.Logger.mu.Lock()
-	defer entry.Logger.mu.Unlock()
-	serialized, err := entry.Logger.Formatter.Format(entry)
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
-	} else {
-		_, err = entry.Logger.Out.Write(serialized)
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
-		}
-	}
-}
-
-func (entry *Entry) Log(level Level, args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(level) {
-		entry.log(level, fmt.Sprint(args...))
-	}
-}
-
-func (entry *Entry) Trace(args ...interface{}) {
-	entry.Log(TraceLevel, args...)
-}
-
-func (entry *Entry) Debug(args ...interface{}) {
-	entry.Log(DebugLevel, args...)
-}
-
-func (entry *Entry) Print(args ...interface{}) {
-	entry.Info(args...)
-}
-
-func (entry *Entry) Info(args ...interface{}) {
-	entry.Log(InfoLevel, args...)
-}
-
-func (entry *Entry) Warn(args ...interface{}) {
-	entry.Log(WarnLevel, args...)
-}
-
-func (entry *Entry) Warning(args ...interface{}) {
-	entry.Warn(args...)
-}
-
-func (entry *Entry) Error(args ...interface{}) {
-	entry.Log(ErrorLevel, args...)
-}
-
-func (entry *Entry) Fatal(args ...interface{}) {
-	entry.Log(FatalLevel, args...)
-	entry.Logger.Exit(1)
-}
-
-func (entry *Entry) Panic(args ...interface{}) {
-	entry.Log(PanicLevel, args...)
-	panic(fmt.Sprint(args...))
-}
-
-// Entry Printf family functions
-
-func (entry *Entry) Logf(level Level, format string, args ...interface{}) {
-	entry.Log(level, fmt.Sprintf(format, args...))
-}
-
-func (entry *Entry) Tracef(format string, args ...interface{}) {
-	entry.Logf(TraceLevel, format, args...)
-}
-
-func (entry *Entry) Debugf(format string, args ...interface{}) {
-	entry.Logf(DebugLevel, format, args...)
-}
-
-func (entry *Entry) Infof(format string, args ...interface{}) {
-	entry.Logf(InfoLevel, format, args...)
-}
-
-func (entry *Entry) Printf(format string, args ...interface{}) {
-	entry.Infof(format, args...)
-}
-
-func (entry *Entry) Warnf(format string, args ...interface{}) {
-	entry.Logf(WarnLevel, format, args...)
-}
-
-func (entry *Entry) Warningf(format string, args ...interface{}) {
-	entry.Warnf(format, args...)
-}
-
-func (entry *Entry) Errorf(format string, args ...interface{}) {
-	entry.Logf(ErrorLevel, format, args...)
-}
-
-func (entry *Entry) Fatalf(format string, args ...interface{}) {
-	entry.Logf(FatalLevel, format, args...)
-	entry.Logger.Exit(1)
-}
-
-func (entry *Entry) Panicf(format string, args ...interface{}) {
-	entry.Logf(PanicLevel, format, args...)
-}
-
-// Entry Println family functions
-
-func (entry *Entry) Logln(level Level, args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(level) {
-		entry.Log(level, entry.sprintlnn(args...))
-	}
-}
-
-func (entry *Entry) Traceln(args ...interface{}) {
-	entry.Logln(TraceLevel, args...)
-}
-
-func (entry *Entry) Debugln(args ...interface{}) {
-	entry.Logln(DebugLevel, args...)
-}
-
-func (entry *Entry) Infoln(args ...interface{}) {
-	entry.Logln(InfoLevel, args...)
-}
-
-func (entry *Entry) Println(args ...interface{}) {
-	entry.Infoln(args...)
-}
-
-func (entry *Entry) Warnln(args ...interface{}) {
-	entry.Logln(WarnLevel, args...)
-}
-
-func (entry *Entry) Warningln(args ...interface{}) {
-	entry.Warnln(args...)
-}
-
-func (entry *Entry) Errorln(args ...interface{}) {
-	entry.Logln(ErrorLevel, args...)
-}
-
-func (entry *Entry) Fatalln(args ...interface{}) {
-	entry.Logln(FatalLevel, args...)
-	entry.Logger.Exit(1)
-}
-
-func (entry *Entry) Panicln(args ...interface{}) {
-	entry.Logln(PanicLevel, args...)
-}
-
-// Sprintlnn => Sprint no newline. This is to get the behavior of how
-// fmt.Sprintln where spaces are always added between operands, regardless of
-// their type. Instead of vendoring the Sprintln implementation to spare a
-// string allocation, we do the simplest thing.
-func (entry *Entry) sprintlnn(args ...interface{}) string {
-	msg := fmt.Sprintln(args...)
-	return msg[:len(msg)-1]
-}
diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go
deleted file mode 100644
index 7342613..0000000
--- a/vendor/github.com/sirupsen/logrus/exported.go
+++ /dev/null
@@ -1,219 +0,0 @@
-package logrus
-
-import (
-	"io"
-	"time"
-)
-
-var (
-	// std is the name of the standard logger in stdlib `log`
-	std = New()
-)
-
-func StandardLogger() *Logger {
-	return std
-}
-
-// SetOutput sets the standard logger output.
-func SetOutput(out io.Writer) {
-	std.SetOutput(out)
-}
-
-// SetFormatter sets the standard logger formatter.
-func SetFormatter(formatter Formatter) {
-	std.SetFormatter(formatter)
-}
-
-// SetReportCaller sets whether the standard logger will include the calling
-// method as a field.
-func SetReportCaller(include bool) {
-	std.SetReportCaller(include)
-}
-
-// SetLevel sets the standard logger level.
-func SetLevel(level Level) {
-	std.SetLevel(level)
-}
-
-// GetLevel returns the standard logger level.
-func GetLevel() Level {
-	return std.GetLevel()
-}
-
-// IsLevelEnabled checks if the log level of the standard logger is greater than the level param
-func IsLevelEnabled(level Level) bool {
-	return std.IsLevelEnabled(level)
-}
-
-// AddHook adds a hook to the standard logger hooks.
-func AddHook(hook Hook) {
-	std.AddHook(hook)
-}
-
-// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
-func WithError(err error) *Entry {
-	return std.WithField(ErrorKey, err)
-}
-
-// WithField creates an entry from the standard logger and adds a field to
-// it. If you want multiple fields, use `WithFields`.
-//
-// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
-// or Panic on the Entry it returns.
-func WithField(key string, value interface{}) *Entry {
-	return std.WithField(key, value)
-}
-
-// WithFields creates an entry from the standard logger and adds multiple
-// fields to it. This is simply a helper for `WithField`, invoking it
-// once for each field.
-//
-// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
-// or Panic on the Entry it returns.
-func WithFields(fields Fields) *Entry {
-	return std.WithFields(fields)
-}
-
-// WithTime creats an entry from the standard logger and overrides the time of
-// logs generated with it.
-//
-// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
-// or Panic on the Entry it returns.
-func WithTime(t time.Time) *Entry {
-	return std.WithTime(t)
-}
-
-// Trace logs a message at level Trace on the standard logger.
-func Trace(args ...interface{}) {
-	std.Trace(args...)
-}
-
-// Debug logs a message at level Debug on the standard logger.
-func Debug(args ...interface{}) {
-	std.Debug(args...)
-}
-
-// Print logs a message at level Info on the standard logger.
-func Print(args ...interface{}) {
-	std.Print(args...)
-}
-
-// Info logs a message at level Info on the standard logger.
-func Info(args ...interface{}) {
-	std.Info(args...)
-}
-
-// Warn logs a message at level Warn on the standard logger.
-func Warn(args ...interface{}) {
-	std.Warn(args...)
-}
-
-// Warning logs a message at level Warn on the standard logger.
-func Warning(args ...interface{}) {
-	std.Warning(args...)
-}
-
-// Error logs a message at level Error on the standard logger.
-func Error(args ...interface{}) {
-	std.Error(args...)
-}
-
-// Panic logs a message at level Panic on the standard logger.
-func Panic(args ...interface{}) {
-	std.Panic(args...)
-}
-
-// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
-func Fatal(args ...interface{}) {
-	std.Fatal(args...)
-}
-
-// Tracef logs a message at level Trace on the standard logger.
-func Tracef(format string, args ...interface{}) {
-	std.Tracef(format, args...)
-}
-
-// Debugf logs a message at level Debug on the standard logger.
-func Debugf(format string, args ...interface{}) {
-	std.Debugf(format, args...)
-}
-
-// Printf logs a message at level Info on the standard logger.
-func Printf(format string, args ...interface{}) {
-	std.Printf(format, args...)
-}
-
-// Infof logs a message at level Info on the standard logger.
-func Infof(format string, args ...interface{}) {
-	std.Infof(format, args...)
-}
-
-// Warnf logs a message at level Warn on the standard logger.
-func Warnf(format string, args ...interface{}) {
-	std.Warnf(format, args...)
-}
-
-// Warningf logs a message at level Warn on the standard logger.
-func Warningf(format string, args ...interface{}) {
-	std.Warningf(format, args...)
-}
-
-// Errorf logs a message at level Error on the standard logger.
-func Errorf(format string, args ...interface{}) {
-	std.Errorf(format, args...)
-}
-
-// Panicf logs a message at level Panic on the standard logger.
-func Panicf(format string, args ...interface{}) {
-	std.Panicf(format, args...)
-}
-
-// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
-func Fatalf(format string, args ...interface{}) {
-	std.Fatalf(format, args...)
-}
-
-// Traceln logs a message at level Trace on the standard logger.
-func Traceln(args ...interface{}) {
-	std.Traceln(args...)
-}
-
-// Debugln logs a message at level Debug on the standard logger.
-func Debugln(args ...interface{}) {
-	std.Debugln(args...)
-}
-
-// Println logs a message at level Info on the standard logger.
-func Println(args ...interface{}) {
-	std.Println(args...)
-}
-
-// Infoln logs a message at level Info on the standard logger.
-func Infoln(args ...interface{}) {
-	std.Infoln(args...)
-}
-
-// Warnln logs a message at level Warn on the standard logger.
-func Warnln(args ...interface{}) {
-	std.Warnln(args...)
-}
-
-// Warningln logs a message at level Warn on the standard logger.
-func Warningln(args ...interface{}) {
-	std.Warningln(args...)
-}
-
-// Errorln logs a message at level Error on the standard logger.
-func Errorln(args ...interface{}) {
-	std.Errorln(args...)
-}
-
-// Panicln logs a message at level Panic on the standard logger.
-func Panicln(args ...interface{}) {
-	std.Panicln(args...)
-}
-
-// Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
-func Fatalln(args ...interface{}) {
-	std.Fatalln(args...)
-}
diff --git a/vendor/github.com/sirupsen/logrus/formatter.go b/vendor/github.com/sirupsen/logrus/formatter.go
deleted file mode 100644
index 4088837..0000000
--- a/vendor/github.com/sirupsen/logrus/formatter.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package logrus
-
-import "time"
-
-// Default key names for the default fields
-const (
-	defaultTimestampFormat = time.RFC3339
-	FieldKeyMsg            = "msg"
-	FieldKeyLevel          = "level"
-	FieldKeyTime           = "time"
-	FieldKeyLogrusError    = "logrus_error"
-	FieldKeyFunc           = "func"
-	FieldKeyFile           = "file"
-)
-
-// The Formatter interface is used to implement a custom Formatter. It takes an
-// `Entry`. It exposes all the fields, including the default ones:
-//
-// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
-// * `entry.Data["time"]`. The timestamp.
-// * `entry.Data["level"]. The level the entry was logged at.
-//
-// Any additional fields added with `WithField` or `WithFields` are also in
-// `entry.Data`. Format is expected to return an array of bytes which are then
-// logged to `logger.Out`.
-type Formatter interface {
-	Format(*Entry) ([]byte, error)
-}
-
-// This is to not silently overwrite `time`, `msg`, `func` and `level` fields when
-// dumping it. If this code wasn't there doing:
-//
-//  logrus.WithField("level", 1).Info("hello")
-//
-// Would just silently drop the user provided level. Instead with this code
-// it'll logged as:
-//
-//  {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
-//
-// It's not exported because it's still using Data in an opinionated way. It's to
-// avoid code duplication between the two default formatters.
-func prefixFieldClashes(data Fields, fieldMap FieldMap, reportCaller bool) {
-	timeKey := fieldMap.resolve(FieldKeyTime)
-	if t, ok := data[timeKey]; ok {
-		data["fields."+timeKey] = t
-		delete(data, timeKey)
-	}
-
-	msgKey := fieldMap.resolve(FieldKeyMsg)
-	if m, ok := data[msgKey]; ok {
-		data["fields."+msgKey] = m
-		delete(data, msgKey)
-	}
-
-	levelKey := fieldMap.resolve(FieldKeyLevel)
-	if l, ok := data[levelKey]; ok {
-		data["fields."+levelKey] = l
-		delete(data, levelKey)
-	}
-
-	logrusErrKey := fieldMap.resolve(FieldKeyLogrusError)
-	if l, ok := data[logrusErrKey]; ok {
-		data["fields."+logrusErrKey] = l
-		delete(data, logrusErrKey)
-	}
-
-	// If reportCaller is not set, 'func' will not conflict.
-	if reportCaller {
-		funcKey := fieldMap.resolve(FieldKeyFunc)
-		if l, ok := data[funcKey]; ok {
-			data["fields."+funcKey] = l
-		}
-		fileKey := fieldMap.resolve(FieldKeyFile)
-		if l, ok := data[fileKey]; ok {
-			data["fields."+fileKey] = l
-		}
-	}
-}
diff --git a/vendor/github.com/sirupsen/logrus/go.mod b/vendor/github.com/sirupsen/logrus/go.mod
deleted file mode 100644
index 94574cc..0000000
--- a/vendor/github.com/sirupsen/logrus/go.mod
+++ /dev/null
@@ -1,11 +0,0 @@
-module github.com/sirupsen/logrus
-
-require (
-	github.com/davecgh/go-spew v1.1.1 // indirect
-	github.com/konsorten/go-windows-terminal-sequences v1.0.1
-	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/stretchr/objx v0.1.1 // indirect
-	github.com/stretchr/testify v1.2.2
-	golang.org/x/crypto v0.0.0-20180904163835-0709b304e793
-	golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33
-)
diff --git a/vendor/github.com/sirupsen/logrus/go.sum b/vendor/github.com/sirupsen/logrus/go.sum
deleted file mode 100644
index 133d34a..0000000
--- a/vendor/github.com/sirupsen/logrus/go.sum
+++ /dev/null
@@ -1,15 +0,0 @@
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe h1:CHRGQ8V7OlCYtwaKPJi3iA7J+YdNKdo8j7nG5IgDhjs=
-github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
diff --git a/vendor/github.com/sirupsen/logrus/hooks.go b/vendor/github.com/sirupsen/logrus/hooks.go
deleted file mode 100644
index 3f151cd..0000000
--- a/vendor/github.com/sirupsen/logrus/hooks.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package logrus
-
-// A hook to be fired when logging on the logging levels returned from
-// `Levels()` on your implementation of the interface. Note that this is not
-// fired in a goroutine or a channel with workers, you should handle such
-// functionality yourself if your call is non-blocking and you don't wish for
-// the logging calls for levels returned from `Levels()` to block.
-type Hook interface {
-	Levels() []Level
-	Fire(*Entry) error
-}
-
-// Internal type for storing the hooks on a logger instance.
-type LevelHooks map[Level][]Hook
-
-// Add a hook to an instance of logger. This is called with
-// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
-func (hooks LevelHooks) Add(hook Hook) {
-	for _, level := range hook.Levels() {
-		hooks[level] = append(hooks[level], hook)
-	}
-}
-
-// Fire all the hooks for the passed level. Used by `entry.log` to fire
-// appropriate hooks for a log entry.
-func (hooks LevelHooks) Fire(level Level, entry *Entry) error {
-	for _, hook := range hooks[level] {
-		if err := hook.Fire(entry); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go
deleted file mode 100644
index 2605753..0000000
--- a/vendor/github.com/sirupsen/logrus/json_formatter.go
+++ /dev/null
@@ -1,105 +0,0 @@
-package logrus
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-)
-
-type fieldKey string
-
-// FieldMap allows customization of the key names for default fields.
-type FieldMap map[fieldKey]string
-
-func (f FieldMap) resolve(key fieldKey) string {
-	if k, ok := f[key]; ok {
-		return k
-	}
-
-	return string(key)
-}
-
-// JSONFormatter formats logs into parsable json
-type JSONFormatter struct {
-	// TimestampFormat sets the format used for marshaling timestamps.
-	TimestampFormat string
-
-	// DisableTimestamp allows disabling automatic timestamps in output
-	DisableTimestamp bool
-
-	// DataKey allows users to put all the log entry parameters into a nested dictionary at a given key.
-	DataKey string
-
-	// FieldMap allows users to customize the names of keys for default fields.
-	// As an example:
-	// formatter := &JSONFormatter{
-	//   	FieldMap: FieldMap{
-	// 		 FieldKeyTime:  "@timestamp",
-	// 		 FieldKeyLevel: "@level",
-	// 		 FieldKeyMsg:   "@message",
-	// 		 FieldKeyFunc:  "@caller",
-	//    },
-	// }
-	FieldMap FieldMap
-
-	// PrettyPrint will indent all json logs
-	PrettyPrint bool
-}
-
-// Format renders a single log entry
-func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
-	data := make(Fields, len(entry.Data)+4)
-	for k, v := range entry.Data {
-		switch v := v.(type) {
-		case error:
-			// Otherwise errors are ignored by `encoding/json`
-			// https://github.com/sirupsen/logrus/issues/137
-			data[k] = v.Error()
-		default:
-			data[k] = v
-		}
-	}
-
-	if f.DataKey != "" {
-		newData := make(Fields, 4)
-		newData[f.DataKey] = data
-		data = newData
-	}
-
-	prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
-
-	timestampFormat := f.TimestampFormat
-	if timestampFormat == "" {
-		timestampFormat = defaultTimestampFormat
-	}
-
-	if entry.err != "" {
-		data[f.FieldMap.resolve(FieldKeyLogrusError)] = entry.err
-	}
-	if !f.DisableTimestamp {
-		data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
-	}
-	data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
-	data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
-	if entry.HasCaller() {
-		data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller.Function
-		data[f.FieldMap.resolve(FieldKeyFile)] = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
-	}
-
-	var b *bytes.Buffer
-	if entry.Buffer != nil {
-		b = entry.Buffer
-	} else {
-		b = &bytes.Buffer{}
-	}
-
-	encoder := json.NewEncoder(b)
-	if f.PrettyPrint {
-		encoder.SetIndent("", "  ")
-	}
-	if err := encoder.Encode(data); err != nil {
-		return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
-	}
-
-	return b.Bytes(), nil
-}
diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go
deleted file mode 100644
index 9bf64e2..0000000
--- a/vendor/github.com/sirupsen/logrus/logger.go
+++ /dev/null
@@ -1,343 +0,0 @@
-package logrus
-
-import (
-	"io"
-	"os"
-	"sync"
-	"sync/atomic"
-	"time"
-)
-
-type Logger struct {
-	// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
-	// file, or leave it default which is `os.Stderr`. You can also set this to
-	// something more adventurous, such as logging to Kafka.
-	Out io.Writer
-	// Hooks for the logger instance. These allow firing events based on logging
-	// levels and log entries. For example, to send errors to an error tracking
-	// service, log to StatsD or dump the core on fatal errors.
-	Hooks LevelHooks
-	// All log entries pass through the formatter before logged to Out. The
-	// included formatters are `TextFormatter` and `JSONFormatter` for which
-	// TextFormatter is the default. In development (when a TTY is attached) it
-	// logs with colors, but to a file it wouldn't. You can easily implement your
-	// own that implements the `Formatter` interface, see the `README` or included
-	// formatters for examples.
-	Formatter Formatter
-
-	// Flag for whether to log caller info (off by default)
-	ReportCaller bool
-
-	// The logging level the logger should log at. This is typically (and defaults
-	// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
-	// logged.
-	Level Level
-	// Used to sync writing to the log. Locking is enabled by Default
-	mu MutexWrap
-	// Reusable empty entry
-	entryPool sync.Pool
-	// Function to exit the application, defaults to `os.Exit()`
-	ExitFunc exitFunc
-}
-
-type exitFunc func(int)
-
-type MutexWrap struct {
-	lock     sync.Mutex
-	disabled bool
-}
-
-func (mw *MutexWrap) Lock() {
-	if !mw.disabled {
-		mw.lock.Lock()
-	}
-}
-
-func (mw *MutexWrap) Unlock() {
-	if !mw.disabled {
-		mw.lock.Unlock()
-	}
-}
-
-func (mw *MutexWrap) Disable() {
-	mw.disabled = true
-}
-
-// Creates a new logger. Configuration should be set by changing `Formatter`,
-// `Out` and `Hooks` directly on the default logger instance. You can also just
-// instantiate your own:
-//
-//    var log = &Logger{
-//      Out: os.Stderr,
-//      Formatter: new(JSONFormatter),
-//      Hooks: make(LevelHooks),
-//      Level: logrus.DebugLevel,
-//    }
-//
-// It's recommended to make this a global instance called `log`.
-func New() *Logger {
-	return &Logger{
-		Out:          os.Stderr,
-		Formatter:    new(TextFormatter),
-		Hooks:        make(LevelHooks),
-		Level:        InfoLevel,
-		ExitFunc:     os.Exit,
-		ReportCaller: false,
-	}
-}
-
-func (logger *Logger) newEntry() *Entry {
-	entry, ok := logger.entryPool.Get().(*Entry)
-	if ok {
-		return entry
-	}
-	return NewEntry(logger)
-}
-
-func (logger *Logger) releaseEntry(entry *Entry) {
-	entry.Data = map[string]interface{}{}
-	logger.entryPool.Put(entry)
-}
-
-// Adds a field to the log entry, note that it doesn't log until you call
-// Debug, Print, Info, Warn, Error, Fatal or Panic. It only creates a log entry.
-// If you want multiple fields, use `WithFields`.
-func (logger *Logger) WithField(key string, value interface{}) *Entry {
-	entry := logger.newEntry()
-	defer logger.releaseEntry(entry)
-	return entry.WithField(key, value)
-}
-
-// Adds a struct of fields to the log entry. All it does is call `WithField` for
-// each `Field`.
-func (logger *Logger) WithFields(fields Fields) *Entry {
-	entry := logger.newEntry()
-	defer logger.releaseEntry(entry)
-	return entry.WithFields(fields)
-}
-
-// Add an error as single field to the log entry.  All it does is call
-// `WithError` for the given `error`.
-func (logger *Logger) WithError(err error) *Entry {
-	entry := logger.newEntry()
-	defer logger.releaseEntry(entry)
-	return entry.WithError(err)
-}
-
-// Overrides the time of the log entry.
-func (logger *Logger) WithTime(t time.Time) *Entry {
-	entry := logger.newEntry()
-	defer logger.releaseEntry(entry)
-	return entry.WithTime(t)
-}
-
-func (logger *Logger) Logf(level Level, format string, args ...interface{}) {
-	if logger.IsLevelEnabled(level) {
-		entry := logger.newEntry()
-		entry.Logf(level, format, args...)
-		logger.releaseEntry(entry)
-	}
-}
-
-func (logger *Logger) Tracef(format string, args ...interface{}) {
-	logger.Logf(TraceLevel, format, args...)
-}
-
-func (logger *Logger) Debugf(format string, args ...interface{}) {
-	logger.Logf(DebugLevel, format, args...)
-}
-
-func (logger *Logger) Infof(format string, args ...interface{}) {
-	logger.Logf(InfoLevel, format, args...)
-}
-
-func (logger *Logger) Printf(format string, args ...interface{}) {
-	entry := logger.newEntry()
-	entry.Printf(format, args...)
-	logger.releaseEntry(entry)
-}
-
-func (logger *Logger) Warnf(format string, args ...interface{}) {
-	logger.Logf(WarnLevel, format, args...)
-}
-
-func (logger *Logger) Warningf(format string, args ...interface{}) {
-	logger.Warnf(format, args...)
-}
-
-func (logger *Logger) Errorf(format string, args ...interface{}) {
-	logger.Logf(ErrorLevel, format, args...)
-}
-
-func (logger *Logger) Fatalf(format string, args ...interface{}) {
-	logger.Logf(FatalLevel, format, args...)
-	logger.Exit(1)
-}
-
-func (logger *Logger) Panicf(format string, args ...interface{}) {
-	logger.Logf(PanicLevel, format, args...)
-}
-
-func (logger *Logger) Log(level Level, args ...interface{}) {
-	if logger.IsLevelEnabled(level) {
-		entry := logger.newEntry()
-		entry.Log(level, args...)
-		logger.releaseEntry(entry)
-	}
-}
-
-func (logger *Logger) Trace(args ...interface{}) {
-	logger.Log(TraceLevel, args...)
-}
-
-func (logger *Logger) Debug(args ...interface{}) {
-	logger.Log(DebugLevel, args...)
-}
-
-func (logger *Logger) Info(args ...interface{}) {
-	logger.Log(InfoLevel, args...)
-}
-
-func (logger *Logger) Print(args ...interface{}) {
-	entry := logger.newEntry()
-	entry.Info(args...)
-	logger.releaseEntry(entry)
-}
-
-func (logger *Logger) Warn(args ...interface{}) {
-	logger.Log(WarnLevel, args...)
-}
-
-func (logger *Logger) Warning(args ...interface{}) {
-	logger.Warn(args...)
-}
-
-func (logger *Logger) Error(args ...interface{}) {
-	logger.Log(ErrorLevel, args...)
-}
-
-func (logger *Logger) Fatal(args ...interface{}) {
-	logger.Log(FatalLevel, args...)
-	logger.Exit(1)
-}
-
-func (logger *Logger) Panic(args ...interface{}) {
-	logger.Log(PanicLevel, args...)
-}
-
-func (logger *Logger) Logln(level Level, args ...interface{}) {
-	if logger.IsLevelEnabled(level) {
-		entry := logger.newEntry()
-		entry.Logln(level, args...)
-		logger.releaseEntry(entry)
-	}
-}
-
-func (logger *Logger) Traceln(args ...interface{}) {
-	logger.Logln(TraceLevel, args...)
-}
-
-func (logger *Logger) Debugln(args ...interface{}) {
-	logger.Logln(DebugLevel, args...)
-}
-
-func (logger *Logger) Infoln(args ...interface{}) {
-	logger.Logln(InfoLevel, args...)
-}
-
-func (logger *Logger) Println(args ...interface{}) {
-	entry := logger.newEntry()
-	entry.Println(args...)
-	logger.releaseEntry(entry)
-}
-
-func (logger *Logger) Warnln(args ...interface{}) {
-	logger.Logln(WarnLevel, args...)
-}
-
-func (logger *Logger) Warningln(args ...interface{}) {
-	logger.Warn(args...)
-}
-
-func (logger *Logger) Errorln(args ...interface{}) {
-	logger.Logln(ErrorLevel, args...)
-}
-
-func (logger *Logger) Fatalln(args ...interface{}) {
-	logger.Logln(FatalLevel, args...)
-	logger.Exit(1)
-}
-
-func (logger *Logger) Panicln(args ...interface{}) {
-	logger.Logln(PanicLevel, args...)
-}
-
-func (logger *Logger) Exit(code int) {
-	runHandlers()
-	if logger.ExitFunc == nil {
-		logger.ExitFunc = os.Exit
-	}
-	logger.ExitFunc(code)
-}
-
-//When file is opened with appending mode, it's safe to
-//write concurrently to a file (within 4k message on Linux).
-//In these cases user can choose to disable the lock.
-func (logger *Logger) SetNoLock() {
-	logger.mu.Disable()
-}
-
-func (logger *Logger) level() Level {
-	return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
-}
-
-// SetLevel sets the logger level.
-func (logger *Logger) SetLevel(level Level) {
-	atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
-}
-
-// GetLevel returns the logger level.
-func (logger *Logger) GetLevel() Level {
-	return logger.level()
-}
-
-// AddHook adds a hook to the logger hooks.
-func (logger *Logger) AddHook(hook Hook) {
-	logger.mu.Lock()
-	defer logger.mu.Unlock()
-	logger.Hooks.Add(hook)
-}
-
-// IsLevelEnabled checks if the log level of the logger is greater than the level param
-func (logger *Logger) IsLevelEnabled(level Level) bool {
-	return logger.level() >= level
-}
-
-// SetFormatter sets the logger formatter.
-func (logger *Logger) SetFormatter(formatter Formatter) {
-	logger.mu.Lock()
-	defer logger.mu.Unlock()
-	logger.Formatter = formatter
-}
-
-// SetOutput sets the logger output.
-func (logger *Logger) SetOutput(output io.Writer) {
-	logger.mu.Lock()
-	defer logger.mu.Unlock()
-	logger.Out = output
-}
-
-func (logger *Logger) SetReportCaller(reportCaller bool) {
-	logger.mu.Lock()
-	defer logger.mu.Unlock()
-	logger.ReportCaller = reportCaller
-}
-
-// ReplaceHooks replaces the logger hooks and returns the old ones
-func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
-	logger.mu.Lock()
-	oldHooks := logger.Hooks
-	logger.Hooks = hooks
-	logger.mu.Unlock()
-	return oldHooks
-}
diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go
deleted file mode 100644
index c1ca889..0000000
--- a/vendor/github.com/sirupsen/logrus/logrus.go
+++ /dev/null
@@ -1,186 +0,0 @@
-package logrus
-
-import (
-	"fmt"
-	"log"
-	"strings"
-)
-
-// Fields type, used to pass to `WithFields`.
-type Fields map[string]interface{}
-
-// Level type
-type Level uint32
-
-// Convert the Level to a string. E.g. PanicLevel becomes "panic".
-func (level Level) String() string {
-	if b, err := level.MarshalText(); err == nil {
-		return string(b)
-	} else {
-		return "unknown"
-	}
-}
-
-// ParseLevel takes a string level and returns the Logrus log level constant.
-func ParseLevel(lvl string) (Level, error) {
-	switch strings.ToLower(lvl) {
-	case "panic":
-		return PanicLevel, nil
-	case "fatal":
-		return FatalLevel, nil
-	case "error":
-		return ErrorLevel, nil
-	case "warn", "warning":
-		return WarnLevel, nil
-	case "info":
-		return InfoLevel, nil
-	case "debug":
-		return DebugLevel, nil
-	case "trace":
-		return TraceLevel, nil
-	}
-
-	var l Level
-	return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
-}
-
-// UnmarshalText implements encoding.TextUnmarshaler.
-func (level *Level) UnmarshalText(text []byte) error {
-	l, err := ParseLevel(string(text))
-	if err != nil {
-		return err
-	}
-
-	*level = Level(l)
-
-	return nil
-}
-
-func (level Level) MarshalText() ([]byte, error) {
-	switch level {
-	case TraceLevel:
-		return []byte("trace"), nil
-	case DebugLevel:
-		return []byte("debug"), nil
-	case InfoLevel:
-		return []byte("info"), nil
-	case WarnLevel:
-		return []byte("warning"), nil
-	case ErrorLevel:
-		return []byte("error"), nil
-	case FatalLevel:
-		return []byte("fatal"), nil
-	case PanicLevel:
-		return []byte("panic"), nil
-	}
-
-	return nil, fmt.Errorf("not a valid lorus level %q", level)
-}
-
-// A constant exposing all logging levels
-var AllLevels = []Level{
-	PanicLevel,
-	FatalLevel,
-	ErrorLevel,
-	WarnLevel,
-	InfoLevel,
-	DebugLevel,
-	TraceLevel,
-}
-
-// These are the different logging levels. You can set the logging level to log
-// on your instance of logger, obtained with `logrus.New()`.
-const (
-	// PanicLevel level, highest level of severity. Logs and then calls panic with the
-	// message passed to Debug, Info, ...
-	PanicLevel Level = iota
-	// FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit even if the
-	// logging level is set to Panic.
-	FatalLevel
-	// ErrorLevel level. Logs. Used for errors that should definitely be noted.
-	// Commonly used for hooks to send errors to an error tracking service.
-	ErrorLevel
-	// WarnLevel level. Non-critical entries that deserve eyes.
-	WarnLevel
-	// InfoLevel level. General operational entries about what's going on inside the
-	// application.
-	InfoLevel
-	// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
-	DebugLevel
-	// TraceLevel level. Designates finer-grained informational events than the Debug.
-	TraceLevel
-)
-
-// Won't compile if StdLogger can't be realized by a log.Logger
-var (
-	_ StdLogger = &log.Logger{}
-	_ StdLogger = &Entry{}
-	_ StdLogger = &Logger{}
-)
-
-// StdLogger is what your logrus-enabled library should take, that way
-// it'll accept a stdlib logger and a logrus logger. There's no standard
-// interface, this is the closest we get, unfortunately.
-type StdLogger interface {
-	Print(...interface{})
-	Printf(string, ...interface{})
-	Println(...interface{})
-
-	Fatal(...interface{})
-	Fatalf(string, ...interface{})
-	Fatalln(...interface{})
-
-	Panic(...interface{})
-	Panicf(string, ...interface{})
-	Panicln(...interface{})
-}
-
-// The FieldLogger interface generalizes the Entry and Logger types
-type FieldLogger interface {
-	WithField(key string, value interface{}) *Entry
-	WithFields(fields Fields) *Entry
-	WithError(err error) *Entry
-
-	Debugf(format string, args ...interface{})
-	Infof(format string, args ...interface{})
-	Printf(format string, args ...interface{})
-	Warnf(format string, args ...interface{})
-	Warningf(format string, args ...interface{})
-	Errorf(format string, args ...interface{})
-	Fatalf(format string, args ...interface{})
-	Panicf(format string, args ...interface{})
-
-	Debug(args ...interface{})
-	Info(args ...interface{})
-	Print(args ...interface{})
-	Warn(args ...interface{})
-	Warning(args ...interface{})
-	Error(args ...interface{})
-	Fatal(args ...interface{})
-	Panic(args ...interface{})
-
-	Debugln(args ...interface{})
-	Infoln(args ...interface{})
-	Println(args ...interface{})
-	Warnln(args ...interface{})
-	Warningln(args ...interface{})
-	Errorln(args ...interface{})
-	Fatalln(args ...interface{})
-	Panicln(args ...interface{})
-
-	// IsDebugEnabled() bool
-	// IsInfoEnabled() bool
-	// IsWarnEnabled() bool
-	// IsErrorEnabled() bool
-	// IsFatalEnabled() bool
-	// IsPanicEnabled() bool
-}
-
-// Ext1FieldLogger (the first extension to FieldLogger) is superfluous, it is
-// here for consistancy. Do not use. Use Logger or Entry instead.
-type Ext1FieldLogger interface {
-	FieldLogger
-	Tracef(format string, args ...interface{})
-	Trace(args ...interface{})
-	Traceln(args ...interface{})
-}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_aix.go b/vendor/github.com/sirupsen/logrus/terminal_check_aix.go
deleted file mode 100644
index 04fdb7b..0000000
--- a/vendor/github.com/sirupsen/logrus/terminal_check_aix.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build !appengine,!js,!windows,aix
-
-package logrus
-
-import "io"
-
-func checkIfTerminal(w io.Writer) bool {
-	return false
-}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
deleted file mode 100644
index 2403de9..0000000
--- a/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build appengine
-
-package logrus
-
-import (
-	"io"
-)
-
-func checkIfTerminal(w io.Writer) bool {
-	return true
-}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_js.go b/vendor/github.com/sirupsen/logrus/terminal_check_js.go
deleted file mode 100644
index 0c20975..0000000
--- a/vendor/github.com/sirupsen/logrus/terminal_check_js.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build js
-
-package logrus
-
-import (
-	"io"
-)
-
-func checkIfTerminal(w io.Writer) bool {
-	return false
-}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
deleted file mode 100644
index d465565..0000000
--- a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// +build !appengine,!js,!windows,!aix
-
-package logrus
-
-import (
-	"io"
-	"os"
-
-	"golang.org/x/crypto/ssh/terminal"
-)
-
-func checkIfTerminal(w io.Writer) bool {
-	switch v := w.(type) {
-	case *os.File:
-		return terminal.IsTerminal(int(v.Fd()))
-	default:
-		return false
-	}
-}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go
deleted file mode 100644
index 3b9d286..0000000
--- a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// +build !appengine,!js,windows
-
-package logrus
-
-import (
-	"io"
-	"os"
-	"syscall"
-)
-
-func checkIfTerminal(w io.Writer) bool {
-	switch v := w.(type) {
-	case *os.File:
-		var mode uint32
-		err := syscall.GetConsoleMode(syscall.Handle(v.Fd()), &mode)
-		return err == nil
-	default:
-		return false
-	}
-}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/sirupsen/logrus/terminal_notwindows.go
deleted file mode 100644
index 3dbd237..0000000
--- a/vendor/github.com/sirupsen/logrus/terminal_notwindows.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// +build !windows
-
-package logrus
-
-import "io"
-
-func initTerminal(w io.Writer) {
-}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_windows.go b/vendor/github.com/sirupsen/logrus/terminal_windows.go
deleted file mode 100644
index b4ef528..0000000
--- a/vendor/github.com/sirupsen/logrus/terminal_windows.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// +build !appengine,!js,windows
-
-package logrus
-
-import (
-	"io"
-	"os"
-	"syscall"
-
-	sequences "github.com/konsorten/go-windows-terminal-sequences"
-)
-
-func initTerminal(w io.Writer) {
-	switch v := w.(type) {
-	case *os.File:
-		sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true)
-	}
-}
diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go
deleted file mode 100644
index fb21649..0000000
--- a/vendor/github.com/sirupsen/logrus/text_formatter.go
+++ /dev/null
@@ -1,273 +0,0 @@
-package logrus
-
-import (
-	"bytes"
-	"fmt"
-	"os"
-	"runtime"
-	"sort"
-	"strings"
-	"sync"
-	"time"
-)
-
-const (
-	nocolor = 0
-	red     = 31
-	green   = 32
-	yellow  = 33
-	blue    = 36
-	gray    = 37
-)
-
-var (
-	baseTimestamp time.Time
-	emptyFieldMap FieldMap
-)
-
-func init() {
-	baseTimestamp = time.Now()
-}
-
-// TextFormatter formats logs into text
-type TextFormatter struct {
-	// Set to true to bypass checking for a TTY before outputting colors.
-	ForceColors bool
-
-	// Force disabling colors.
-	DisableColors bool
-
-	// Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/
-	EnvironmentOverrideColors bool
-
-	// Disable timestamp logging. useful when output is redirected to logging
-	// system that already adds timestamps.
-	DisableTimestamp bool
-
-	// Enable logging the full timestamp when a TTY is attached instead of just
-	// the time passed since beginning of execution.
-	FullTimestamp bool
-
-	// TimestampFormat to use for display when a full timestamp is printed
-	TimestampFormat string
-
-	// The fields are sorted by default for a consistent output. For applications
-	// that log extremely frequently and don't use the JSON formatter this may not
-	// be desired.
-	DisableSorting bool
-
-	// The keys sorting function, when uninitialized it uses sort.Strings.
-	SortingFunc func([]string)
-
-	// Disables the truncation of the level text to 4 characters.
-	DisableLevelTruncation bool
-
-	// QuoteEmptyFields will wrap empty fields in quotes if true
-	QuoteEmptyFields bool
-
-	// Whether the logger's out is to a terminal
-	isTerminal bool
-
-	// FieldMap allows users to customize the names of keys for default fields.
-	// As an example:
-	// formatter := &TextFormatter{
-	//     FieldMap: FieldMap{
-	//         FieldKeyTime:  "@timestamp",
-	//         FieldKeyLevel: "@level",
-	//         FieldKeyMsg:   "@message"}}
-	FieldMap FieldMap
-
-	terminalInitOnce sync.Once
-}
-
-func (f *TextFormatter) init(entry *Entry) {
-	if entry.Logger != nil {
-		f.isTerminal = checkIfTerminal(entry.Logger.Out)
-
-		if f.isTerminal {
-			initTerminal(entry.Logger.Out)
-		}
-	}
-}
-
-func (f *TextFormatter) isColored() bool {
-	isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows"))
-
-	if f.EnvironmentOverrideColors {
-		if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" {
-			isColored = true
-		} else if ok && force == "0" {
-			isColored = false
-		} else if os.Getenv("CLICOLOR") == "0" {
-			isColored = false
-		}
-	}
-
-	return isColored && !f.DisableColors
-}
-
-// Format renders a single log entry
-func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
-	data := make(Fields)
-	for k, v := range entry.Data {
-		data[k] = v
-	}
-	prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
-	keys := make([]string, 0, len(data))
-	for k := range data {
-		keys = append(keys, k)
-	}
-
-	fixedKeys := make([]string, 0, 4+len(data))
-	if !f.DisableTimestamp {
-		fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
-	}
-	fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLevel))
-	if entry.Message != "" {
-		fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyMsg))
-	}
-	if entry.err != "" {
-		fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError))
-	}
-	if entry.HasCaller() {
-		fixedKeys = append(fixedKeys,
-			f.FieldMap.resolve(FieldKeyFunc), f.FieldMap.resolve(FieldKeyFile))
-	}
-
-	if !f.DisableSorting {
-		if f.SortingFunc == nil {
-			sort.Strings(keys)
-			fixedKeys = append(fixedKeys, keys...)
-		} else {
-			if !f.isColored() {
-				fixedKeys = append(fixedKeys, keys...)
-				f.SortingFunc(fixedKeys)
-			} else {
-				f.SortingFunc(keys)
-			}
-		}
-	} else {
-		fixedKeys = append(fixedKeys, keys...)
-	}
-
-	var b *bytes.Buffer
-	if entry.Buffer != nil {
-		b = entry.Buffer
-	} else {
-		b = &bytes.Buffer{}
-	}
-
-	f.terminalInitOnce.Do(func() { f.init(entry) })
-
-	timestampFormat := f.TimestampFormat
-	if timestampFormat == "" {
-		timestampFormat = defaultTimestampFormat
-	}
-	if f.isColored() {
-		f.printColored(b, entry, keys, data, timestampFormat)
-	} else {
-		for _, key := range fixedKeys {
-			var value interface{}
-			switch {
-			case key == f.FieldMap.resolve(FieldKeyTime):
-				value = entry.Time.Format(timestampFormat)
-			case key == f.FieldMap.resolve(FieldKeyLevel):
-				value = entry.Level.String()
-			case key == f.FieldMap.resolve(FieldKeyMsg):
-				value = entry.Message
-			case key == f.FieldMap.resolve(FieldKeyLogrusError):
-				value = entry.err
-			case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller():
-				value = entry.Caller.Function
-			case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller():
-				value = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
-			default:
-				value = data[key]
-			}
-			f.appendKeyValue(b, key, value)
-		}
-	}
-
-	b.WriteByte('\n')
-	return b.Bytes(), nil
-}
-
-func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) {
-	var levelColor int
-	switch entry.Level {
-	case DebugLevel, TraceLevel:
-		levelColor = gray
-	case WarnLevel:
-		levelColor = yellow
-	case ErrorLevel, FatalLevel, PanicLevel:
-		levelColor = red
-	default:
-		levelColor = blue
-	}
-
-	levelText := strings.ToUpper(entry.Level.String())
-	if !f.DisableLevelTruncation {
-		levelText = levelText[0:4]
-	}
-
-	// Remove a single newline if it already exists in the message to keep
-	// the behavior of logrus text_formatter the same as the stdlib log package
-	entry.Message = strings.TrimSuffix(entry.Message, "\n")
-
-	caller := ""
-
-	if entry.HasCaller() {
-		caller = fmt.Sprintf("%s:%d %s()",
-			entry.Caller.File, entry.Caller.Line, entry.Caller.Function)
-	}
-
-	if f.DisableTimestamp {
-		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message)
-	} else if !f.FullTimestamp {
-		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message)
-	} else {
-		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message)
-	}
-	for _, k := range keys {
-		v := data[k]
-		fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
-		f.appendValue(b, v)
-	}
-}
-
-func (f *TextFormatter) needsQuoting(text string) bool {
-	if f.QuoteEmptyFields && len(text) == 0 {
-		return true
-	}
-	for _, ch := range text {
-		if !((ch >= 'a' && ch <= 'z') ||
-			(ch >= 'A' && ch <= 'Z') ||
-			(ch >= '0' && ch <= '9') ||
-			ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
-			return true
-		}
-	}
-	return false
-}
-
-func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
-	if b.Len() > 0 {
-		b.WriteByte(' ')
-	}
-	b.WriteString(key)
-	b.WriteByte('=')
-	f.appendValue(b, value)
-}
-
-func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
-	stringVal, ok := value.(string)
-	if !ok {
-		stringVal = fmt.Sprint(value)
-	}
-
-	if !f.needsQuoting(stringVal) {
-		b.WriteString(stringVal)
-	} else {
-		b.WriteString(fmt.Sprintf("%q", stringVal))
-	}
-}
diff --git a/vendor/github.com/sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go
deleted file mode 100644
index 9e1f751..0000000
--- a/vendor/github.com/sirupsen/logrus/writer.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package logrus
-
-import (
-	"bufio"
-	"io"
-	"runtime"
-)
-
-func (logger *Logger) Writer() *io.PipeWriter {
-	return logger.WriterLevel(InfoLevel)
-}
-
-func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
-	return NewEntry(logger).WriterLevel(level)
-}
-
-func (entry *Entry) Writer() *io.PipeWriter {
-	return entry.WriterLevel(InfoLevel)
-}
-
-func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
-	reader, writer := io.Pipe()
-
-	var printFunc func(args ...interface{})
-
-	switch level {
-	case TraceLevel:
-		printFunc = entry.Trace
-	case DebugLevel:
-		printFunc = entry.Debug
-	case InfoLevel:
-		printFunc = entry.Info
-	case WarnLevel:
-		printFunc = entry.Warn
-	case ErrorLevel:
-		printFunc = entry.Error
-	case FatalLevel:
-		printFunc = entry.Fatal
-	case PanicLevel:
-		printFunc = entry.Panic
-	default:
-		printFunc = entry.Print
-	}
-
-	go entry.writerScanner(reader, printFunc)
-	runtime.SetFinalizer(writer, writerFinalizer)
-
-	return writer
-}
-
-func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
-	scanner := bufio.NewScanner(reader)
-	for scanner.Scan() {
-		printFunc(scanner.Text())
-	}
-	if err := scanner.Err(); err != nil {
-		entry.Errorf("Error while reading from Writer: %s", err)
-	}
-	reader.Close()
-}
-
-func writerFinalizer(writer *io.PipeWriter) {
-	writer.Close()
-}
diff --git a/vendor/github.com/soheilhy/cmux/.gitignore b/vendor/github.com/soheilhy/cmux/.gitignore
deleted file mode 100644
index daf913b..0000000
--- a/vendor/github.com/soheilhy/cmux/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
-*.prof
diff --git a/vendor/github.com/soheilhy/cmux/.travis.yml b/vendor/github.com/soheilhy/cmux/.travis.yml
deleted file mode 100644
index 4bc48e0..0000000
--- a/vendor/github.com/soheilhy/cmux/.travis.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-language: go
-
-go:
-  - 1.6
-  - 1.7
-  - 1.8
-  - tip
-
-matrix:
-  allow_failures:
-    - go: tip
-
-gobuild_args: -race
-
-before_install:
-  - if [[ $TRAVIS_GO_VERSION == 1.6* ]]; then go get -u github.com/kisielk/errcheck; fi
-  - if [[ $TRAVIS_GO_VERSION == 1.6* ]]; then go get -u github.com/golang/lint/golint; fi
-
-before_script:
-  - '! gofmt -s -l . | read'
-  - echo $TRAVIS_GO_VERSION
-  - if [[ $TRAVIS_GO_VERSION == 1.6* ]]; then golint ./...; fi
-  - if [[ $TRAVIS_GO_VERSION == 1.6* ]]; then errcheck ./...; fi
-  - if [[ $TRAVIS_GO_VERSION == 1.6* ]]; then go tool vet .; fi
-  - if [[ $TRAVIS_GO_VERSION == 1.6* ]]; then go tool vet --shadow .; fi
-
-script:
-  - go test -bench . -v ./...
-  - go test -race -bench . -v ./...
diff --git a/vendor/github.com/soheilhy/cmux/CONTRIBUTORS b/vendor/github.com/soheilhy/cmux/CONTRIBUTORS
deleted file mode 100644
index 49878f2..0000000
--- a/vendor/github.com/soheilhy/cmux/CONTRIBUTORS
+++ /dev/null
@@ -1,12 +0,0 @@
-# The list of people who have contributed code to the cmux repository.
-#
-# Auto-generated with:
-#		git log --oneline --pretty=format:'%an <%aE>' | sort -u
-#
-Andreas Jaekle <andreas@jaekle.net>
-Dmitri Shuralyov <shurcooL@gmail.com>
-Ethan Mosbaugh <emosbaugh@gmail.com>
-Soheil Hassas Yeganeh <soheil.h.y@gmail.com>
-Soheil Hassas Yeganeh <soheil@cs.toronto.edu>
-Tamir Duberstein <tamir@cockroachlabs.com>
-Tamir Duberstein <tamird@gmail.com>
diff --git a/vendor/github.com/soheilhy/cmux/LICENSE b/vendor/github.com/soheilhy/cmux/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/vendor/github.com/soheilhy/cmux/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/soheilhy/cmux/README.md b/vendor/github.com/soheilhy/cmux/README.md
deleted file mode 100644
index 70306e6..0000000
--- a/vendor/github.com/soheilhy/cmux/README.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# cmux: Connection Mux ![Travis Build Status](https://api.travis-ci.org/soheilhy/args.svg?branch=master "Travis Build Status") [![GoDoc](https://godoc.org/github.com/soheilhy/cmux?status.svg)](http://godoc.org/github.com/soheilhy/cmux)
-
-cmux is a generic Go library to multiplex connections based on
-their payload. Using cmux, you can serve gRPC, SSH, HTTPS, HTTP,
-Go RPC, and pretty much any other protocol on the same TCP listener.
-
-## How-To
-Simply create your main listener, create a cmux for that listener,
-and then match connections:
-```go
-// Create the main listener.
-l, err := net.Listen("tcp", ":23456")
-if err != nil {
-	log.Fatal(err)
-}
-
-// Create a cmux.
-m := cmux.New(l)
-
-// Match connections in order:
-// First grpc, then HTTP, and otherwise Go RPC/TCP.
-grpcL := m.Match(cmux.HTTP2HeaderField("content-type", "application/grpc"))
-httpL := m.Match(cmux.HTTP1Fast())
-trpcL := m.Match(cmux.Any()) // Any means anything that is not yet matched.
-
-// Create your protocol servers.
-grpcS := grpc.NewServer()
-grpchello.RegisterGreeterServer(grpcs, &server{})
-
-httpS := &http.Server{
-	Handler: &helloHTTP1Handler{},
-}
-
-trpcS := rpc.NewServer()
-trpcS.Register(&ExampleRPCRcvr{})
-
-// Use the muxed listeners for your servers.
-go grpcS.Serve(grpcL)
-go httpS.Serve(httpL)
-go trpcS.Accept(trpcL)
-
-// Start serving!
-m.Serve()
-```
-
-Take a look at [other examples in the GoDoc](http://godoc.org/github.com/soheilhy/cmux/#pkg-examples).
-
-## Docs
-* [GoDocs](https://godoc.org/github.com/soheilhy/cmux)
-
-## Performance
-There is room for improvment but, since we are only matching
-the very first bytes of a connection, the performance overheads on
-long-lived connections (i.e., RPCs and pipelined HTTP streams)
-is negligible.
-
-*TODO(soheil)*: Add benchmarks.
-
-## Limitations
-* *TLS*: `net/http` uses a type assertion to identify TLS connections; since
-cmux's lookahead-implementing connection wraps the underlying TLS connection,
-this type assertion fails.
-Because of that, you can serve HTTPS using cmux but `http.Request.TLS`
-would not be set in your handlers.
-
-* *Different Protocols on The Same Connection*: `cmux` matches the connection
-when it's accepted. For example, one connection can be either gRPC or REST, but
-not both. That is, we assume that a client connection is either used for gRPC
-or REST.
-
-* *Java gRPC Clients*: Java gRPC client blocks until it receives a SETTINGS
-frame from the server. If you are using the Java client to connect to a cmux'ed
-gRPC server please match with writers:
-```go
-grpcl := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"))
-```
-
-# Copyright and License
-Copyright 2016 The CMux Authors. All rights reserved.
-
-See [CONTRIBUTORS](https://github.com/soheilhy/cmux/blob/master/CONTRIBUTORS)
-for the CMux Authors. Code is released under
-[the Apache 2 license](https://github.com/soheilhy/cmux/blob/master/LICENSE).
diff --git a/vendor/github.com/soheilhy/cmux/buffer.go b/vendor/github.com/soheilhy/cmux/buffer.go
deleted file mode 100644
index f8cf30a..0000000
--- a/vendor/github.com/soheilhy/cmux/buffer.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2016 The CMux Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied. See the License for the specific language governing
-// permissions and limitations under the License.
-
-package cmux
-
-import (
-	"bytes"
-	"io"
-)
-
-// bufferedReader is an optimized implementation of io.Reader that behaves like
-// ```
-// io.MultiReader(bytes.NewReader(buffer.Bytes()), io.TeeReader(source, buffer))
-// ```
-// without allocating.
-type bufferedReader struct {
-	source     io.Reader
-	buffer     bytes.Buffer
-	bufferRead int
-	bufferSize int
-	sniffing   bool
-	lastErr    error
-}
-
-func (s *bufferedReader) Read(p []byte) (int, error) {
-	if s.bufferSize > s.bufferRead {
-		// If we have already read something from the buffer before, we return the
-		// same data and the last error if any. We need to immediately return,
-		// otherwise we may block for ever, if we try to be smart and call
-		// source.Read() seeking a little bit of more data.
-		bn := copy(p, s.buffer.Bytes()[s.bufferRead:s.bufferSize])
-		s.bufferRead += bn
-		return bn, s.lastErr
-	} else if !s.sniffing && s.buffer.Cap() != 0 {
-		// We don't need the buffer anymore.
-		// Reset it to release the internal slice.
-		s.buffer = bytes.Buffer{}
-	}
-
-	// If there is nothing more to return in the sniffed buffer, read from the
-	// source.
-	sn, sErr := s.source.Read(p)
-	if sn > 0 && s.sniffing {
-		s.lastErr = sErr
-		if wn, wErr := s.buffer.Write(p[:sn]); wErr != nil {
-			return wn, wErr
-		}
-	}
-	return sn, sErr
-}
-
-func (s *bufferedReader) reset(snif bool) {
-	s.sniffing = snif
-	s.bufferRead = 0
-	s.bufferSize = s.buffer.Len()
-}
diff --git a/vendor/github.com/soheilhy/cmux/cmux.go b/vendor/github.com/soheilhy/cmux/cmux.go
deleted file mode 100644
index 8040342..0000000
--- a/vendor/github.com/soheilhy/cmux/cmux.go
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2016 The CMux Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied. See the License for the specific language governing
-// permissions and limitations under the License.
-
-package cmux
-
-import (
-	"fmt"
-	"io"
-	"net"
-	"sync"
-	"time"
-)
-
-// Matcher matches a connection based on its content.
-type Matcher func(io.Reader) bool
-
-// MatchWriter is a match that can also write response (say to do handshake).
-type MatchWriter func(io.Writer, io.Reader) bool
-
-// ErrorHandler handles an error and returns whether
-// the mux should continue serving the listener.
-type ErrorHandler func(error) bool
-
-var _ net.Error = ErrNotMatched{}
-
-// ErrNotMatched is returned whenever a connection is not matched by any of
-// the matchers registered in the multiplexer.
-type ErrNotMatched struct {
-	c net.Conn
-}
-
-func (e ErrNotMatched) Error() string {
-	return fmt.Sprintf("mux: connection %v not matched by an matcher",
-		e.c.RemoteAddr())
-}
-
-// Temporary implements the net.Error interface.
-func (e ErrNotMatched) Temporary() bool { return true }
-
-// Timeout implements the net.Error interface.
-func (e ErrNotMatched) Timeout() bool { return false }
-
-type errListenerClosed string
-
-func (e errListenerClosed) Error() string   { return string(e) }
-func (e errListenerClosed) Temporary() bool { return false }
-func (e errListenerClosed) Timeout() bool   { return false }
-
-// ErrListenerClosed is returned from muxListener.Accept when the underlying
-// listener is closed.
-var ErrListenerClosed = errListenerClosed("mux: listener closed")
-
-// for readability of readTimeout
-var noTimeout time.Duration
-
-// New instantiates a new connection multiplexer.
-func New(l net.Listener) CMux {
-	return &cMux{
-		root:        l,
-		bufLen:      1024,
-		errh:        func(_ error) bool { return true },
-		donec:       make(chan struct{}),
-		readTimeout: noTimeout,
-	}
-}
-
-// CMux is a multiplexer for network connections.
-type CMux interface {
-	// Match returns a net.Listener that sees (i.e., accepts) only
-	// the connections matched by at least one of the matcher.
-	//
-	// The order used to call Match determines the priority of matchers.
-	Match(...Matcher) net.Listener
-	// MatchWithWriters returns a net.Listener that accepts only the
-	// connections that matched by at least of the matcher writers.
-	//
-	// Prefer Matchers over MatchWriters, since the latter can write on the
-	// connection before the actual handler.
-	//
-	// The order used to call Match determines the priority of matchers.
-	MatchWithWriters(...MatchWriter) net.Listener
-	// Serve starts multiplexing the listener. Serve blocks and perhaps
-	// should be invoked concurrently within a go routine.
-	Serve() error
-	// HandleError registers an error handler that handles listener errors.
-	HandleError(ErrorHandler)
-	// sets a timeout for the read of matchers
-	SetReadTimeout(time.Duration)
-}
-
-type matchersListener struct {
-	ss []MatchWriter
-	l  muxListener
-}
-
-type cMux struct {
-	root        net.Listener
-	bufLen      int
-	errh        ErrorHandler
-	donec       chan struct{}
-	sls         []matchersListener
-	readTimeout time.Duration
-}
-
-func matchersToMatchWriters(matchers []Matcher) []MatchWriter {
-	mws := make([]MatchWriter, 0, len(matchers))
-	for _, m := range matchers {
-		cm := m
-		mws = append(mws, func(w io.Writer, r io.Reader) bool {
-			return cm(r)
-		})
-	}
-	return mws
-}
-
-func (m *cMux) Match(matchers ...Matcher) net.Listener {
-	mws := matchersToMatchWriters(matchers)
-	return m.MatchWithWriters(mws...)
-}
-
-func (m *cMux) MatchWithWriters(matchers ...MatchWriter) net.Listener {
-	ml := muxListener{
-		Listener: m.root,
-		connc:    make(chan net.Conn, m.bufLen),
-	}
-	m.sls = append(m.sls, matchersListener{ss: matchers, l: ml})
-	return ml
-}
-
-func (m *cMux) SetReadTimeout(t time.Duration) {
-	m.readTimeout = t
-}
-
-func (m *cMux) Serve() error {
-	var wg sync.WaitGroup
-
-	defer func() {
-		close(m.donec)
-		wg.Wait()
-
-		for _, sl := range m.sls {
-			close(sl.l.connc)
-			// Drain the connections enqueued for the listener.
-			for c := range sl.l.connc {
-				_ = c.Close()
-			}
-		}
-	}()
-
-	for {
-		c, err := m.root.Accept()
-		if err != nil {
-			if !m.handleErr(err) {
-				return err
-			}
-			continue
-		}
-
-		wg.Add(1)
-		go m.serve(c, m.donec, &wg)
-	}
-}
-
-func (m *cMux) serve(c net.Conn, donec <-chan struct{}, wg *sync.WaitGroup) {
-	defer wg.Done()
-
-	muc := newMuxConn(c)
-	if m.readTimeout > noTimeout {
-		_ = c.SetReadDeadline(time.Now().Add(m.readTimeout))
-	}
-	for _, sl := range m.sls {
-		for _, s := range sl.ss {
-			matched := s(muc.Conn, muc.startSniffing())
-			if matched {
-				muc.doneSniffing()
-				if m.readTimeout > noTimeout {
-					_ = c.SetReadDeadline(time.Time{})
-				}
-				select {
-				case sl.l.connc <- muc:
-				case <-donec:
-					_ = c.Close()
-				}
-				return
-			}
-		}
-	}
-
-	_ = c.Close()
-	err := ErrNotMatched{c: c}
-	if !m.handleErr(err) {
-		_ = m.root.Close()
-	}
-}
-
-func (m *cMux) HandleError(h ErrorHandler) {
-	m.errh = h
-}
-
-func (m *cMux) handleErr(err error) bool {
-	if !m.errh(err) {
-		return false
-	}
-
-	if ne, ok := err.(net.Error); ok {
-		return ne.Temporary()
-	}
-
-	return false
-}
-
-type muxListener struct {
-	net.Listener
-	connc chan net.Conn
-}
-
-func (l muxListener) Accept() (net.Conn, error) {
-	c, ok := <-l.connc
-	if !ok {
-		return nil, ErrListenerClosed
-	}
-	return c, nil
-}
-
-// MuxConn wraps a net.Conn and provides transparent sniffing of connection data.
-type MuxConn struct {
-	net.Conn
-	buf bufferedReader
-}
-
-func newMuxConn(c net.Conn) *MuxConn {
-	return &MuxConn{
-		Conn: c,
-		buf:  bufferedReader{source: c},
-	}
-}
-
-// From the io.Reader documentation:
-//
-// When Read encounters an error or end-of-file condition after
-// successfully reading n > 0 bytes, it returns the number of
-// bytes read.  It may return the (non-nil) error from the same call
-// or return the error (and n == 0) from a subsequent call.
-// An instance of this general case is that a Reader returning
-// a non-zero number of bytes at the end of the input stream may
-// return either err == EOF or err == nil.  The next Read should
-// return 0, EOF.
-func (m *MuxConn) Read(p []byte) (int, error) {
-	return m.buf.Read(p)
-}
-
-func (m *MuxConn) startSniffing() io.Reader {
-	m.buf.reset(true)
-	return &m.buf
-}
-
-func (m *MuxConn) doneSniffing() {
-	m.buf.reset(false)
-}
diff --git a/vendor/github.com/soheilhy/cmux/doc.go b/vendor/github.com/soheilhy/cmux/doc.go
deleted file mode 100644
index aaa8f31..0000000
--- a/vendor/github.com/soheilhy/cmux/doc.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2016 The CMux Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied. See the License for the specific language governing
-// permissions and limitations under the License.
-
-// Package cmux is a library to multiplex network connections based on
-// their payload. Using cmux, you can serve different protocols from the
-// same listener.
-package cmux
diff --git a/vendor/github.com/soheilhy/cmux/matchers.go b/vendor/github.com/soheilhy/cmux/matchers.go
deleted file mode 100644
index 878ae98..0000000
--- a/vendor/github.com/soheilhy/cmux/matchers.go
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright 2016 The CMux Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied. See the License for the specific language governing
-// permissions and limitations under the License.
-
-package cmux
-
-import (
-	"bufio"
-	"crypto/tls"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"strings"
-
-	"golang.org/x/net/http2"
-	"golang.org/x/net/http2/hpack"
-)
-
-// Any is a Matcher that matches any connection.
-func Any() Matcher {
-	return func(r io.Reader) bool { return true }
-}
-
-// PrefixMatcher returns a matcher that matches a connection if it
-// starts with any of the strings in strs.
-func PrefixMatcher(strs ...string) Matcher {
-	pt := newPatriciaTreeString(strs...)
-	return pt.matchPrefix
-}
-
-func prefixByteMatcher(list ...[]byte) Matcher {
-	pt := newPatriciaTree(list...)
-	return pt.matchPrefix
-}
-
-var defaultHTTPMethods = []string{
-	"OPTIONS",
-	"GET",
-	"HEAD",
-	"POST",
-	"PUT",
-	"DELETE",
-	"TRACE",
-	"CONNECT",
-}
-
-// HTTP1Fast only matches the methods in the HTTP request.
-//
-// This matcher is very optimistic: if it returns true, it does not mean that
-// the request is a valid HTTP response. If you want a correct but slower HTTP1
-// matcher, use HTTP1 instead.
-func HTTP1Fast(extMethods ...string) Matcher {
-	return PrefixMatcher(append(defaultHTTPMethods, extMethods...)...)
-}
-
-// TLS matches HTTPS requests.
-//
-// By default, any TLS handshake packet is matched. An optional whitelist
-// of versions can be passed in to restrict the matcher, for example:
-//  TLS(tls.VersionTLS11, tls.VersionTLS12)
-func TLS(versions ...int) Matcher {
-	if len(versions) == 0 {
-		versions = []int{
-			tls.VersionSSL30,
-			tls.VersionTLS10,
-			tls.VersionTLS11,
-			tls.VersionTLS12,
-		}
-	}
-	prefixes := [][]byte{}
-	for _, v := range versions {
-		prefixes = append(prefixes, []byte{22, byte(v >> 8 & 0xff), byte(v & 0xff)})
-	}
-	return prefixByteMatcher(prefixes...)
-}
-
-const maxHTTPRead = 4096
-
-// HTTP1 parses the first line or upto 4096 bytes of the request to see if
-// the conection contains an HTTP request.
-func HTTP1() Matcher {
-	return func(r io.Reader) bool {
-		br := bufio.NewReader(&io.LimitedReader{R: r, N: maxHTTPRead})
-		l, part, err := br.ReadLine()
-		if err != nil || part {
-			return false
-		}
-
-		_, _, proto, ok := parseRequestLine(string(l))
-		if !ok {
-			return false
-		}
-
-		v, _, ok := http.ParseHTTPVersion(proto)
-		return ok && v == 1
-	}
-}
-
-// grabbed from net/http.
-func parseRequestLine(line string) (method, uri, proto string, ok bool) {
-	s1 := strings.Index(line, " ")
-	s2 := strings.Index(line[s1+1:], " ")
-	if s1 < 0 || s2 < 0 {
-		return
-	}
-	s2 += s1 + 1
-	return line[:s1], line[s1+1 : s2], line[s2+1:], true
-}
-
-// HTTP2 parses the frame header of the first frame to detect whether the
-// connection is an HTTP2 connection.
-func HTTP2() Matcher {
-	return hasHTTP2Preface
-}
-
-// HTTP1HeaderField returns a matcher matching the header fields of the first
-// request of an HTTP 1 connection.
-func HTTP1HeaderField(name, value string) Matcher {
-	return func(r io.Reader) bool {
-		return matchHTTP1Field(r, name, func(gotValue string) bool {
-			return gotValue == value
-		})
-	}
-}
-
-// HTTP1HeaderFieldPrefix returns a matcher matching the header fields of the
-// first request of an HTTP 1 connection. If the header with key name has a
-// value prefixed with valuePrefix, this will match.
-func HTTP1HeaderFieldPrefix(name, valuePrefix string) Matcher {
-	return func(r io.Reader) bool {
-		return matchHTTP1Field(r, name, func(gotValue string) bool {
-			return strings.HasPrefix(gotValue, valuePrefix)
-		})
-	}
-}
-
-// HTTP2HeaderField returns a matcher matching the header fields of the first
-// headers frame.
-func HTTP2HeaderField(name, value string) Matcher {
-	return func(r io.Reader) bool {
-		return matchHTTP2Field(ioutil.Discard, r, name, func(gotValue string) bool {
-			return gotValue == value
-		})
-	}
-}
-
-// HTTP2HeaderFieldPrefix returns a matcher matching the header fields of the
-// first headers frame. If the header with key name has a value prefixed with
-// valuePrefix, this will match.
-func HTTP2HeaderFieldPrefix(name, valuePrefix string) Matcher {
-	return func(r io.Reader) bool {
-		return matchHTTP2Field(ioutil.Discard, r, name, func(gotValue string) bool {
-			return strings.HasPrefix(gotValue, valuePrefix)
-		})
-	}
-}
-
-// HTTP2MatchHeaderFieldSendSettings matches the header field and writes the
-// settings to the server. Prefer HTTP2HeaderField over this one, if the client
-// does not block on receiving a SETTING frame.
-func HTTP2MatchHeaderFieldSendSettings(name, value string) MatchWriter {
-	return func(w io.Writer, r io.Reader) bool {
-		return matchHTTP2Field(w, r, name, func(gotValue string) bool {
-			return gotValue == value
-		})
-	}
-}
-
-// HTTP2MatchHeaderFieldPrefixSendSettings matches the header field prefix
-// and writes the settings to the server. Prefer HTTP2HeaderFieldPrefix over
-// this one, if the client does not block on receiving a SETTING frame.
-func HTTP2MatchHeaderFieldPrefixSendSettings(name, valuePrefix string) MatchWriter {
-	return func(w io.Writer, r io.Reader) bool {
-		return matchHTTP2Field(w, r, name, func(gotValue string) bool {
-			return strings.HasPrefix(gotValue, valuePrefix)
-		})
-	}
-}
-
-func hasHTTP2Preface(r io.Reader) bool {
-	var b [len(http2.ClientPreface)]byte
-	last := 0
-
-	for {
-		n, err := r.Read(b[last:])
-		if err != nil {
-			return false
-		}
-
-		last += n
-		eq := string(b[:last]) == http2.ClientPreface[:last]
-		if last == len(http2.ClientPreface) {
-			return eq
-		}
-		if !eq {
-			return false
-		}
-	}
-}
-
-func matchHTTP1Field(r io.Reader, name string, matches func(string) bool) (matched bool) {
-	req, err := http.ReadRequest(bufio.NewReader(r))
-	if err != nil {
-		return false
-	}
-
-	return matches(req.Header.Get(name))
-}
-
-func matchHTTP2Field(w io.Writer, r io.Reader, name string, matches func(string) bool) (matched bool) {
-	if !hasHTTP2Preface(r) {
-		return false
-	}
-
-	done := false
-	framer := http2.NewFramer(w, r)
-	hdec := hpack.NewDecoder(uint32(4<<10), func(hf hpack.HeaderField) {
-		if hf.Name == name {
-			done = true
-			if matches(hf.Value) {
-				matched = true
-			}
-		}
-	})
-	for {
-		f, err := framer.ReadFrame()
-		if err != nil {
-			return false
-		}
-
-		switch f := f.(type) {
-		case *http2.SettingsFrame:
-			// Sender acknoweldged the SETTINGS frame. No need to write
-			// SETTINGS again.
-			if f.IsAck() {
-				break
-			}
-			if err := framer.WriteSettings(); err != nil {
-				return false
-			}
-		case *http2.ContinuationFrame:
-			if _, err := hdec.Write(f.HeaderBlockFragment()); err != nil {
-				return false
-			}
-			done = done || f.FrameHeader.Flags&http2.FlagHeadersEndHeaders != 0
-		case *http2.HeadersFrame:
-			if _, err := hdec.Write(f.HeaderBlockFragment()); err != nil {
-				return false
-			}
-			done = done || f.FrameHeader.Flags&http2.FlagHeadersEndHeaders != 0
-		}
-
-		if done {
-			return matched
-		}
-	}
-}
diff --git a/vendor/github.com/soheilhy/cmux/patricia.go b/vendor/github.com/soheilhy/cmux/patricia.go
deleted file mode 100644
index c3e3d85..0000000
--- a/vendor/github.com/soheilhy/cmux/patricia.go
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2016 The CMux Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied. See the License for the specific language governing
-// permissions and limitations under the License.
-
-package cmux
-
-import (
-	"bytes"
-	"io"
-)
-
-// patriciaTree is a simple patricia tree that handles []byte instead of string
-// and cannot be changed after instantiation.
-type patriciaTree struct {
-	root     *ptNode
-	maxDepth int // max depth of the tree.
-}
-
-func newPatriciaTree(bs ...[]byte) *patriciaTree {
-	max := 0
-	for _, b := range bs {
-		if max < len(b) {
-			max = len(b)
-		}
-	}
-	return &patriciaTree{
-		root:     newNode(bs),
-		maxDepth: max + 1,
-	}
-}
-
-func newPatriciaTreeString(strs ...string) *patriciaTree {
-	b := make([][]byte, len(strs))
-	for i, s := range strs {
-		b[i] = []byte(s)
-	}
-	return newPatriciaTree(b...)
-}
-
-func (t *patriciaTree) matchPrefix(r io.Reader) bool {
-	buf := make([]byte, t.maxDepth)
-	n, _ := io.ReadFull(r, buf)
-	return t.root.match(buf[:n], true)
-}
-
-func (t *patriciaTree) match(r io.Reader) bool {
-	buf := make([]byte, t.maxDepth)
-	n, _ := io.ReadFull(r, buf)
-	return t.root.match(buf[:n], false)
-}
-
-type ptNode struct {
-	prefix   []byte
-	next     map[byte]*ptNode
-	terminal bool
-}
-
-func newNode(strs [][]byte) *ptNode {
-	if len(strs) == 0 {
-		return &ptNode{
-			prefix:   []byte{},
-			terminal: true,
-		}
-	}
-
-	if len(strs) == 1 {
-		return &ptNode{
-			prefix:   strs[0],
-			terminal: true,
-		}
-	}
-
-	p, strs := splitPrefix(strs)
-	n := &ptNode{
-		prefix: p,
-	}
-
-	nexts := make(map[byte][][]byte)
-	for _, s := range strs {
-		if len(s) == 0 {
-			n.terminal = true
-			continue
-		}
-		nexts[s[0]] = append(nexts[s[0]], s[1:])
-	}
-
-	n.next = make(map[byte]*ptNode)
-	for first, rests := range nexts {
-		n.next[first] = newNode(rests)
-	}
-
-	return n
-}
-
-func splitPrefix(bss [][]byte) (prefix []byte, rest [][]byte) {
-	if len(bss) == 0 || len(bss[0]) == 0 {
-		return prefix, bss
-	}
-
-	if len(bss) == 1 {
-		return bss[0], [][]byte{{}}
-	}
-
-	for i := 0; ; i++ {
-		var cur byte
-		eq := true
-		for j, b := range bss {
-			if len(b) <= i {
-				eq = false
-				break
-			}
-
-			if j == 0 {
-				cur = b[i]
-				continue
-			}
-
-			if cur != b[i] {
-				eq = false
-				break
-			}
-		}
-
-		if !eq {
-			break
-		}
-
-		prefix = append(prefix, cur)
-	}
-
-	rest = make([][]byte, 0, len(bss))
-	for _, b := range bss {
-		rest = append(rest, b[len(prefix):])
-	}
-
-	return prefix, rest
-}
-
-func (n *ptNode) match(b []byte, prefix bool) bool {
-	l := len(n.prefix)
-	if l > 0 {
-		if l > len(b) {
-			l = len(b)
-		}
-		if !bytes.Equal(b[:l], n.prefix) {
-			return false
-		}
-	}
-
-	if n.terminal && (prefix || len(n.prefix) == len(b)) {
-		return true
-	}
-
-	if l >= len(b) {
-		return false
-	}
-
-	nextN, ok := n.next[b[l]]
-	if !ok {
-		return false
-	}
-
-	if l == len(b) {
-		b = b[l:l]
-	} else {
-		b = b[l+1:]
-	}
-	return nextN.match(b, prefix)
-}
diff --git a/vendor/github.com/spf13/cobra/.gitignore b/vendor/github.com/spf13/cobra/.gitignore
deleted file mode 100644
index 1b8c7c2..0000000
--- a/vendor/github.com/spf13/cobra/.gitignore
+++ /dev/null
@@ -1,36 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-# Vim files https://github.com/github/gitignore/blob/master/Global/Vim.gitignore
-# swap
-[._]*.s[a-w][a-z]
-[._]s[a-w][a-z]
-# session
-Session.vim
-# temporary
-.netrwhist
-*~
-# auto-generated tag files
-tags
-
-*.exe
-
-cobra.test
diff --git a/vendor/github.com/spf13/cobra/.mailmap b/vendor/github.com/spf13/cobra/.mailmap
deleted file mode 100644
index 94ec530..0000000
--- a/vendor/github.com/spf13/cobra/.mailmap
+++ /dev/null
@@ -1,3 +0,0 @@
-Steve Francia <steve.francia@gmail.com>
-Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
-Fabiano Franz <ffranz@redhat.com>                   <contact@fabianofranz.com>
diff --git a/vendor/github.com/spf13/cobra/.travis.yml b/vendor/github.com/spf13/cobra/.travis.yml
deleted file mode 100644
index 5afcb20..0000000
--- a/vendor/github.com/spf13/cobra/.travis.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-language: go
-
-matrix:
-  include:
-    - go: 1.9.4
-    - go: 1.10.0
-    - go: tip
-  allow_failures:
-    - go: tip
-
-before_install:
-  - mkdir -p bin
-  - curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.4.3/shellcheck
-  - chmod +x bin/shellcheck
-script:
-  - PATH=$PATH:$PWD/bin go test -v ./...
-  - go build
-  - diff -u <(echo -n) <(gofmt -d -s .)
-  - if [ -z $NOVET ]; then
-      diff -u <(echo -n) <(go tool vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint');
-    fi
diff --git a/vendor/github.com/spf13/cobra/LICENSE.txt b/vendor/github.com/spf13/cobra/LICENSE.txt
deleted file mode 100644
index 298f0e2..0000000
--- a/vendor/github.com/spf13/cobra/LICENSE.txt
+++ /dev/null
@@ -1,174 +0,0 @@
-                                Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md
deleted file mode 100644
index 851fcc0..0000000
--- a/vendor/github.com/spf13/cobra/README.md
+++ /dev/null
@@ -1,736 +0,0 @@
-![cobra logo](https://cloud.githubusercontent.com/assets/173412/10886352/ad566232-814f-11e5-9cd0-aa101788c117.png)
-
-Cobra is both a library for creating powerful modern CLI applications as well as a program to generate applications and command files.
-
-Many of the most widely used Go projects are built using Cobra including:
-
-* [Kubernetes](http://kubernetes.io/)
-* [Hugo](http://gohugo.io)
-* [rkt](https://github.com/coreos/rkt)
-* [etcd](https://github.com/coreos/etcd)
-* [Moby (former Docker)](https://github.com/moby/moby)
-* [Docker (distribution)](https://github.com/docker/distribution)
-* [OpenShift](https://www.openshift.com/)
-* [Delve](https://github.com/derekparker/delve)
-* [GopherJS](http://www.gopherjs.org/)
-* [CockroachDB](http://www.cockroachlabs.com/)
-* [Bleve](http://www.blevesearch.com/)
-* [ProjectAtomic (enterprise)](http://www.projectatomic.io/)
-* [GiantSwarm's swarm](https://github.com/giantswarm/cli)
-* [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)
-* [rclone](http://rclone.org/)
-* [nehm](https://github.com/bogem/nehm)
-* [Pouch](https://github.com/alibaba/pouch)
-
-[![Build Status](https://travis-ci.org/spf13/cobra.svg "Travis CI status")](https://travis-ci.org/spf13/cobra)
-[![CircleCI status](https://circleci.com/gh/spf13/cobra.png?circle-token=:circle-token "CircleCI status")](https://circleci.com/gh/spf13/cobra)
-[![GoDoc](https://godoc.org/github.com/spf13/cobra?status.svg)](https://godoc.org/github.com/spf13/cobra)
-
-# Table of Contents
-
-- [Overview](#overview)
-- [Concepts](#concepts)
-  * [Commands](#commands)
-  * [Flags](#flags)
-- [Installing](#installing)
-- [Getting Started](#getting-started)
-  * [Using the Cobra Generator](#using-the-cobra-generator)
-  * [Using the Cobra Library](#using-the-cobra-library)
-  * [Working with Flags](#working-with-flags)
-  * [Positional and Custom Arguments](#positional-and-custom-arguments)
-  * [Example](#example)
-  * [Help Command](#help-command)
-  * [Usage Message](#usage-message)
-  * [PreRun and PostRun Hooks](#prerun-and-postrun-hooks)
-  * [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens)
-  * [Generating documentation for your command](#generating-documentation-for-your-command)
-  * [Generating bash completions](#generating-bash-completions)
-- [Contributing](#contributing)
-- [License](#license)
-
-# Overview
-
-Cobra is a library providing a simple interface to create powerful modern CLI
-interfaces similar to git & go tools.
-
-Cobra is also an application that will generate your application scaffolding to rapidly
-develop a Cobra-based application.
-
-Cobra provides:
-* Easy subcommand-based CLIs: `app server`, `app fetch`, etc.
-* Fully POSIX-compliant flags (including short & long versions)
-* Nested subcommands
-* Global, local and cascading flags
-* Easy generation of applications & commands with `cobra init appname` & `cobra add cmdname`
-* Intelligent suggestions (`app srver`... did you mean `app server`?)
-* Automatic help generation for commands and flags
-* Automatic help flag recognition of `-h`, `--help`, etc.
-* Automatically generated bash autocomplete for your application
-* Automatically generated man pages for your application
-* Command aliases so you can change things without breaking them
-* The flexibility to define your own help, usage, etc.
-* Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps
-
-# Concepts
-
-Cobra is built on a structure of commands, arguments & flags.
-
-**Commands** represent actions, **Args** are things and **Flags** are modifiers for those actions.
-
-The best applications will read like sentences when used. Users will know how
-to use the application because they will natively understand how to use it.
-
-The pattern to follow is
-`APPNAME VERB NOUN --ADJECTIVE.`
-    or
-`APPNAME COMMAND ARG --FLAG`
-
-A few good real world examples may better illustrate this point.
-
-In the following example, 'server' is a command, and 'port' is a flag:
-
-    hugo server --port=1313
-
-In this command we are telling Git to clone the url bare.
-
-    git clone URL --bare
-
-## Commands
-
-Command is the central point of the application. Each interaction that
-the application supports will be contained in a Command. A command can
-have children commands and optionally run an action.
-
-In the example above, 'server' is the command.
-
-[More about cobra.Command](https://godoc.org/github.com/spf13/cobra#Command)
-
-## Flags
-
-A flag is a way to modify the behavior of a command. Cobra supports
-fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/).
-A Cobra command can define flags that persist through to children commands
-and flags that are only available to that command.
-
-In the example above, 'port' is the flag.
-
-Flag functionality is provided by the [pflag
-library](https://github.com/spf13/pflag), a fork of the flag standard library
-which maintains the same interface while adding POSIX compliance.
-
-# Installing
-Using Cobra is easy. First, use `go get` to install the latest version
-of the library. This command will install the `cobra` generator executable
-along with the library and its dependencies:
-
-    go get -u github.com/spf13/cobra/cobra
-
-Next, include Cobra in your application:
-
-```go
-import "github.com/spf13/cobra"
-```
-
-# Getting Started
-
-While you are welcome to provide your own organization, typically a Cobra-based
-application will follow the following organizational structure:
-
-```
-  ▾ appName/
-    ▾ cmd/
-        add.go
-        your.go
-        commands.go
-        here.go
-      main.go
-```
-
-In a Cobra app, typically the main.go file is very bare. It serves one purpose: initializing Cobra.
-
-```go
-package main
-
-import (
-  "fmt"
-  "os"
-
-  "{pathToYourApp}/cmd"
-)
-
-func main() {
-  cmd.Execute()
-}
-```
-
-## Using the Cobra Generator
-
-Cobra provides its own program that will create your application and add any
-commands you want. It's the easiest way to incorporate Cobra into your application.
-
-[Here](https://github.com/spf13/cobra/blob/master/cobra/README.md) you can find more information about it.
-
-## Using the Cobra Library
-
-To manually implement Cobra you need to create a bare main.go file and a rootCmd file.
-You will optionally provide additional commands as you see fit.
-
-### Create rootCmd
-
-Cobra doesn't require any special constructors. Simply create your commands.
-
-Ideally you place this in app/cmd/root.go:
-
-```go
-var rootCmd = &cobra.Command{
-  Use:   "hugo",
-  Short: "Hugo is a very fast static site generator",
-  Long: `A Fast and Flexible Static Site Generator built with
-                love by spf13 and friends in Go.
-                Complete documentation is available at http://hugo.spf13.com`,
-  Run: func(cmd *cobra.Command, args []string) {
-    // Do Stuff Here
-  },
-}
-
-func Execute() {
-  if err := rootCmd.Execute(); err != nil {
-    fmt.Println(err)
-    os.Exit(1)
-  }
-}
-```
-
-You will additionally define flags and handle configuration in your init() function.
-
-For example cmd/root.go:
-
-```go
-import (
-  "fmt"
-  "os"
-
-  homedir "github.com/mitchellh/go-homedir"
-  "github.com/spf13/cobra"
-  "github.com/spf13/viper"
-)
-
-func init() {
-  cobra.OnInitialize(initConfig)
-  rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
-  rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/")
-  rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
-  rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)")
-  rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
-  viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
-  viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase"))
-  viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
-  viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
-  viper.SetDefault("license", "apache")
-}
-
-func initConfig() {
-  // Don't forget to read config either from cfgFile or from home directory!
-  if cfgFile != "" {
-    // Use config file from the flag.
-    viper.SetConfigFile(cfgFile)
-  } else {
-    // Find home directory.
-    home, err := homedir.Dir()
-    if err != nil {
-      fmt.Println(err)
-      os.Exit(1)
-    }
-
-    // Search config in home directory with name ".cobra" (without extension).
-    viper.AddConfigPath(home)
-    viper.SetConfigName(".cobra")
-  }
-
-  if err := viper.ReadInConfig(); err != nil {
-    fmt.Println("Can't read config:", err)
-    os.Exit(1)
-  }
-}
-```
-
-### Create your main.go
-
-With the root command you need to have your main function execute it.
-Execute should be run on the root for clarity, though it can be called on any command.
-
-In a Cobra app, typically the main.go file is very bare. It serves, one purpose, to initialize Cobra.
-
-```go
-package main
-
-import (
-  "fmt"
-  "os"
-
-  "{pathToYourApp}/cmd"
-)
-
-func main() {
-  cmd.Execute()
-}
-```
-
-### Create additional commands
-
-Additional commands can be defined and typically are each given their own file
-inside of the cmd/ directory.
-
-If you wanted to create a version command you would create cmd/version.go and
-populate it with the following:
-
-```go
-package cmd
-
-import (
-  "fmt"
-
-  "github.com/spf13/cobra"
-)
-
-func init() {
-  rootCmd.AddCommand(versionCmd)
-}
-
-var versionCmd = &cobra.Command{
-  Use:   "version",
-  Short: "Print the version number of Hugo",
-  Long:  `All software has versions. This is Hugo's`,
-  Run: func(cmd *cobra.Command, args []string) {
-    fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
-  },
-}
-```
-
-## Working with Flags
-
-Flags provide modifiers to control how the action command operates.
-
-### Assign flags to a command
-
-Since the flags are defined and used in different locations, we need to
-define a variable outside with the correct scope to assign the flag to
-work with.
-
-```go
-var Verbose bool
-var Source string
-```
-
-There are two different approaches to assign a flag.
-
-### Persistent Flags
-
-A flag can be 'persistent' meaning that this flag will be available to the
-command it's assigned to as well as every command under that command. For
-global flags, assign a flag as a persistent flag on the root.
-
-```go
-rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
-```
-
-### Local Flags
-
-A flag can also be assigned locally which will only apply to that specific command.
-
-```go
-rootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
-```
-
-### Local Flag on Parent Commands
-
-By default Cobra only parses local flags on the target command, any local flags on
-parent commands are ignored. By enabling `Command.TraverseChildren` Cobra will
-parse local flags on each command before executing the target command.
-
-```go
-command := cobra.Command{
-  Use: "print [OPTIONS] [COMMANDS]",
-  TraverseChildren: true,
-}
-```
-
-### Bind Flags with Config
-
-You can also bind your flags with [viper](https://github.com/spf13/viper):
-```go
-var author string
-
-func init() {
-  rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution")
-  viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
-}
-```
-
-In this example the persistent flag `author` is bound with `viper`.
-**Note**, that the variable `author` will not be set to the value from config,
-when the `--author` flag is not provided by user.
-
-More in [viper documentation](https://github.com/spf13/viper#working-with-flags).
-
-### Required flags
-
-Flags are optional by default. If instead you wish your command to report an error
-when a flag has not been set, mark it as required:
-```go
-rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
-rootCmd.MarkFlagRequired("region")
-```
-
-## Positional and Custom Arguments
-
-Validation of positional arguments can be specified using the `Args` field
-of `Command`.
-
-The following validators are built in:
-
-- `NoArgs` - the command will report an error if there are any positional args.
-- `ArbitraryArgs` - the command will accept any args.
-- `OnlyValidArgs` - the command will report an error if there are any positional args that are not in the `ValidArgs` field of `Command`.
-- `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args.
-- `MaximumNArgs(int)` - the command will report an error if there are more than N positional args.
-- `ExactArgs(int)` - the command will report an error if there are not exactly N positional args.
-- `RangeArgs(min, max)` - the command will report an error if the number of args is not between the minimum and maximum number of expected args.
-
-An example of setting the custom validator:
-
-```go
-var cmd = &cobra.Command{
-  Short: "hello",
-  Args: func(cmd *cobra.Command, args []string) error {
-    if len(args) < 1 {
-      return errors.New("requires at least one arg")
-    }
-    if myapp.IsValidColor(args[0]) {
-      return nil
-    }
-    return fmt.Errorf("invalid color specified: %s", args[0])
-  },
-  Run: func(cmd *cobra.Command, args []string) {
-    fmt.Println("Hello, World!")
-  },
-}
-```
-
-## Example
-
-In the example below, we have defined three commands. Two are at the top level
-and one (cmdTimes) is a child of one of the top commands. In this case the root
-is not executable meaning that a subcommand is required. This is accomplished
-by not providing a 'Run' for the 'rootCmd'.
-
-We have only defined one flag for a single command.
-
-More documentation about flags is available at https://github.com/spf13/pflag
-
-```go
-package main
-
-import (
-  "fmt"
-  "strings"
-
-  "github.com/spf13/cobra"
-)
-
-func main() {
-  var echoTimes int
-
-  var cmdPrint = &cobra.Command{
-    Use:   "print [string to print]",
-    Short: "Print anything to the screen",
-    Long: `print is for printing anything back to the screen.
-For many years people have printed back to the screen.`,
-    Args: cobra.MinimumNArgs(1),
-    Run: func(cmd *cobra.Command, args []string) {
-      fmt.Println("Print: " + strings.Join(args, " "))
-    },
-  }
-
-  var cmdEcho = &cobra.Command{
-    Use:   "echo [string to echo]",
-    Short: "Echo anything to the screen",
-    Long: `echo is for echoing anything back.
-Echo works a lot like print, except it has a child command.`,
-    Args: cobra.MinimumNArgs(1),
-    Run: func(cmd *cobra.Command, args []string) {
-      fmt.Println("Print: " + strings.Join(args, " "))
-    },
-  }
-
-  var cmdTimes = &cobra.Command{
-    Use:   "times [# times] [string to echo]",
-    Short: "Echo anything to the screen more times",
-    Long: `echo things multiple times back to the user by providing
-a count and a string.`,
-    Args: cobra.MinimumNArgs(1),
-    Run: func(cmd *cobra.Command, args []string) {
-      for i := 0; i < echoTimes; i++ {
-        fmt.Println("Echo: " + strings.Join(args, " "))
-      }
-    },
-  }
-
-  cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input")
-
-  var rootCmd = &cobra.Command{Use: "app"}
-  rootCmd.AddCommand(cmdPrint, cmdEcho)
-  cmdEcho.AddCommand(cmdTimes)
-  rootCmd.Execute()
-}
-```
-
-For a more complete example of a larger application, please checkout [Hugo](http://gohugo.io/).
-
-## Help Command
-
-Cobra automatically adds a help command to your application when you have subcommands.
-This will be called when a user runs 'app help'. Additionally, help will also
-support all other commands as input. Say, for instance, you have a command called
-'create' without any additional configuration; Cobra will work when 'app help
-create' is called.  Every command will automatically have the '--help' flag added.
-
-### Example
-
-The following output is automatically generated by Cobra. Nothing beyond the
-command and flag definitions are needed.
-
-    $ cobra help
-
-    Cobra is a CLI library for Go that empowers applications.
-    This application is a tool to generate the needed files
-    to quickly create a Cobra application.
-
-    Usage:
-      cobra [command]
-
-    Available Commands:
-      add         Add a command to a Cobra Application
-      help        Help about any command
-      init        Initialize a Cobra Application
-
-    Flags:
-      -a, --author string    author name for copyright attribution (default "YOUR NAME")
-          --config string    config file (default is $HOME/.cobra.yaml)
-      -h, --help             help for cobra
-      -l, --license string   name of license for the project
-          --viper            use Viper for configuration (default true)
-
-    Use "cobra [command] --help" for more information about a command.
-
-
-Help is just a command like any other. There is no special logic or behavior
-around it. In fact, you can provide your own if you want.
-
-### Defining your own help
-
-You can provide your own Help command or your own template for the default command to use
-with following functions:
-
-```go
-cmd.SetHelpCommand(cmd *Command)
-cmd.SetHelpFunc(f func(*Command, []string))
-cmd.SetHelpTemplate(s string)
-```
-
-The latter two will also apply to any children commands.
-
-## Usage Message
-
-When the user provides an invalid flag or invalid command, Cobra responds by
-showing the user the 'usage'.
-
-### Example
-You may recognize this from the help above. That's because the default help
-embeds the usage as part of its output.
-
-    $ cobra --invalid
-    Error: unknown flag: --invalid
-    Usage:
-      cobra [command]
-
-    Available Commands:
-      add         Add a command to a Cobra Application
-      help        Help about any command
-      init        Initialize a Cobra Application
-
-    Flags:
-      -a, --author string    author name for copyright attribution (default "YOUR NAME")
-          --config string    config file (default is $HOME/.cobra.yaml)
-      -h, --help             help for cobra
-      -l, --license string   name of license for the project
-          --viper            use Viper for configuration (default true)
-
-    Use "cobra [command] --help" for more information about a command.
-
-### Defining your own usage
-You can provide your own usage function or template for Cobra to use.
-Like help, the function and template are overridable through public methods:
-
-```go
-cmd.SetUsageFunc(f func(*Command) error)
-cmd.SetUsageTemplate(s string)
-```
-
-## Version Flag
-
-Cobra adds a top-level '--version' flag if the Version field is set on the root command.
-Running an application with the '--version' flag will print the version to stdout using
-the version template. The template can be customized using the
-`cmd.SetVersionTemplate(s string)` function.
-
-## PreRun and PostRun Hooks
-
-It is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistentPostRun` and `PostRun` will be executed after `Run`.  The `Persistent*Run` functions will be inherited by children if they do not declare their own.  These functions are run in the following order:
-
-- `PersistentPreRun`
-- `PreRun`
-- `Run`
-- `PostRun`
-- `PersistentPostRun`
-
-An example of two commands which use all of these features is below.  When the subcommand is executed, it will run the root command's `PersistentPreRun` but not the root command's `PersistentPostRun`:
-
-```go
-package main
-
-import (
-  "fmt"
-
-  "github.com/spf13/cobra"
-)
-
-func main() {
-
-  var rootCmd = &cobra.Command{
-    Use:   "root [sub]",
-    Short: "My root command",
-    PersistentPreRun: func(cmd *cobra.Command, args []string) {
-      fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
-    },
-    PreRun: func(cmd *cobra.Command, args []string) {
-      fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
-    },
-    Run: func(cmd *cobra.Command, args []string) {
-      fmt.Printf("Inside rootCmd Run with args: %v\n", args)
-    },
-    PostRun: func(cmd *cobra.Command, args []string) {
-      fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
-    },
-    PersistentPostRun: func(cmd *cobra.Command, args []string) {
-      fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
-    },
-  }
-
-  var subCmd = &cobra.Command{
-    Use:   "sub [no options!]",
-    Short: "My subcommand",
-    PreRun: func(cmd *cobra.Command, args []string) {
-      fmt.Printf("Inside subCmd PreRun with args: %v\n", args)
-    },
-    Run: func(cmd *cobra.Command, args []string) {
-      fmt.Printf("Inside subCmd Run with args: %v\n", args)
-    },
-    PostRun: func(cmd *cobra.Command, args []string) {
-      fmt.Printf("Inside subCmd PostRun with args: %v\n", args)
-    },
-    PersistentPostRun: func(cmd *cobra.Command, args []string) {
-      fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args)
-    },
-  }
-
-  rootCmd.AddCommand(subCmd)
-
-  rootCmd.SetArgs([]string{""})
-  rootCmd.Execute()
-  fmt.Println()
-  rootCmd.SetArgs([]string{"sub", "arg1", "arg2"})
-  rootCmd.Execute()
-}
-```
-
-Output:
-```
-Inside rootCmd PersistentPreRun with args: []
-Inside rootCmd PreRun with args: []
-Inside rootCmd Run with args: []
-Inside rootCmd PostRun with args: []
-Inside rootCmd PersistentPostRun with args: []
-
-Inside rootCmd PersistentPreRun with args: [arg1 arg2]
-Inside subCmd PreRun with args: [arg1 arg2]
-Inside subCmd Run with args: [arg1 arg2]
-Inside subCmd PostRun with args: [arg1 arg2]
-Inside subCmd PersistentPostRun with args: [arg1 arg2]
-```
-
-## Suggestions when "unknown command" happens
-
-Cobra will print automatic suggestions when "unknown command" errors happen. This allows Cobra to behave similarly to the `git` command when a typo happens. For example:
-
-```
-$ hugo srever
-Error: unknown command "srever" for "hugo"
-
-Did you mean this?
-        server
-
-Run 'hugo --help' for usage.
-```
-
-Suggestions are automatic based on every subcommand registered and use an implementation of [Levenshtein distance](http://en.wikipedia.org/wiki/Levenshtein_distance). Every registered command that matches a minimum distance of 2 (ignoring case) will be displayed as a suggestion.
-
-If you need to disable suggestions or tweak the string distance in your command, use:
-
-```go
-command.DisableSuggestions = true
-```
-
-or
-
-```go
-command.SuggestionsMinimumDistance = 1
-```
-
-You can also explicitly set names for which a given command will be suggested using the `SuggestFor` attribute. This allows suggestions for strings that are not close in terms of string distance, but makes sense in your set of commands and for some which you don't want aliases. Example:
-
-```
-$ kubectl remove
-Error: unknown command "remove" for "kubectl"
-
-Did you mean this?
-        delete
-
-Run 'kubectl help' for usage.
-```
-
-## Generating documentation for your command
-
-Cobra can generate documentation based on subcommands, flags, etc. in the following formats:
-
-- [Markdown](doc/md_docs.md)
-- [ReStructured Text](doc/rest_docs.md)
-- [Man Page](doc/man_docs.md)
-
-## Generating bash completions
-
-Cobra can generate a bash-completion file. If you add more information to your command, these completions can be amazingly powerful and flexible.  Read more about it in [Bash Completions](bash_completions.md).
-
-# Contributing
-
-1. Fork it
-2. Download your fork to your PC (`git clone https://github.com/your_username/cobra && cd cobra`)
-3. Create your feature branch (`git checkout -b my-new-feature`)
-4. Make changes and add them (`git add .`)
-5. Commit your changes (`git commit -m 'Add some feature'`)
-6. Push to the branch (`git push origin my-new-feature`)
-7. Create new pull request
-
-# License
-
-Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt)
diff --git a/vendor/github.com/spf13/cobra/args.go b/vendor/github.com/spf13/cobra/args.go
deleted file mode 100644
index a5d8a92..0000000
--- a/vendor/github.com/spf13/cobra/args.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package cobra
-
-import (
-	"fmt"
-)
-
-type PositionalArgs func(cmd *Command, args []string) error
-
-// Legacy arg validation has the following behaviour:
-// - root commands with no subcommands can take arbitrary arguments
-// - root commands with subcommands will do subcommand validity checking
-// - subcommands will always accept arbitrary arguments
-func legacyArgs(cmd *Command, args []string) error {
-	// no subcommand, always take args
-	if !cmd.HasSubCommands() {
-		return nil
-	}
-
-	// root command with subcommands, do subcommand checking.
-	if !cmd.HasParent() && len(args) > 0 {
-		return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
-	}
-	return nil
-}
-
-// NoArgs returns an error if any args are included.
-func NoArgs(cmd *Command, args []string) error {
-	if len(args) > 0 {
-		return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())
-	}
-	return nil
-}
-
-// OnlyValidArgs returns an error if any args are not in the list of ValidArgs.
-func OnlyValidArgs(cmd *Command, args []string) error {
-	if len(cmd.ValidArgs) > 0 {
-		for _, v := range args {
-			if !stringInSlice(v, cmd.ValidArgs) {
-				return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
-			}
-		}
-	}
-	return nil
-}
-
-// ArbitraryArgs never returns an error.
-func ArbitraryArgs(cmd *Command, args []string) error {
-	return nil
-}
-
-// MinimumNArgs returns an error if there is not at least N args.
-func MinimumNArgs(n int) PositionalArgs {
-	return func(cmd *Command, args []string) error {
-		if len(args) < n {
-			return fmt.Errorf("requires at least %d arg(s), only received %d", n, len(args))
-		}
-		return nil
-	}
-}
-
-// MaximumNArgs returns an error if there are more than N args.
-func MaximumNArgs(n int) PositionalArgs {
-	return func(cmd *Command, args []string) error {
-		if len(args) > n {
-			return fmt.Errorf("accepts at most %d arg(s), received %d", n, len(args))
-		}
-		return nil
-	}
-}
-
-// ExactArgs returns an error if there are not exactly n args.
-func ExactArgs(n int) PositionalArgs {
-	return func(cmd *Command, args []string) error {
-		if len(args) != n {
-			return fmt.Errorf("accepts %d arg(s), received %d", n, len(args))
-		}
-		return nil
-	}
-}
-
-// RangeArgs returns an error if the number of args is not within the expected range.
-func RangeArgs(min int, max int) PositionalArgs {
-	return func(cmd *Command, args []string) error {
-		if len(args) < min || len(args) > max {
-			return fmt.Errorf("accepts between %d and %d arg(s), received %d", min, max, len(args))
-		}
-		return nil
-	}
-}
diff --git a/vendor/github.com/spf13/cobra/bash_completions.go b/vendor/github.com/spf13/cobra/bash_completions.go
deleted file mode 100644
index 8fa8f48..0000000
--- a/vendor/github.com/spf13/cobra/bash_completions.go
+++ /dev/null
@@ -1,584 +0,0 @@
-package cobra
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"os"
-	"sort"
-	"strings"
-
-	"github.com/spf13/pflag"
-)
-
-// Annotations for Bash completion.
-const (
-	BashCompFilenameExt     = "cobra_annotation_bash_completion_filename_extensions"
-	BashCompCustom          = "cobra_annotation_bash_completion_custom"
-	BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag"
-	BashCompSubdirsInDir    = "cobra_annotation_bash_completion_subdirs_in_dir"
-)
-
-func writePreamble(buf *bytes.Buffer, name string) {
-	buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
-	buf.WriteString(fmt.Sprintf(`
-__%[1]s_debug()
-{
-    if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
-        echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
-    fi
-}
-
-# Homebrew on Macs have version 1.3 of bash-completion which doesn't include
-# _init_completion. This is a very minimal version of that function.
-__%[1]s_init_completion()
-{
-    COMPREPLY=()
-    _get_comp_words_by_ref "$@" cur prev words cword
-}
-
-__%[1]s_index_of_word()
-{
-    local w word=$1
-    shift
-    index=0
-    for w in "$@"; do
-        [[ $w = "$word" ]] && return
-        index=$((index+1))
-    done
-    index=-1
-}
-
-__%[1]s_contains_word()
-{
-    local w word=$1; shift
-    for w in "$@"; do
-        [[ $w = "$word" ]] && return
-    done
-    return 1
-}
-
-__%[1]s_handle_reply()
-{
-    __%[1]s_debug "${FUNCNAME[0]}"
-    case $cur in
-        -*)
-            if [[ $(type -t compopt) = "builtin" ]]; then
-                compopt -o nospace
-            fi
-            local allflags
-            if [ ${#must_have_one_flag[@]} -ne 0 ]; then
-                allflags=("${must_have_one_flag[@]}")
-            else
-                allflags=("${flags[*]} ${two_word_flags[*]}")
-            fi
-            COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
-            if [[ $(type -t compopt) = "builtin" ]]; then
-                [[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace
-            fi
-
-            # complete after --flag=abc
-            if [[ $cur == *=* ]]; then
-                if [[ $(type -t compopt) = "builtin" ]]; then
-                    compopt +o nospace
-                fi
-
-                local index flag
-                flag="${cur%%=*}"
-                __%[1]s_index_of_word "${flag}" "${flags_with_completion[@]}"
-                COMPREPLY=()
-                if [[ ${index} -ge 0 ]]; then
-                    PREFIX=""
-                    cur="${cur#*=}"
-                    ${flags_completion[${index}]}
-                    if [ -n "${ZSH_VERSION}" ]; then
-                        # zsh completion needs --flag= prefix
-                        eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
-                    fi
-                fi
-            fi
-            return 0;
-            ;;
-    esac
-
-    # check if we are handling a flag with special work handling
-    local index
-    __%[1]s_index_of_word "${prev}" "${flags_with_completion[@]}"
-    if [[ ${index} -ge 0 ]]; then
-        ${flags_completion[${index}]}
-        return
-    fi
-
-    # we are parsing a flag and don't have a special handler, no completion
-    if [[ ${cur} != "${words[cword]}" ]]; then
-        return
-    fi
-
-    local completions
-    completions=("${commands[@]}")
-    if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then
-        completions=("${must_have_one_noun[@]}")
-    fi
-    if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
-        completions+=("${must_have_one_flag[@]}")
-    fi
-    COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )
-
-    if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
-        COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") )
-    fi
-
-    if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
-        declare -F __custom_func >/dev/null && __custom_func
-    fi
-
-    # available in bash-completion >= 2, not always present on macOS
-    if declare -F __ltrim_colon_completions >/dev/null; then
-        __ltrim_colon_completions "$cur"
-    fi
-
-    # If there is only 1 completion and it is a flag with an = it will be completed
-    # but we don't want a space after the =
-    if [[ "${#COMPREPLY[@]}" -eq "1" ]] && [[ $(type -t compopt) = "builtin" ]] && [[ "${COMPREPLY[0]}" == --*= ]]; then
-       compopt -o nospace
-    fi
-}
-
-# The arguments should be in the form "ext1|ext2|extn"
-__%[1]s_handle_filename_extension_flag()
-{
-    local ext="$1"
-    _filedir "@(${ext})"
-}
-
-__%[1]s_handle_subdirs_in_dir_flag()
-{
-    local dir="$1"
-    pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
-}
-
-__%[1]s_handle_flag()
-{
-    __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
-
-    # if a command required a flag, and we found it, unset must_have_one_flag()
-    local flagname=${words[c]}
-    local flagvalue
-    # if the word contained an =
-    if [[ ${words[c]} == *"="* ]]; then
-        flagvalue=${flagname#*=} # take in as flagvalue after the =
-        flagname=${flagname%%=*} # strip everything after the =
-        flagname="${flagname}=" # but put the = back
-    fi
-    __%[1]s_debug "${FUNCNAME[0]}: looking for ${flagname}"
-    if __%[1]s_contains_word "${flagname}" "${must_have_one_flag[@]}"; then
-        must_have_one_flag=()
-    fi
-
-    # if you set a flag which only applies to this command, don't show subcommands
-    if __%[1]s_contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
-      commands=()
-    fi
-
-    # keep flag value with flagname as flaghash
-    # flaghash variable is an associative array which is only supported in bash > 3.
-    if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
-        if [ -n "${flagvalue}" ] ; then
-            flaghash[${flagname}]=${flagvalue}
-        elif [ -n "${words[ $((c+1)) ]}" ] ; then
-            flaghash[${flagname}]=${words[ $((c+1)) ]}
-        else
-            flaghash[${flagname}]="true" # pad "true" for bool flag
-        fi
-    fi
-
-    # skip the argument to a two word flag
-    if __%[1]s_contains_word "${words[c]}" "${two_word_flags[@]}"; then
-        c=$((c+1))
-        # if we are looking for a flags value, don't show commands
-        if [[ $c -eq $cword ]]; then
-            commands=()
-        fi
-    fi
-
-    c=$((c+1))
-
-}
-
-__%[1]s_handle_noun()
-{
-    __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
-
-    if __%[1]s_contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
-        must_have_one_noun=()
-    elif __%[1]s_contains_word "${words[c]}" "${noun_aliases[@]}"; then
-        must_have_one_noun=()
-    fi
-
-    nouns+=("${words[c]}")
-    c=$((c+1))
-}
-
-__%[1]s_handle_command()
-{
-    __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
-
-    local next_command
-    if [[ -n ${last_command} ]]; then
-        next_command="_${last_command}_${words[c]//:/__}"
-    else
-        if [[ $c -eq 0 ]]; then
-            next_command="_%[1]s_root_command"
-        else
-            next_command="_${words[c]//:/__}"
-        fi
-    fi
-    c=$((c+1))
-    __%[1]s_debug "${FUNCNAME[0]}: looking for ${next_command}"
-    declare -F "$next_command" >/dev/null && $next_command
-}
-
-__%[1]s_handle_word()
-{
-    if [[ $c -ge $cword ]]; then
-        __%[1]s_handle_reply
-        return
-    fi
-    __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
-    if [[ "${words[c]}" == -* ]]; then
-        __%[1]s_handle_flag
-    elif __%[1]s_contains_word "${words[c]}" "${commands[@]}"; then
-        __%[1]s_handle_command
-    elif [[ $c -eq 0 ]]; then
-        __%[1]s_handle_command
-    elif __%[1]s_contains_word "${words[c]}" "${command_aliases[@]}"; then
-        # aliashash variable is an associative array which is only supported in bash > 3.
-        if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
-            words[c]=${aliashash[${words[c]}]}
-            __%[1]s_handle_command
-        else
-            __%[1]s_handle_noun
-        fi
-    else
-        __%[1]s_handle_noun
-    fi
-    __%[1]s_handle_word
-}
-
-`, name))
-}
-
-func writePostscript(buf *bytes.Buffer, name string) {
-	name = strings.Replace(name, ":", "__", -1)
-	buf.WriteString(fmt.Sprintf("__start_%s()\n", name))
-	buf.WriteString(fmt.Sprintf(`{
-    local cur prev words cword
-    declare -A flaghash 2>/dev/null || :
-    declare -A aliashash 2>/dev/null || :
-    if declare -F _init_completion >/dev/null 2>&1; then
-        _init_completion -s || return
-    else
-        __%[1]s_init_completion -n "=" || return
-    fi
-
-    local c=0
-    local flags=()
-    local two_word_flags=()
-    local local_nonpersistent_flags=()
-    local flags_with_completion=()
-    local flags_completion=()
-    local commands=("%[1]s")
-    local must_have_one_flag=()
-    local must_have_one_noun=()
-    local last_command
-    local nouns=()
-
-    __%[1]s_handle_word
-}
-
-`, name))
-	buf.WriteString(fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
-    complete -o default -F __start_%s %s
-else
-    complete -o default -o nospace -F __start_%s %s
-fi
-
-`, name, name, name, name))
-	buf.WriteString("# ex: ts=4 sw=4 et filetype=sh\n")
-}
-
-func writeCommands(buf *bytes.Buffer, cmd *Command) {
-	buf.WriteString("    commands=()\n")
-	for _, c := range cmd.Commands() {
-		if !c.IsAvailableCommand() || c == cmd.helpCommand {
-			continue
-		}
-		buf.WriteString(fmt.Sprintf("    commands+=(%q)\n", c.Name()))
-		writeCmdAliases(buf, c)
-	}
-	buf.WriteString("\n")
-}
-
-func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string, cmd *Command) {
-	for key, value := range annotations {
-		switch key {
-		case BashCompFilenameExt:
-			buf.WriteString(fmt.Sprintf("    flags_with_completion+=(%q)\n", name))
-
-			var ext string
-			if len(value) > 0 {
-				ext = fmt.Sprintf("__%s_handle_filename_extension_flag ", cmd.Root().Name()) + strings.Join(value, "|")
-			} else {
-				ext = "_filedir"
-			}
-			buf.WriteString(fmt.Sprintf("    flags_completion+=(%q)\n", ext))
-		case BashCompCustom:
-			buf.WriteString(fmt.Sprintf("    flags_with_completion+=(%q)\n", name))
-			if len(value) > 0 {
-				handlers := strings.Join(value, "; ")
-				buf.WriteString(fmt.Sprintf("    flags_completion+=(%q)\n", handlers))
-			} else {
-				buf.WriteString("    flags_completion+=(:)\n")
-			}
-		case BashCompSubdirsInDir:
-			buf.WriteString(fmt.Sprintf("    flags_with_completion+=(%q)\n", name))
-
-			var ext string
-			if len(value) == 1 {
-				ext = fmt.Sprintf("__%s_handle_subdirs_in_dir_flag ", cmd.Root().Name()) + value[0]
-			} else {
-				ext = "_filedir -d"
-			}
-			buf.WriteString(fmt.Sprintf("    flags_completion+=(%q)\n", ext))
-		}
-	}
-}
-
-func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
-	name := flag.Shorthand
-	format := "    "
-	if len(flag.NoOptDefVal) == 0 {
-		format += "two_word_"
-	}
-	format += "flags+=(\"-%s\")\n"
-	buf.WriteString(fmt.Sprintf(format, name))
-	writeFlagHandler(buf, "-"+name, flag.Annotations, cmd)
-}
-
-func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
-	name := flag.Name
-	format := "    flags+=(\"--%s"
-	if len(flag.NoOptDefVal) == 0 {
-		format += "="
-	}
-	format += "\")\n"
-	buf.WriteString(fmt.Sprintf(format, name))
-	writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
-}
-
-func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
-	name := flag.Name
-	format := "    local_nonpersistent_flags+=(\"--%s"
-	if len(flag.NoOptDefVal) == 0 {
-		format += "="
-	}
-	format += "\")\n"
-	buf.WriteString(fmt.Sprintf(format, name))
-}
-
-func writeFlags(buf *bytes.Buffer, cmd *Command) {
-	buf.WriteString(`    flags=()
-    two_word_flags=()
-    local_nonpersistent_flags=()
-    flags_with_completion=()
-    flags_completion=()
-
-`)
-	localNonPersistentFlags := cmd.LocalNonPersistentFlags()
-	cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
-		if nonCompletableFlag(flag) {
-			return
-		}
-		writeFlag(buf, flag, cmd)
-		if len(flag.Shorthand) > 0 {
-			writeShortFlag(buf, flag, cmd)
-		}
-		if localNonPersistentFlags.Lookup(flag.Name) != nil {
-			writeLocalNonPersistentFlag(buf, flag)
-		}
-	})
-	cmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
-		if nonCompletableFlag(flag) {
-			return
-		}
-		writeFlag(buf, flag, cmd)
-		if len(flag.Shorthand) > 0 {
-			writeShortFlag(buf, flag, cmd)
-		}
-	})
-
-	buf.WriteString("\n")
-}
-
-func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
-	buf.WriteString("    must_have_one_flag=()\n")
-	flags := cmd.NonInheritedFlags()
-	flags.VisitAll(func(flag *pflag.Flag) {
-		if nonCompletableFlag(flag) {
-			return
-		}
-		for key := range flag.Annotations {
-			switch key {
-			case BashCompOneRequiredFlag:
-				format := "    must_have_one_flag+=(\"--%s"
-				if flag.Value.Type() != "bool" {
-					format += "="
-				}
-				format += "\")\n"
-				buf.WriteString(fmt.Sprintf(format, flag.Name))
-
-				if len(flag.Shorthand) > 0 {
-					buf.WriteString(fmt.Sprintf("    must_have_one_flag+=(\"-%s\")\n", flag.Shorthand))
-				}
-			}
-		}
-	})
-}
-
-func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
-	buf.WriteString("    must_have_one_noun=()\n")
-	sort.Sort(sort.StringSlice(cmd.ValidArgs))
-	for _, value := range cmd.ValidArgs {
-		buf.WriteString(fmt.Sprintf("    must_have_one_noun+=(%q)\n", value))
-	}
-}
-
-func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
-	if len(cmd.Aliases) == 0 {
-		return
-	}
-
-	sort.Sort(sort.StringSlice(cmd.Aliases))
-
-	buf.WriteString(fmt.Sprint(`    if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n"))
-	for _, value := range cmd.Aliases {
-		buf.WriteString(fmt.Sprintf("        command_aliases+=(%q)\n", value))
-		buf.WriteString(fmt.Sprintf("        aliashash[%q]=%q\n", value, cmd.Name()))
-	}
-	buf.WriteString(`    fi`)
-	buf.WriteString("\n")
-}
-func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
-	buf.WriteString("    noun_aliases=()\n")
-	sort.Sort(sort.StringSlice(cmd.ArgAliases))
-	for _, value := range cmd.ArgAliases {
-		buf.WriteString(fmt.Sprintf("    noun_aliases+=(%q)\n", value))
-	}
-}
-
-func gen(buf *bytes.Buffer, cmd *Command) {
-	for _, c := range cmd.Commands() {
-		if !c.IsAvailableCommand() || c == cmd.helpCommand {
-			continue
-		}
-		gen(buf, c)
-	}
-	commandName := cmd.CommandPath()
-	commandName = strings.Replace(commandName, " ", "_", -1)
-	commandName = strings.Replace(commandName, ":", "__", -1)
-
-	if cmd.Root() == cmd {
-		buf.WriteString(fmt.Sprintf("_%s_root_command()\n{\n", commandName))
-	} else {
-		buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
-	}
-
-	buf.WriteString(fmt.Sprintf("    last_command=%q\n", commandName))
-	buf.WriteString("\n")
-	buf.WriteString("    command_aliases=()\n")
-	buf.WriteString("\n")
-
-	writeCommands(buf, cmd)
-	writeFlags(buf, cmd)
-	writeRequiredFlag(buf, cmd)
-	writeRequiredNouns(buf, cmd)
-	writeArgAliases(buf, cmd)
-	buf.WriteString("}\n\n")
-}
-
-// GenBashCompletion generates bash completion file and writes to the passed writer.
-func (c *Command) GenBashCompletion(w io.Writer) error {
-	buf := new(bytes.Buffer)
-	writePreamble(buf, c.Name())
-	if len(c.BashCompletionFunction) > 0 {
-		buf.WriteString(c.BashCompletionFunction + "\n")
-	}
-	gen(buf, c)
-	writePostscript(buf, c.Name())
-
-	_, err := buf.WriteTo(w)
-	return err
-}
-
-func nonCompletableFlag(flag *pflag.Flag) bool {
-	return flag.Hidden || len(flag.Deprecated) > 0
-}
-
-// GenBashCompletionFile generates bash completion file.
-func (c *Command) GenBashCompletionFile(filename string) error {
-	outFile, err := os.Create(filename)
-	if err != nil {
-		return err
-	}
-	defer outFile.Close()
-
-	return c.GenBashCompletion(outFile)
-}
-
-// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
-// and causes your command to report an error if invoked without the flag.
-func (c *Command) MarkFlagRequired(name string) error {
-	return MarkFlagRequired(c.Flags(), name)
-}
-
-// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
-// and causes your command to report an error if invoked without the flag.
-func (c *Command) MarkPersistentFlagRequired(name string) error {
-	return MarkFlagRequired(c.PersistentFlags(), name)
-}
-
-// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
-// and causes your command to report an error if invoked without the flag.
-func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
-	return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
-}
-
-// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
-// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
-func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
-	return MarkFlagFilename(c.Flags(), name, extensions...)
-}
-
-// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
-// Generated bash autocompletion will call the bash function f for the flag.
-func (c *Command) MarkFlagCustom(name string, f string) error {
-	return MarkFlagCustom(c.Flags(), name, f)
-}
-
-// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
-// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
-func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
-	return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
-}
-
-// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists.
-// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
-func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {
-	return flags.SetAnnotation(name, BashCompFilenameExt, extensions)
-}
-
-// MarkFlagCustom adds the BashCompCustom annotation to the named flag in the flag set, if it exists.
-// Generated bash autocompletion will call the bash function f for the flag.
-func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {
-	return flags.SetAnnotation(name, BashCompCustom, []string{f})
-}
diff --git a/vendor/github.com/spf13/cobra/bash_completions.md b/vendor/github.com/spf13/cobra/bash_completions.md
deleted file mode 100644
index e79d476..0000000
--- a/vendor/github.com/spf13/cobra/bash_completions.md
+++ /dev/null
@@ -1,221 +0,0 @@
-# Generating Bash Completions For Your Own cobra.Command
-
-Generating bash completions from a cobra command is incredibly easy. An actual program which does so for the kubernetes kubectl binary is as follows:
-
-```go
-package main
-
-import (
-	"io/ioutil"
-	"os"
-
-	"k8s.io/kubernetes/pkg/kubectl/cmd"
-	"k8s.io/kubernetes/pkg/kubectl/cmd/util"
-)
-
-func main() {
-	kubectl := cmd.NewKubectlCommand(util.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
-	kubectl.GenBashCompletionFile("out.sh")
-}
-```
-
-`out.sh` will get you completions of subcommands and flags. Copy it to `/etc/bash_completion.d/` as described [here](https://debian-administration.org/article/316/An_introduction_to_bash_completion_part_1) and reset your terminal to use autocompletion. If you make additional annotations to your code, you can get even more intelligent and flexible behavior.
-
-## Creating your own custom functions
-
-Some more actual code that works in kubernetes:
-
-```bash
-const (
-        bash_completion_func = `__kubectl_parse_get()
-{
-    local kubectl_output out
-    if kubectl_output=$(kubectl get --no-headers "$1" 2>/dev/null); then
-        out=($(echo "${kubectl_output}" | awk '{print $1}'))
-        COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) )
-    fi
-}
-
-__kubectl_get_resource()
-{
-    if [[ ${#nouns[@]} -eq 0 ]]; then
-        return 1
-    fi
-    __kubectl_parse_get ${nouns[${#nouns[@]} -1]}
-    if [[ $? -eq 0 ]]; then
-        return 0
-    fi
-}
-
-__custom_func() {
-    case ${last_command} in
-        kubectl_get | kubectl_describe | kubectl_delete | kubectl_stop)
-            __kubectl_get_resource
-            return
-            ;;
-        *)
-            ;;
-    esac
-}
-`)
-```
-
-And then I set that in my command definition:
-
-```go
-cmds := &cobra.Command{
-	Use:   "kubectl",
-	Short: "kubectl controls the Kubernetes cluster manager",
-	Long: `kubectl controls the Kubernetes cluster manager.
-
-Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
-	Run: runHelp,
-	BashCompletionFunction: bash_completion_func,
-}
-```
-
-The `BashCompletionFunction` option is really only valid/useful on the root command. Doing the above will cause `__custom_func()` to be called when the built in processor was unable to find a solution. In the case of kubernetes a valid command might look something like `kubectl get pod [mypod]`. If you type `kubectl get pod [tab][tab]` the `__customc_func()` will run because the cobra.Command only understood "kubectl" and "get." `__custom_func()` will see that the cobra.Command is "kubectl_get" and will thus call another helper `__kubectl_get_resource()`.  `__kubectl_get_resource` will look at the 'nouns' collected. In our example the only noun will be `pod`.  So it will call `__kubectl_parse_get pod`.  `__kubectl_parse_get` will actually call out to kubernetes and get any pods.  It will then set `COMPREPLY` to valid pods!
-
-## Have the completions code complete your 'nouns'
-
-In the above example "pod" was assumed to already be typed. But if you want `kubectl get [tab][tab]` to show a list of valid "nouns" you have to set them. Simplified code from `kubectl get` looks like:
-
-```go
-validArgs []string = { "pod", "node", "service", "replicationcontroller" }
-
-cmd := &cobra.Command{
-	Use:     "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)",
-	Short:   "Display one or many resources",
-	Long:    get_long,
-	Example: get_example,
-	Run: func(cmd *cobra.Command, args []string) {
-		err := RunGet(f, out, cmd, args)
-		util.CheckErr(err)
-	},
-	ValidArgs: validArgs,
-}
-```
-
-Notice we put the "ValidArgs" on the "get" subcommand. Doing so will give results like
-
-```bash
-# kubectl get [tab][tab]
-node                 pod                    replicationcontroller  service
-```
-
-## Plural form and shortcuts for nouns
-
-If your nouns have a number of aliases, you can define them alongside `ValidArgs` using `ArgAliases`:
-
-```go
-argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" }
-
-cmd := &cobra.Command{
-    ...
-	ValidArgs:  validArgs,
-	ArgAliases: argAliases
-}
-```
-
-The aliases are not shown to the user on tab completion, but they are accepted as valid nouns by
-the completion algorithm if entered manually, e.g. in:
-
-```bash
-# kubectl get rc [tab][tab]
-backend        frontend       database 
-```
-
-Note that without declaring `rc` as an alias, the completion algorithm would show the list of nouns
-in this example again instead of the replication controllers.
-
-## Mark flags as required
-
-Most of the time completions will only show subcommands. But if a flag is required to make a subcommand work, you probably want it to show up when the user types [tab][tab].  Marking a flag as 'Required' is incredibly easy.
-
-```go
-cmd.MarkFlagRequired("pod")
-cmd.MarkFlagRequired("container")
-```
-
-and you'll get something like
-
-```bash
-# kubectl exec [tab][tab][tab]
--c            --container=  -p            --pod=  
-```
-
-# Specify valid filename extensions for flags that take a filename
-
-In this example we use --filename= and expect to get a json or yaml file as the argument. To make this easier we annotate the --filename flag with valid filename extensions.
-
-```go
-	annotations := []string{"json", "yaml", "yml"}
-	annotation := make(map[string][]string)
-	annotation[cobra.BashCompFilenameExt] = annotations
-
-	flag := &pflag.Flag{
-		Name:        "filename",
-		Shorthand:   "f",
-		Usage:       usage,
-		Value:       value,
-		DefValue:    value.String(),
-		Annotations: annotation,
-	}
-	cmd.Flags().AddFlag(flag)
-```
-
-Now when you run a command with this filename flag you'll get something like
-
-```bash
-# kubectl create -f 
-test/                         example/                      rpmbuild/
-hello.yml                     test.json
-```
-
-So while there are many other files in the CWD it only shows me subdirs and those with valid extensions.
-
-# Specify custom flag completion
-
-Similar to the filename completion and filtering using cobra.BashCompFilenameExt, you can specify
-a custom flag completion function with cobra.BashCompCustom:
-
-```go
-	annotation := make(map[string][]string)
-	annotation[cobra.BashCompCustom] = []string{"__kubectl_get_namespaces"}
-
-	flag := &pflag.Flag{
-		Name:        "namespace",
-		Usage:       usage,
-		Annotations: annotation,
-	}
-	cmd.Flags().AddFlag(flag)
-```
-
-In addition add the `__handle_namespace_flag` implementation in the `BashCompletionFunction`
-value, e.g.:
-
-```bash
-__kubectl_get_namespaces()
-{
-    local template
-    template="{{ range .items  }}{{ .metadata.name }} {{ end }}"
-    local kubectl_out
-    if kubectl_out=$(kubectl get -o template --template="${template}" namespace 2>/dev/null); then
-        COMPREPLY=( $( compgen -W "${kubectl_out}[*]" -- "$cur" ) )
-    fi
-}
-```
-# Using bash aliases for commands
-
-You can also configure the `bash aliases` for the commands and they will also support completions.
-
-```bash
-alias aliasname=origcommand
-complete -o default -F __start_origcommand aliasname
-
-# and now when you run `aliasname` completion will make
-# suggestions as it did for `origcommand`.
-
-$) aliasname <tab><tab>
-completion     firstcommand   secondcommand
-```
diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go
deleted file mode 100644
index 7010fd1..0000000
--- a/vendor/github.com/spf13/cobra/cobra.go
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright © 2013 Steve Francia <spf@spf13.com>.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Commands similar to git, go tools and other modern CLI tools
-// inspired by go, go-Commander, gh and subcommand
-
-package cobra
-
-import (
-	"fmt"
-	"io"
-	"reflect"
-	"strconv"
-	"strings"
-	"text/template"
-	"unicode"
-)
-
-var templateFuncs = template.FuncMap{
-	"trim":                    strings.TrimSpace,
-	"trimRightSpace":          trimRightSpace,
-	"trimTrailingWhitespaces": trimRightSpace,
-	"appendIfNotPresent":      appendIfNotPresent,
-	"rpad":                    rpad,
-	"gt":                      Gt,
-	"eq":                      Eq,
-}
-
-var initializers []func()
-
-// EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing
-// to automatically enable in CLI tools.
-// Set this to true to enable it.
-var EnablePrefixMatching = false
-
-// EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
-// To disable sorting, set it to false.
-var EnableCommandSorting = true
-
-// MousetrapHelpText enables an information splash screen on Windows
-// if the CLI is started from explorer.exe.
-// To disable the mousetrap, just set this variable to blank string ("").
-// Works only on Microsoft Windows.
-var MousetrapHelpText string = `This is a command line tool.
-
-You need to open cmd.exe and run it from there.
-`
-
-// AddTemplateFunc adds a template function that's available to Usage and Help
-// template generation.
-func AddTemplateFunc(name string, tmplFunc interface{}) {
-	templateFuncs[name] = tmplFunc
-}
-
-// AddTemplateFuncs adds multiple template functions that are available to Usage and
-// Help template generation.
-func AddTemplateFuncs(tmplFuncs template.FuncMap) {
-	for k, v := range tmplFuncs {
-		templateFuncs[k] = v
-	}
-}
-
-// OnInitialize sets the passed functions to be run when each command's
-// Execute method is called.
-func OnInitialize(y ...func()) {
-	initializers = append(initializers, y...)
-}
-
-// FIXME Gt is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
-
-// Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
-// Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
-// ints and then compared.
-func Gt(a interface{}, b interface{}) bool {
-	var left, right int64
-	av := reflect.ValueOf(a)
-
-	switch av.Kind() {
-	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
-		left = int64(av.Len())
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		left = av.Int()
-	case reflect.String:
-		left, _ = strconv.ParseInt(av.String(), 10, 64)
-	}
-
-	bv := reflect.ValueOf(b)
-
-	switch bv.Kind() {
-	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
-		right = int64(bv.Len())
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		right = bv.Int()
-	case reflect.String:
-		right, _ = strconv.ParseInt(bv.String(), 10, 64)
-	}
-
-	return left > right
-}
-
-// FIXME Eq is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
-
-// Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
-func Eq(a interface{}, b interface{}) bool {
-	av := reflect.ValueOf(a)
-	bv := reflect.ValueOf(b)
-
-	switch av.Kind() {
-	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
-		panic("Eq called on unsupported type")
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return av.Int() == bv.Int()
-	case reflect.String:
-		return av.String() == bv.String()
-	}
-	return false
-}
-
-func trimRightSpace(s string) string {
-	return strings.TrimRightFunc(s, unicode.IsSpace)
-}
-
-// FIXME appendIfNotPresent is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
-
-// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s.
-func appendIfNotPresent(s, stringToAppend string) string {
-	if strings.Contains(s, stringToAppend) {
-		return s
-	}
-	return s + " " + stringToAppend
-}
-
-// rpad adds padding to the right of a string.
-func rpad(s string, padding int) string {
-	template := fmt.Sprintf("%%-%ds", padding)
-	return fmt.Sprintf(template, s)
-}
-
-// tmpl executes the given template text on data, writing the result to w.
-func tmpl(w io.Writer, text string, data interface{}) error {
-	t := template.New("top")
-	t.Funcs(templateFuncs)
-	template.Must(t.Parse(text))
-	return t.Execute(w, data)
-}
-
-// ld compares two strings and returns the levenshtein distance between them.
-func ld(s, t string, ignoreCase bool) int {
-	if ignoreCase {
-		s = strings.ToLower(s)
-		t = strings.ToLower(t)
-	}
-	d := make([][]int, len(s)+1)
-	for i := range d {
-		d[i] = make([]int, len(t)+1)
-	}
-	for i := range d {
-		d[i][0] = i
-	}
-	for j := range d[0] {
-		d[0][j] = j
-	}
-	for j := 1; j <= len(t); j++ {
-		for i := 1; i <= len(s); i++ {
-			if s[i-1] == t[j-1] {
-				d[i][j] = d[i-1][j-1]
-			} else {
-				min := d[i-1][j]
-				if d[i][j-1] < min {
-					min = d[i][j-1]
-				}
-				if d[i-1][j-1] < min {
-					min = d[i-1][j-1]
-				}
-				d[i][j] = min + 1
-			}
-		}
-
-	}
-	return d[len(s)][len(t)]
-}
-
-func stringInSlice(a string, list []string) bool {
-	for _, b := range list {
-		if b == a {
-			return true
-		}
-	}
-	return false
-}
diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden
deleted file mode 100644
index d645695..0000000
--- a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go
deleted file mode 100644
index 34d1bf3..0000000
--- a/vendor/github.com/spf13/cobra/command.go
+++ /dev/null
@@ -1,1517 +0,0 @@
-// Copyright © 2013 Steve Francia <spf@spf13.com>.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.
-// In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
-package cobra
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"os"
-	"path/filepath"
-	"sort"
-	"strings"
-
-	flag "github.com/spf13/pflag"
-)
-
-// FParseErrWhitelist configures Flag parse errors to be ignored
-type FParseErrWhitelist flag.ParseErrorsWhitelist
-
-// Command is just that, a command for your application.
-// E.g.  'go run ...' - 'run' is the command. Cobra requires
-// you to define the usage and description as part of your command
-// definition to ensure usability.
-type Command struct {
-	// Use is the one-line usage message.
-	Use string
-
-	// Aliases is an array of aliases that can be used instead of the first word in Use.
-	Aliases []string
-
-	// SuggestFor is an array of command names for which this command will be suggested -
-	// similar to aliases but only suggests.
-	SuggestFor []string
-
-	// Short is the short description shown in the 'help' output.
-	Short string
-
-	// Long is the long message shown in the 'help <this-command>' output.
-	Long string
-
-	// Example is examples of how to use the command.
-	Example string
-
-	// ValidArgs is list of all valid non-flag arguments that are accepted in bash completions
-	ValidArgs []string
-
-	// Expected arguments
-	Args PositionalArgs
-
-	// ArgAliases is List of aliases for ValidArgs.
-	// These are not suggested to the user in the bash completion,
-	// but accepted if entered manually.
-	ArgAliases []string
-
-	// BashCompletionFunction is custom functions used by the bash autocompletion generator.
-	BashCompletionFunction string
-
-	// Deprecated defines, if this command is deprecated and should print this string when used.
-	Deprecated string
-
-	// Hidden defines, if this command is hidden and should NOT show up in the list of available commands.
-	Hidden bool
-
-	// Annotations are key/value pairs that can be used by applications to identify or
-	// group commands.
-	Annotations map[string]string
-
-	// Version defines the version for this command. If this value is non-empty and the command does not
-	// define a "version" flag, a "version" boolean flag will be added to the command and, if specified,
-	// will print content of the "Version" variable.
-	Version string
-
-	// The *Run functions are executed in the following order:
-	//   * PersistentPreRun()
-	//   * PreRun()
-	//   * Run()
-	//   * PostRun()
-	//   * PersistentPostRun()
-	// All functions get the same args, the arguments after the command name.
-	//
-	// PersistentPreRun: children of this command will inherit and execute.
-	PersistentPreRun func(cmd *Command, args []string)
-	// PersistentPreRunE: PersistentPreRun but returns an error.
-	PersistentPreRunE func(cmd *Command, args []string) error
-	// PreRun: children of this command will not inherit.
-	PreRun func(cmd *Command, args []string)
-	// PreRunE: PreRun but returns an error.
-	PreRunE func(cmd *Command, args []string) error
-	// Run: Typically the actual work function. Most commands will only implement this.
-	Run func(cmd *Command, args []string)
-	// RunE: Run but returns an error.
-	RunE func(cmd *Command, args []string) error
-	// PostRun: run after the Run command.
-	PostRun func(cmd *Command, args []string)
-	// PostRunE: PostRun but returns an error.
-	PostRunE func(cmd *Command, args []string) error
-	// PersistentPostRun: children of this command will inherit and execute after PostRun.
-	PersistentPostRun func(cmd *Command, args []string)
-	// PersistentPostRunE: PersistentPostRun but returns an error.
-	PersistentPostRunE func(cmd *Command, args []string) error
-
-	// SilenceErrors is an option to quiet errors down stream.
-	SilenceErrors bool
-
-	// SilenceUsage is an option to silence usage when an error occurs.
-	SilenceUsage bool
-
-	// DisableFlagParsing disables the flag parsing.
-	// If this is true all flags will be passed to the command as arguments.
-	DisableFlagParsing bool
-
-	// DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...")
-	// will be printed by generating docs for this command.
-	DisableAutoGenTag bool
-
-	// DisableFlagsInUseLine will disable the addition of [flags] to the usage
-	// line of a command when printing help or generating docs
-	DisableFlagsInUseLine bool
-
-	// DisableSuggestions disables the suggestions based on Levenshtein distance
-	// that go along with 'unknown command' messages.
-	DisableSuggestions bool
-	// SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
-	// Must be > 0.
-	SuggestionsMinimumDistance int
-
-	// TraverseChildren parses flags on all parents before executing child command.
-	TraverseChildren bool
-
-	//FParseErrWhitelist flag parse errors to be ignored
-	FParseErrWhitelist FParseErrWhitelist
-
-	// commands is the list of commands supported by this program.
-	commands []*Command
-	// parent is a parent command for this command.
-	parent *Command
-	// Max lengths of commands' string lengths for use in padding.
-	commandsMaxUseLen         int
-	commandsMaxCommandPathLen int
-	commandsMaxNameLen        int
-	// commandsAreSorted defines, if command slice are sorted or not.
-	commandsAreSorted bool
-	// commandCalledAs is the name or alias value used to call this command.
-	commandCalledAs struct {
-		name   string
-		called bool
-	}
-
-	// args is actual args parsed from flags.
-	args []string
-	// flagErrorBuf contains all error messages from pflag.
-	flagErrorBuf *bytes.Buffer
-	// flags is full set of flags.
-	flags *flag.FlagSet
-	// pflags contains persistent flags.
-	pflags *flag.FlagSet
-	// lflags contains local flags.
-	lflags *flag.FlagSet
-	// iflags contains inherited flags.
-	iflags *flag.FlagSet
-	// parentsPflags is all persistent flags of cmd's parents.
-	parentsPflags *flag.FlagSet
-	// globNormFunc is the global normalization function
-	// that we can use on every pflag set and children commands
-	globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
-
-	// output is an output writer defined by user.
-	output io.Writer
-	// usageFunc is usage func defined by user.
-	usageFunc func(*Command) error
-	// usageTemplate is usage template defined by user.
-	usageTemplate string
-	// flagErrorFunc is func defined by user and it's called when the parsing of
-	// flags returns an error.
-	flagErrorFunc func(*Command, error) error
-	// helpTemplate is help template defined by user.
-	helpTemplate string
-	// helpFunc is help func defined by user.
-	helpFunc func(*Command, []string)
-	// helpCommand is command with usage 'help'. If it's not defined by user,
-	// cobra uses default help command.
-	helpCommand *Command
-	// versionTemplate is the version template defined by user.
-	versionTemplate string
-}
-
-// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
-// particularly useful when testing.
-func (c *Command) SetArgs(a []string) {
-	c.args = a
-}
-
-// SetOutput sets the destination for usage and error messages.
-// If output is nil, os.Stderr is used.
-func (c *Command) SetOutput(output io.Writer) {
-	c.output = output
-}
-
-// SetUsageFunc sets usage function. Usage can be defined by application.
-func (c *Command) SetUsageFunc(f func(*Command) error) {
-	c.usageFunc = f
-}
-
-// SetUsageTemplate sets usage template. Can be defined by Application.
-func (c *Command) SetUsageTemplate(s string) {
-	c.usageTemplate = s
-}
-
-// SetFlagErrorFunc sets a function to generate an error when flag parsing
-// fails.
-func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
-	c.flagErrorFunc = f
-}
-
-// SetHelpFunc sets help function. Can be defined by Application.
-func (c *Command) SetHelpFunc(f func(*Command, []string)) {
-	c.helpFunc = f
-}
-
-// SetHelpCommand sets help command.
-func (c *Command) SetHelpCommand(cmd *Command) {
-	c.helpCommand = cmd
-}
-
-// SetHelpTemplate sets help template to be used. Application can use it to set custom template.
-func (c *Command) SetHelpTemplate(s string) {
-	c.helpTemplate = s
-}
-
-// SetVersionTemplate sets version template to be used. Application can use it to set custom template.
-func (c *Command) SetVersionTemplate(s string) {
-	c.versionTemplate = s
-}
-
-// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.
-// The user should not have a cyclic dependency on commands.
-func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {
-	c.Flags().SetNormalizeFunc(n)
-	c.PersistentFlags().SetNormalizeFunc(n)
-	c.globNormFunc = n
-
-	for _, command := range c.commands {
-		command.SetGlobalNormalizationFunc(n)
-	}
-}
-
-// OutOrStdout returns output to stdout.
-func (c *Command) OutOrStdout() io.Writer {
-	return c.getOut(os.Stdout)
-}
-
-// OutOrStderr returns output to stderr
-func (c *Command) OutOrStderr() io.Writer {
-	return c.getOut(os.Stderr)
-}
-
-func (c *Command) getOut(def io.Writer) io.Writer {
-	if c.output != nil {
-		return c.output
-	}
-	if c.HasParent() {
-		return c.parent.getOut(def)
-	}
-	return def
-}
-
-// UsageFunc returns either the function set by SetUsageFunc for this command
-// or a parent, or it returns a default usage function.
-func (c *Command) UsageFunc() (f func(*Command) error) {
-	if c.usageFunc != nil {
-		return c.usageFunc
-	}
-	if c.HasParent() {
-		return c.Parent().UsageFunc()
-	}
-	return func(c *Command) error {
-		c.mergePersistentFlags()
-		err := tmpl(c.OutOrStderr(), c.UsageTemplate(), c)
-		if err != nil {
-			c.Println(err)
-		}
-		return err
-	}
-}
-
-// Usage puts out the usage for the command.
-// Used when a user provides invalid input.
-// Can be defined by user by overriding UsageFunc.
-func (c *Command) Usage() error {
-	return c.UsageFunc()(c)
-}
-
-// HelpFunc returns either the function set by SetHelpFunc for this command
-// or a parent, or it returns a function with default help behavior.
-func (c *Command) HelpFunc() func(*Command, []string) {
-	if c.helpFunc != nil {
-		return c.helpFunc
-	}
-	if c.HasParent() {
-		return c.Parent().HelpFunc()
-	}
-	return func(c *Command, a []string) {
-		c.mergePersistentFlags()
-		err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
-		if err != nil {
-			c.Println(err)
-		}
-	}
-}
-
-// Help puts out the help for the command.
-// Used when a user calls help [command].
-// Can be defined by user by overriding HelpFunc.
-func (c *Command) Help() error {
-	c.HelpFunc()(c, []string{})
-	return nil
-}
-
-// UsageString return usage string.
-func (c *Command) UsageString() string {
-	tmpOutput := c.output
-	bb := new(bytes.Buffer)
-	c.SetOutput(bb)
-	c.Usage()
-	c.output = tmpOutput
-	return bb.String()
-}
-
-// FlagErrorFunc returns either the function set by SetFlagErrorFunc for this
-// command or a parent, or it returns a function which returns the original
-// error.
-func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
-	if c.flagErrorFunc != nil {
-		return c.flagErrorFunc
-	}
-
-	if c.HasParent() {
-		return c.parent.FlagErrorFunc()
-	}
-	return func(c *Command, err error) error {
-		return err
-	}
-}
-
-var minUsagePadding = 25
-
-// UsagePadding return padding for the usage.
-func (c *Command) UsagePadding() int {
-	if c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen {
-		return minUsagePadding
-	}
-	return c.parent.commandsMaxUseLen
-}
-
-var minCommandPathPadding = 11
-
-// CommandPathPadding return padding for the command path.
-func (c *Command) CommandPathPadding() int {
-	if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen {
-		return minCommandPathPadding
-	}
-	return c.parent.commandsMaxCommandPathLen
-}
-
-var minNamePadding = 11
-
-// NamePadding returns padding for the name.
-func (c *Command) NamePadding() int {
-	if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen {
-		return minNamePadding
-	}
-	return c.parent.commandsMaxNameLen
-}
-
-// UsageTemplate returns usage template for the command.
-func (c *Command) UsageTemplate() string {
-	if c.usageTemplate != "" {
-		return c.usageTemplate
-	}
-
-	if c.HasParent() {
-		return c.parent.UsageTemplate()
-	}
-	return `Usage:{{if .Runnable}}
-  {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
-  {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
-
-Aliases:
-  {{.NameAndAliases}}{{end}}{{if .HasExample}}
-
-Examples:
-{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
-
-Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
-  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
-
-Flags:
-{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
-
-Global Flags:
-{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
-
-Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
-  {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
-
-Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
-`
-}
-
-// HelpTemplate return help template for the command.
-func (c *Command) HelpTemplate() string {
-	if c.helpTemplate != "" {
-		return c.helpTemplate
-	}
-
-	if c.HasParent() {
-		return c.parent.HelpTemplate()
-	}
-	return `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}}
-
-{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
-}
-
-// VersionTemplate return version template for the command.
-func (c *Command) VersionTemplate() string {
-	if c.versionTemplate != "" {
-		return c.versionTemplate
-	}
-
-	if c.HasParent() {
-		return c.parent.VersionTemplate()
-	}
-	return `{{with .Name}}{{printf "%s " .}}{{end}}{{printf "version %s" .Version}}
-`
-}
-
-func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
-	flag := fs.Lookup(name)
-	if flag == nil {
-		return false
-	}
-	return flag.NoOptDefVal != ""
-}
-
-func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool {
-	if len(name) == 0 {
-		return false
-	}
-
-	flag := fs.ShorthandLookup(name[:1])
-	if flag == nil {
-		return false
-	}
-	return flag.NoOptDefVal != ""
-}
-
-func stripFlags(args []string, c *Command) []string {
-	if len(args) == 0 {
-		return args
-	}
-	c.mergePersistentFlags()
-
-	commands := []string{}
-	flags := c.Flags()
-
-Loop:
-	for len(args) > 0 {
-		s := args[0]
-		args = args[1:]
-		switch {
-		case s == "--":
-			// "--" terminates the flags
-			break Loop
-		case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
-			// If '--flag arg' then
-			// delete arg from args.
-			fallthrough // (do the same as below)
-		case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
-			// If '-f arg' then
-			// delete 'arg' from args or break the loop if len(args) <= 1.
-			if len(args) <= 1 {
-				break Loop
-			} else {
-				args = args[1:]
-				continue
-			}
-		case s != "" && !strings.HasPrefix(s, "-"):
-			commands = append(commands, s)
-		}
-	}
-
-	return commands
-}
-
-// argsMinusFirstX removes only the first x from args.  Otherwise, commands that look like
-// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]).
-func argsMinusFirstX(args []string, x string) []string {
-	for i, y := range args {
-		if x == y {
-			ret := []string{}
-			ret = append(ret, args[:i]...)
-			ret = append(ret, args[i+1:]...)
-			return ret
-		}
-	}
-	return args
-}
-
-func isFlagArg(arg string) bool {
-	return ((len(arg) >= 3 && arg[1] == '-') ||
-		(len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
-}
-
-// Find the target command given the args and command tree
-// Meant to be run on the highest node. Only searches down.
-func (c *Command) Find(args []string) (*Command, []string, error) {
-	var innerfind func(*Command, []string) (*Command, []string)
-
-	innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
-		argsWOflags := stripFlags(innerArgs, c)
-		if len(argsWOflags) == 0 {
-			return c, innerArgs
-		}
-		nextSubCmd := argsWOflags[0]
-
-		cmd := c.findNext(nextSubCmd)
-		if cmd != nil {
-			return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
-		}
-		return c, innerArgs
-	}
-
-	commandFound, a := innerfind(c, args)
-	if commandFound.Args == nil {
-		return commandFound, a, legacyArgs(commandFound, stripFlags(a, commandFound))
-	}
-	return commandFound, a, nil
-}
-
-func (c *Command) findSuggestions(arg string) string {
-	if c.DisableSuggestions {
-		return ""
-	}
-	if c.SuggestionsMinimumDistance <= 0 {
-		c.SuggestionsMinimumDistance = 2
-	}
-	suggestionsString := ""
-	if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {
-		suggestionsString += "\n\nDid you mean this?\n"
-		for _, s := range suggestions {
-			suggestionsString += fmt.Sprintf("\t%v\n", s)
-		}
-	}
-	return suggestionsString
-}
-
-func (c *Command) findNext(next string) *Command {
-	matches := make([]*Command, 0)
-	for _, cmd := range c.commands {
-		if cmd.Name() == next || cmd.HasAlias(next) {
-			cmd.commandCalledAs.name = next
-			return cmd
-		}
-		if EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) {
-			matches = append(matches, cmd)
-		}
-	}
-
-	if len(matches) == 1 {
-		return matches[0]
-	}
-
-	return nil
-}
-
-// Traverse the command tree to find the command, and parse args for
-// each parent.
-func (c *Command) Traverse(args []string) (*Command, []string, error) {
-	flags := []string{}
-	inFlag := false
-
-	for i, arg := range args {
-		switch {
-		// A long flag with a space separated value
-		case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="):
-			// TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
-			inFlag = !hasNoOptDefVal(arg[2:], c.Flags())
-			flags = append(flags, arg)
-			continue
-		// A short flag with a space separated value
-		case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], c.Flags()):
-			inFlag = true
-			flags = append(flags, arg)
-			continue
-		// The value for a flag
-		case inFlag:
-			inFlag = false
-			flags = append(flags, arg)
-			continue
-		// A flag without a value, or with an `=` separated value
-		case isFlagArg(arg):
-			flags = append(flags, arg)
-			continue
-		}
-
-		cmd := c.findNext(arg)
-		if cmd == nil {
-			return c, args, nil
-		}
-
-		if err := c.ParseFlags(flags); err != nil {
-			return nil, args, err
-		}
-		return cmd.Traverse(args[i+1:])
-	}
-	return c, args, nil
-}
-
-// SuggestionsFor provides suggestions for the typedName.
-func (c *Command) SuggestionsFor(typedName string) []string {
-	suggestions := []string{}
-	for _, cmd := range c.commands {
-		if cmd.IsAvailableCommand() {
-			levenshteinDistance := ld(typedName, cmd.Name(), true)
-			suggestByLevenshtein := levenshteinDistance <= c.SuggestionsMinimumDistance
-			suggestByPrefix := strings.HasPrefix(strings.ToLower(cmd.Name()), strings.ToLower(typedName))
-			if suggestByLevenshtein || suggestByPrefix {
-				suggestions = append(suggestions, cmd.Name())
-			}
-			for _, explicitSuggestion := range cmd.SuggestFor {
-				if strings.EqualFold(typedName, explicitSuggestion) {
-					suggestions = append(suggestions, cmd.Name())
-				}
-			}
-		}
-	}
-	return suggestions
-}
-
-// VisitParents visits all parents of the command and invokes fn on each parent.
-func (c *Command) VisitParents(fn func(*Command)) {
-	if c.HasParent() {
-		fn(c.Parent())
-		c.Parent().VisitParents(fn)
-	}
-}
-
-// Root finds root command.
-func (c *Command) Root() *Command {
-	if c.HasParent() {
-		return c.Parent().Root()
-	}
-	return c
-}
-
-// ArgsLenAtDash will return the length of c.Flags().Args at the moment
-// when a -- was found during args parsing.
-func (c *Command) ArgsLenAtDash() int {
-	return c.Flags().ArgsLenAtDash()
-}
-
-func (c *Command) execute(a []string) (err error) {
-	if c == nil {
-		return fmt.Errorf("Called Execute() on a nil Command")
-	}
-
-	if len(c.Deprecated) > 0 {
-		c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated)
-	}
-
-	// initialize help and version flag at the last point possible to allow for user
-	// overriding
-	c.InitDefaultHelpFlag()
-	c.InitDefaultVersionFlag()
-
-	err = c.ParseFlags(a)
-	if err != nil {
-		return c.FlagErrorFunc()(c, err)
-	}
-
-	// If help is called, regardless of other flags, return we want help.
-	// Also say we need help if the command isn't runnable.
-	helpVal, err := c.Flags().GetBool("help")
-	if err != nil {
-		// should be impossible to get here as we always declare a help
-		// flag in InitDefaultHelpFlag()
-		c.Println("\"help\" flag declared as non-bool. Please correct your code")
-		return err
-	}
-
-	if helpVal {
-		return flag.ErrHelp
-	}
-
-	// for back-compat, only add version flag behavior if version is defined
-	if c.Version != "" {
-		versionVal, err := c.Flags().GetBool("version")
-		if err != nil {
-			c.Println("\"version\" flag declared as non-bool. Please correct your code")
-			return err
-		}
-		if versionVal {
-			err := tmpl(c.OutOrStdout(), c.VersionTemplate(), c)
-			if err != nil {
-				c.Println(err)
-			}
-			return err
-		}
-	}
-
-	if !c.Runnable() {
-		return flag.ErrHelp
-	}
-
-	c.preRun()
-
-	argWoFlags := c.Flags().Args()
-	if c.DisableFlagParsing {
-		argWoFlags = a
-	}
-
-	if err := c.ValidateArgs(argWoFlags); err != nil {
-		return err
-	}
-
-	for p := c; p != nil; p = p.Parent() {
-		if p.PersistentPreRunE != nil {
-			if err := p.PersistentPreRunE(c, argWoFlags); err != nil {
-				return err
-			}
-			break
-		} else if p.PersistentPreRun != nil {
-			p.PersistentPreRun(c, argWoFlags)
-			break
-		}
-	}
-	if c.PreRunE != nil {
-		if err := c.PreRunE(c, argWoFlags); err != nil {
-			return err
-		}
-	} else if c.PreRun != nil {
-		c.PreRun(c, argWoFlags)
-	}
-
-	if err := c.validateRequiredFlags(); err != nil {
-		return err
-	}
-	if c.RunE != nil {
-		if err := c.RunE(c, argWoFlags); err != nil {
-			return err
-		}
-	} else {
-		c.Run(c, argWoFlags)
-	}
-	if c.PostRunE != nil {
-		if err := c.PostRunE(c, argWoFlags); err != nil {
-			return err
-		}
-	} else if c.PostRun != nil {
-		c.PostRun(c, argWoFlags)
-	}
-	for p := c; p != nil; p = p.Parent() {
-		if p.PersistentPostRunE != nil {
-			if err := p.PersistentPostRunE(c, argWoFlags); err != nil {
-				return err
-			}
-			break
-		} else if p.PersistentPostRun != nil {
-			p.PersistentPostRun(c, argWoFlags)
-			break
-		}
-	}
-
-	return nil
-}
-
-func (c *Command) preRun() {
-	for _, x := range initializers {
-		x()
-	}
-}
-
-// Execute uses the args (os.Args[1:] by default)
-// and run through the command tree finding appropriate matches
-// for commands and then corresponding flags.
-func (c *Command) Execute() error {
-	_, err := c.ExecuteC()
-	return err
-}
-
-// ExecuteC executes the command.
-func (c *Command) ExecuteC() (cmd *Command, err error) {
-	// Regardless of what command execute is called on, run on Root only
-	if c.HasParent() {
-		return c.Root().ExecuteC()
-	}
-
-	// windows hook
-	if preExecHookFn != nil {
-		preExecHookFn(c)
-	}
-
-	// initialize help as the last point possible to allow for user
-	// overriding
-	c.InitDefaultHelpCmd()
-
-	var args []string
-
-	// Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
-	if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
-		args = os.Args[1:]
-	} else {
-		args = c.args
-	}
-
-	var flags []string
-	if c.TraverseChildren {
-		cmd, flags, err = c.Traverse(args)
-	} else {
-		cmd, flags, err = c.Find(args)
-	}
-	if err != nil {
-		// If found parse to a subcommand and then failed, talk about the subcommand
-		if cmd != nil {
-			c = cmd
-		}
-		if !c.SilenceErrors {
-			c.Println("Error:", err.Error())
-			c.Printf("Run '%v --help' for usage.\n", c.CommandPath())
-		}
-		return c, err
-	}
-
-	cmd.commandCalledAs.called = true
-	if cmd.commandCalledAs.name == "" {
-		cmd.commandCalledAs.name = cmd.Name()
-	}
-
-	err = cmd.execute(flags)
-	if err != nil {
-		// Always show help if requested, even if SilenceErrors is in
-		// effect
-		if err == flag.ErrHelp {
-			cmd.HelpFunc()(cmd, args)
-			return cmd, nil
-		}
-
-		// If root command has SilentErrors flagged,
-		// all subcommands should respect it
-		if !cmd.SilenceErrors && !c.SilenceErrors {
-			c.Println("Error:", err.Error())
-		}
-
-		// If root command has SilentUsage flagged,
-		// all subcommands should respect it
-		if !cmd.SilenceUsage && !c.SilenceUsage {
-			c.Println(cmd.UsageString())
-		}
-	}
-	return cmd, err
-}
-
-func (c *Command) ValidateArgs(args []string) error {
-	if c.Args == nil {
-		return nil
-	}
-	return c.Args(c, args)
-}
-
-func (c *Command) validateRequiredFlags() error {
-	flags := c.Flags()
-	missingFlagNames := []string{}
-	flags.VisitAll(func(pflag *flag.Flag) {
-		requiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag]
-		if !found {
-			return
-		}
-		if (requiredAnnotation[0] == "true") && !pflag.Changed {
-			missingFlagNames = append(missingFlagNames, pflag.Name)
-		}
-	})
-
-	if len(missingFlagNames) > 0 {
-		return fmt.Errorf(`required flag(s) "%s" not set`, strings.Join(missingFlagNames, `", "`))
-	}
-	return nil
-}
-
-// InitDefaultHelpFlag adds default help flag to c.
-// It is called automatically by executing the c or by calling help and usage.
-// If c already has help flag, it will do nothing.
-func (c *Command) InitDefaultHelpFlag() {
-	c.mergePersistentFlags()
-	if c.Flags().Lookup("help") == nil {
-		usage := "help for "
-		if c.Name() == "" {
-			usage += "this command"
-		} else {
-			usage += c.Name()
-		}
-		c.Flags().BoolP("help", "h", false, usage)
-	}
-}
-
-// InitDefaultVersionFlag adds default version flag to c.
-// It is called automatically by executing the c.
-// If c already has a version flag, it will do nothing.
-// If c.Version is empty, it will do nothing.
-func (c *Command) InitDefaultVersionFlag() {
-	if c.Version == "" {
-		return
-	}
-
-	c.mergePersistentFlags()
-	if c.Flags().Lookup("version") == nil {
-		usage := "version for "
-		if c.Name() == "" {
-			usage += "this command"
-		} else {
-			usage += c.Name()
-		}
-		c.Flags().Bool("version", false, usage)
-	}
-}
-
-// InitDefaultHelpCmd adds default help command to c.
-// It is called automatically by executing the c or by calling help and usage.
-// If c already has help command or c has no subcommands, it will do nothing.
-func (c *Command) InitDefaultHelpCmd() {
-	if !c.HasSubCommands() {
-		return
-	}
-
-	if c.helpCommand == nil {
-		c.helpCommand = &Command{
-			Use:   "help [command]",
-			Short: "Help about any command",
-			Long: `Help provides help for any command in the application.
-Simply type ` + c.Name() + ` help [path to command] for full details.`,
-
-			Run: func(c *Command, args []string) {
-				cmd, _, e := c.Root().Find(args)
-				if cmd == nil || e != nil {
-					c.Printf("Unknown help topic %#q\n", args)
-					c.Root().Usage()
-				} else {
-					cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown
-					cmd.Help()
-				}
-			},
-		}
-	}
-	c.RemoveCommand(c.helpCommand)
-	c.AddCommand(c.helpCommand)
-}
-
-// ResetCommands delete parent, subcommand and help command from c.
-func (c *Command) ResetCommands() {
-	c.parent = nil
-	c.commands = nil
-	c.helpCommand = nil
-	c.parentsPflags = nil
-}
-
-// Sorts commands by their names.
-type commandSorterByName []*Command
-
-func (c commandSorterByName) Len() int           { return len(c) }
-func (c commandSorterByName) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }
-func (c commandSorterByName) Less(i, j int) bool { return c[i].Name() < c[j].Name() }
-
-// Commands returns a sorted slice of child commands.
-func (c *Command) Commands() []*Command {
-	// do not sort commands if it already sorted or sorting was disabled
-	if EnableCommandSorting && !c.commandsAreSorted {
-		sort.Sort(commandSorterByName(c.commands))
-		c.commandsAreSorted = true
-	}
-	return c.commands
-}
-
-// AddCommand adds one or more commands to this parent command.
-func (c *Command) AddCommand(cmds ...*Command) {
-	for i, x := range cmds {
-		if cmds[i] == c {
-			panic("Command can't be a child of itself")
-		}
-		cmds[i].parent = c
-		// update max lengths
-		usageLen := len(x.Use)
-		if usageLen > c.commandsMaxUseLen {
-			c.commandsMaxUseLen = usageLen
-		}
-		commandPathLen := len(x.CommandPath())
-		if commandPathLen > c.commandsMaxCommandPathLen {
-			c.commandsMaxCommandPathLen = commandPathLen
-		}
-		nameLen := len(x.Name())
-		if nameLen > c.commandsMaxNameLen {
-			c.commandsMaxNameLen = nameLen
-		}
-		// If global normalization function exists, update all children
-		if c.globNormFunc != nil {
-			x.SetGlobalNormalizationFunc(c.globNormFunc)
-		}
-		c.commands = append(c.commands, x)
-		c.commandsAreSorted = false
-	}
-}
-
-// RemoveCommand removes one or more commands from a parent command.
-func (c *Command) RemoveCommand(cmds ...*Command) {
-	commands := []*Command{}
-main:
-	for _, command := range c.commands {
-		for _, cmd := range cmds {
-			if command == cmd {
-				command.parent = nil
-				continue main
-			}
-		}
-		commands = append(commands, command)
-	}
-	c.commands = commands
-	// recompute all lengths
-	c.commandsMaxUseLen = 0
-	c.commandsMaxCommandPathLen = 0
-	c.commandsMaxNameLen = 0
-	for _, command := range c.commands {
-		usageLen := len(command.Use)
-		if usageLen > c.commandsMaxUseLen {
-			c.commandsMaxUseLen = usageLen
-		}
-		commandPathLen := len(command.CommandPath())
-		if commandPathLen > c.commandsMaxCommandPathLen {
-			c.commandsMaxCommandPathLen = commandPathLen
-		}
-		nameLen := len(command.Name())
-		if nameLen > c.commandsMaxNameLen {
-			c.commandsMaxNameLen = nameLen
-		}
-	}
-}
-
-// Print is a convenience method to Print to the defined output, fallback to Stderr if not set.
-func (c *Command) Print(i ...interface{}) {
-	fmt.Fprint(c.OutOrStderr(), i...)
-}
-
-// Println is a convenience method to Println to the defined output, fallback to Stderr if not set.
-func (c *Command) Println(i ...interface{}) {
-	c.Print(fmt.Sprintln(i...))
-}
-
-// Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set.
-func (c *Command) Printf(format string, i ...interface{}) {
-	c.Print(fmt.Sprintf(format, i...))
-}
-
-// CommandPath returns the full path to this command.
-func (c *Command) CommandPath() string {
-	if c.HasParent() {
-		return c.Parent().CommandPath() + " " + c.Name()
-	}
-	return c.Name()
-}
-
-// UseLine puts out the full usage for a given command (including parents).
-func (c *Command) UseLine() string {
-	var useline string
-	if c.HasParent() {
-		useline = c.parent.CommandPath() + " " + c.Use
-	} else {
-		useline = c.Use
-	}
-	if c.DisableFlagsInUseLine {
-		return useline
-	}
-	if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") {
-		useline += " [flags]"
-	}
-	return useline
-}
-
-// DebugFlags used to determine which flags have been assigned to which commands
-// and which persist.
-func (c *Command) DebugFlags() {
-	c.Println("DebugFlags called on", c.Name())
-	var debugflags func(*Command)
-
-	debugflags = func(x *Command) {
-		if x.HasFlags() || x.HasPersistentFlags() {
-			c.Println(x.Name())
-		}
-		if x.HasFlags() {
-			x.flags.VisitAll(func(f *flag.Flag) {
-				if x.HasPersistentFlags() && x.persistentFlag(f.Name) != nil {
-					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [LP]")
-				} else {
-					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [L]")
-				}
-			})
-		}
-		if x.HasPersistentFlags() {
-			x.pflags.VisitAll(func(f *flag.Flag) {
-				if x.HasFlags() {
-					if x.flags.Lookup(f.Name) == nil {
-						c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [P]")
-					}
-				} else {
-					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [P]")
-				}
-			})
-		}
-		c.Println(x.flagErrorBuf)
-		if x.HasSubCommands() {
-			for _, y := range x.commands {
-				debugflags(y)
-			}
-		}
-	}
-
-	debugflags(c)
-}
-
-// Name returns the command's name: the first word in the use line.
-func (c *Command) Name() string {
-	name := c.Use
-	i := strings.Index(name, " ")
-	if i >= 0 {
-		name = name[:i]
-	}
-	return name
-}
-
-// HasAlias determines if a given string is an alias of the command.
-func (c *Command) HasAlias(s string) bool {
-	for _, a := range c.Aliases {
-		if a == s {
-			return true
-		}
-	}
-	return false
-}
-
-// CalledAs returns the command name or alias that was used to invoke
-// this command or an empty string if the command has not been called.
-func (c *Command) CalledAs() string {
-	if c.commandCalledAs.called {
-		return c.commandCalledAs.name
-	}
-	return ""
-}
-
-// hasNameOrAliasPrefix returns true if the Name or any of aliases start
-// with prefix
-func (c *Command) hasNameOrAliasPrefix(prefix string) bool {
-	if strings.HasPrefix(c.Name(), prefix) {
-		c.commandCalledAs.name = c.Name()
-		return true
-	}
-	for _, alias := range c.Aliases {
-		if strings.HasPrefix(alias, prefix) {
-			c.commandCalledAs.name = alias
-			return true
-		}
-	}
-	return false
-}
-
-// NameAndAliases returns a list of the command name and all aliases
-func (c *Command) NameAndAliases() string {
-	return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
-}
-
-// HasExample determines if the command has example.
-func (c *Command) HasExample() bool {
-	return len(c.Example) > 0
-}
-
-// Runnable determines if the command is itself runnable.
-func (c *Command) Runnable() bool {
-	return c.Run != nil || c.RunE != nil
-}
-
-// HasSubCommands determines if the command has children commands.
-func (c *Command) HasSubCommands() bool {
-	return len(c.commands) > 0
-}
-
-// IsAvailableCommand determines if a command is available as a non-help command
-// (this includes all non deprecated/hidden commands).
-func (c *Command) IsAvailableCommand() bool {
-	if len(c.Deprecated) != 0 || c.Hidden {
-		return false
-	}
-
-	if c.HasParent() && c.Parent().helpCommand == c {
-		return false
-	}
-
-	if c.Runnable() || c.HasAvailableSubCommands() {
-		return true
-	}
-
-	return false
-}
-
-// IsAdditionalHelpTopicCommand determines if a command is an additional
-// help topic command; additional help topic command is determined by the
-// fact that it is NOT runnable/hidden/deprecated, and has no sub commands that
-// are runnable/hidden/deprecated.
-// Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924.
-func (c *Command) IsAdditionalHelpTopicCommand() bool {
-	// if a command is runnable, deprecated, or hidden it is not a 'help' command
-	if c.Runnable() || len(c.Deprecated) != 0 || c.Hidden {
-		return false
-	}
-
-	// if any non-help sub commands are found, the command is not a 'help' command
-	for _, sub := range c.commands {
-		if !sub.IsAdditionalHelpTopicCommand() {
-			return false
-		}
-	}
-
-	// the command either has no sub commands, or no non-help sub commands
-	return true
-}
-
-// HasHelpSubCommands determines if a command has any available 'help' sub commands
-// that need to be shown in the usage/help default template under 'additional help
-// topics'.
-func (c *Command) HasHelpSubCommands() bool {
-	// return true on the first found available 'help' sub command
-	for _, sub := range c.commands {
-		if sub.IsAdditionalHelpTopicCommand() {
-			return true
-		}
-	}
-
-	// the command either has no sub commands, or no available 'help' sub commands
-	return false
-}
-
-// HasAvailableSubCommands determines if a command has available sub commands that
-// need to be shown in the usage/help default template under 'available commands'.
-func (c *Command) HasAvailableSubCommands() bool {
-	// return true on the first found available (non deprecated/help/hidden)
-	// sub command
-	for _, sub := range c.commands {
-		if sub.IsAvailableCommand() {
-			return true
-		}
-	}
-
-	// the command either has no sub commands, or no available (non deprecated/help/hidden)
-	// sub commands
-	return false
-}
-
-// HasParent determines if the command is a child command.
-func (c *Command) HasParent() bool {
-	return c.parent != nil
-}
-
-// GlobalNormalizationFunc returns the global normalization function or nil if it doesn't exist.
-func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {
-	return c.globNormFunc
-}
-
-// Flags returns the complete FlagSet that applies
-// to this command (local and persistent declared here and by all parents).
-func (c *Command) Flags() *flag.FlagSet {
-	if c.flags == nil {
-		c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
-		if c.flagErrorBuf == nil {
-			c.flagErrorBuf = new(bytes.Buffer)
-		}
-		c.flags.SetOutput(c.flagErrorBuf)
-	}
-
-	return c.flags
-}
-
-// LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands.
-func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
-	persistentFlags := c.PersistentFlags()
-
-	out := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
-	c.LocalFlags().VisitAll(func(f *flag.Flag) {
-		if persistentFlags.Lookup(f.Name) == nil {
-			out.AddFlag(f)
-		}
-	})
-	return out
-}
-
-// LocalFlags returns the local FlagSet specifically set in the current command.
-func (c *Command) LocalFlags() *flag.FlagSet {
-	c.mergePersistentFlags()
-
-	if c.lflags == nil {
-		c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
-		if c.flagErrorBuf == nil {
-			c.flagErrorBuf = new(bytes.Buffer)
-		}
-		c.lflags.SetOutput(c.flagErrorBuf)
-	}
-	c.lflags.SortFlags = c.Flags().SortFlags
-	if c.globNormFunc != nil {
-		c.lflags.SetNormalizeFunc(c.globNormFunc)
-	}
-
-	addToLocal := func(f *flag.Flag) {
-		if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil {
-			c.lflags.AddFlag(f)
-		}
-	}
-	c.Flags().VisitAll(addToLocal)
-	c.PersistentFlags().VisitAll(addToLocal)
-	return c.lflags
-}
-
-// InheritedFlags returns all flags which were inherited from parents commands.
-func (c *Command) InheritedFlags() *flag.FlagSet {
-	c.mergePersistentFlags()
-
-	if c.iflags == nil {
-		c.iflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
-		if c.flagErrorBuf == nil {
-			c.flagErrorBuf = new(bytes.Buffer)
-		}
-		c.iflags.SetOutput(c.flagErrorBuf)
-	}
-
-	local := c.LocalFlags()
-	if c.globNormFunc != nil {
-		c.iflags.SetNormalizeFunc(c.globNormFunc)
-	}
-
-	c.parentsPflags.VisitAll(func(f *flag.Flag) {
-		if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
-			c.iflags.AddFlag(f)
-		}
-	})
-	return c.iflags
-}
-
-// NonInheritedFlags returns all flags which were not inherited from parent commands.
-func (c *Command) NonInheritedFlags() *flag.FlagSet {
-	return c.LocalFlags()
-}
-
-// PersistentFlags returns the persistent FlagSet specifically set in the current command.
-func (c *Command) PersistentFlags() *flag.FlagSet {
-	if c.pflags == nil {
-		c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
-		if c.flagErrorBuf == nil {
-			c.flagErrorBuf = new(bytes.Buffer)
-		}
-		c.pflags.SetOutput(c.flagErrorBuf)
-	}
-	return c.pflags
-}
-
-// ResetFlags deletes all flags from command.
-func (c *Command) ResetFlags() {
-	c.flagErrorBuf = new(bytes.Buffer)
-	c.flagErrorBuf.Reset()
-	c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
-	c.flags.SetOutput(c.flagErrorBuf)
-	c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
-	c.pflags.SetOutput(c.flagErrorBuf)
-
-	c.lflags = nil
-	c.iflags = nil
-	c.parentsPflags = nil
-}
-
-// HasFlags checks if the command contains any flags (local plus persistent from the entire structure).
-func (c *Command) HasFlags() bool {
-	return c.Flags().HasFlags()
-}
-
-// HasPersistentFlags checks if the command contains persistent flags.
-func (c *Command) HasPersistentFlags() bool {
-	return c.PersistentFlags().HasFlags()
-}
-
-// HasLocalFlags checks if the command has flags specifically declared locally.
-func (c *Command) HasLocalFlags() bool {
-	return c.LocalFlags().HasFlags()
-}
-
-// HasInheritedFlags checks if the command has flags inherited from its parent command.
-func (c *Command) HasInheritedFlags() bool {
-	return c.InheritedFlags().HasFlags()
-}
-
-// HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire
-// structure) which are not hidden or deprecated.
-func (c *Command) HasAvailableFlags() bool {
-	return c.Flags().HasAvailableFlags()
-}
-
-// HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated.
-func (c *Command) HasAvailablePersistentFlags() bool {
-	return c.PersistentFlags().HasAvailableFlags()
-}
-
-// HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden
-// or deprecated.
-func (c *Command) HasAvailableLocalFlags() bool {
-	return c.LocalFlags().HasAvailableFlags()
-}
-
-// HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are
-// not hidden or deprecated.
-func (c *Command) HasAvailableInheritedFlags() bool {
-	return c.InheritedFlags().HasAvailableFlags()
-}
-
-// Flag climbs up the command tree looking for matching flag.
-func (c *Command) Flag(name string) (flag *flag.Flag) {
-	flag = c.Flags().Lookup(name)
-
-	if flag == nil {
-		flag = c.persistentFlag(name)
-	}
-
-	return
-}
-
-// Recursively find matching persistent flag.
-func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
-	if c.HasPersistentFlags() {
-		flag = c.PersistentFlags().Lookup(name)
-	}
-
-	if flag == nil {
-		c.updateParentsPflags()
-		flag = c.parentsPflags.Lookup(name)
-	}
-	return
-}
-
-// ParseFlags parses persistent flag tree and local flags.
-func (c *Command) ParseFlags(args []string) error {
-	if c.DisableFlagParsing {
-		return nil
-	}
-
-	if c.flagErrorBuf == nil {
-		c.flagErrorBuf = new(bytes.Buffer)
-	}
-	beforeErrorBufLen := c.flagErrorBuf.Len()
-	c.mergePersistentFlags()
-
-	//do it here after merging all flags and just before parse
-	c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)
-
-	err := c.Flags().Parse(args)
-	// Print warnings if they occurred (e.g. deprecated flag messages).
-	if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {
-		c.Print(c.flagErrorBuf.String())
-	}
-
-	return err
-}
-
-// Parent returns a commands parent command.
-func (c *Command) Parent() *Command {
-	return c.parent
-}
-
-// mergePersistentFlags merges c.PersistentFlags() to c.Flags()
-// and adds missing persistent flags of all parents.
-func (c *Command) mergePersistentFlags() {
-	c.updateParentsPflags()
-	c.Flags().AddFlagSet(c.PersistentFlags())
-	c.Flags().AddFlagSet(c.parentsPflags)
-}
-
-// updateParentsPflags updates c.parentsPflags by adding
-// new persistent flags of all parents.
-// If c.parentsPflags == nil, it makes new.
-func (c *Command) updateParentsPflags() {
-	if c.parentsPflags == nil {
-		c.parentsPflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
-		c.parentsPflags.SetOutput(c.flagErrorBuf)
-		c.parentsPflags.SortFlags = false
-	}
-
-	if c.globNormFunc != nil {
-		c.parentsPflags.SetNormalizeFunc(c.globNormFunc)
-	}
-
-	c.Root().PersistentFlags().AddFlagSet(flag.CommandLine)
-
-	c.VisitParents(func(parent *Command) {
-		c.parentsPflags.AddFlagSet(parent.PersistentFlags())
-	})
-}
diff --git a/vendor/github.com/spf13/cobra/command_notwin.go b/vendor/github.com/spf13/cobra/command_notwin.go
deleted file mode 100644
index 6159c1c..0000000
--- a/vendor/github.com/spf13/cobra/command_notwin.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// +build !windows
-
-package cobra
-
-var preExecHookFn func(*Command)
diff --git a/vendor/github.com/spf13/cobra/command_win.go b/vendor/github.com/spf13/cobra/command_win.go
deleted file mode 100644
index edec728..0000000
--- a/vendor/github.com/spf13/cobra/command_win.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// +build windows
-
-package cobra
-
-import (
-	"os"
-	"time"
-
-	"github.com/inconshreveable/mousetrap"
-)
-
-var preExecHookFn = preExecHook
-
-func preExecHook(c *Command) {
-	if MousetrapHelpText != "" && mousetrap.StartedByExplorer() {
-		c.Print(MousetrapHelpText)
-		time.Sleep(5 * time.Second)
-		os.Exit(1)
-	}
-}
diff --git a/vendor/github.com/spf13/cobra/zsh_completions.go b/vendor/github.com/spf13/cobra/zsh_completions.go
deleted file mode 100644
index 889c22e..0000000
--- a/vendor/github.com/spf13/cobra/zsh_completions.go
+++ /dev/null
@@ -1,126 +0,0 @@
-package cobra
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"os"
-	"strings"
-)
-
-// GenZshCompletionFile generates zsh completion file.
-func (c *Command) GenZshCompletionFile(filename string) error {
-	outFile, err := os.Create(filename)
-	if err != nil {
-		return err
-	}
-	defer outFile.Close()
-
-	return c.GenZshCompletion(outFile)
-}
-
-// GenZshCompletion generates a zsh completion file and writes to the passed writer.
-func (c *Command) GenZshCompletion(w io.Writer) error {
-	buf := new(bytes.Buffer)
-
-	writeHeader(buf, c)
-	maxDepth := maxDepth(c)
-	writeLevelMapping(buf, maxDepth)
-	writeLevelCases(buf, maxDepth, c)
-
-	_, err := buf.WriteTo(w)
-	return err
-}
-
-func writeHeader(w io.Writer, cmd *Command) {
-	fmt.Fprintf(w, "#compdef %s\n\n", cmd.Name())
-}
-
-func maxDepth(c *Command) int {
-	if len(c.Commands()) == 0 {
-		return 0
-	}
-	maxDepthSub := 0
-	for _, s := range c.Commands() {
-		subDepth := maxDepth(s)
-		if subDepth > maxDepthSub {
-			maxDepthSub = subDepth
-		}
-	}
-	return 1 + maxDepthSub
-}
-
-func writeLevelMapping(w io.Writer, numLevels int) {
-	fmt.Fprintln(w, `_arguments \`)
-	for i := 1; i <= numLevels; i++ {
-		fmt.Fprintf(w, `  '%d: :->level%d' \`, i, i)
-		fmt.Fprintln(w)
-	}
-	fmt.Fprintf(w, `  '%d: :%s'`, numLevels+1, "_files")
-	fmt.Fprintln(w)
-}
-
-func writeLevelCases(w io.Writer, maxDepth int, root *Command) {
-	fmt.Fprintln(w, "case $state in")
-	defer fmt.Fprintln(w, "esac")
-
-	for i := 1; i <= maxDepth; i++ {
-		fmt.Fprintf(w, "  level%d)\n", i)
-		writeLevel(w, root, i)
-		fmt.Fprintln(w, "  ;;")
-	}
-	fmt.Fprintln(w, "  *)")
-	fmt.Fprintln(w, "    _arguments '*: :_files'")
-	fmt.Fprintln(w, "  ;;")
-}
-
-func writeLevel(w io.Writer, root *Command, i int) {
-	fmt.Fprintf(w, "    case $words[%d] in\n", i)
-	defer fmt.Fprintln(w, "    esac")
-
-	commands := filterByLevel(root, i)
-	byParent := groupByParent(commands)
-
-	for p, c := range byParent {
-		names := names(c)
-		fmt.Fprintf(w, "      %s)\n", p)
-		fmt.Fprintf(w, "        _arguments '%d: :(%s)'\n", i, strings.Join(names, " "))
-		fmt.Fprintln(w, "      ;;")
-	}
-	fmt.Fprintln(w, "      *)")
-	fmt.Fprintln(w, "        _arguments '*: :_files'")
-	fmt.Fprintln(w, "      ;;")
-
-}
-
-func filterByLevel(c *Command, l int) []*Command {
-	cs := make([]*Command, 0)
-	if l == 0 {
-		cs = append(cs, c)
-		return cs
-	}
-	for _, s := range c.Commands() {
-		cs = append(cs, filterByLevel(s, l-1)...)
-	}
-	return cs
-}
-
-func groupByParent(commands []*Command) map[string][]*Command {
-	m := make(map[string][]*Command)
-	for _, c := range commands {
-		parent := c.Parent()
-		if parent == nil {
-			continue
-		}
-		m[parent.Name()] = append(m[parent.Name()], c)
-	}
-	return m
-}
-
-func names(commands []*Command) []string {
-	ns := make([]string, len(commands))
-	for i, c := range commands {
-		ns[i] = c.Name()
-	}
-	return ns
-}
diff --git a/vendor/github.com/spf13/pflag/.gitignore b/vendor/github.com/spf13/pflag/.gitignore
deleted file mode 100644
index c3da290..0000000
--- a/vendor/github.com/spf13/pflag/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.idea/*
-
diff --git a/vendor/github.com/spf13/pflag/.travis.yml b/vendor/github.com/spf13/pflag/.travis.yml
deleted file mode 100644
index f8a63b3..0000000
--- a/vendor/github.com/spf13/pflag/.travis.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-sudo: false
-
-language: go
-
-go:
-  - 1.7.3
-  - 1.8.1
-  - tip
-
-matrix:
-  allow_failures:
-    - go: tip
-
-install:
-  - go get github.com/golang/lint/golint
-  - export PATH=$GOPATH/bin:$PATH
-  - go install ./...
-
-script:
-  - verify/all.sh -v
-  - go test ./...
diff --git a/vendor/github.com/spf13/pflag/LICENSE b/vendor/github.com/spf13/pflag/LICENSE
deleted file mode 100644
index 63ed1cf..0000000
--- a/vendor/github.com/spf13/pflag/LICENSE
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (c) 2012 Alex Ogier. All rights reserved.
-Copyright (c) 2012 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/spf13/pflag/README.md b/vendor/github.com/spf13/pflag/README.md
deleted file mode 100644
index b052414..0000000
--- a/vendor/github.com/spf13/pflag/README.md
+++ /dev/null
@@ -1,296 +0,0 @@
-[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/spf13/pflag)
-[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/pflag)](https://goreportcard.com/report/github.com/spf13/pflag)
-[![GoDoc](https://godoc.org/github.com/spf13/pflag?status.svg)](https://godoc.org/github.com/spf13/pflag)
-
-## Description
-
-pflag is a drop-in replacement for Go's flag package, implementing
-POSIX/GNU-style --flags.
-
-pflag is compatible with the [GNU extensions to the POSIX recommendations
-for command-line options][1]. For a more precise description, see the
-"Command-line flag syntax" section below.
-
-[1]: http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
-
-pflag is available under the same style of BSD license as the Go language,
-which can be found in the LICENSE file.
-
-## Installation
-
-pflag is available using the standard `go get` command.
-
-Install by running:
-
-    go get github.com/spf13/pflag
-
-Run tests by running:
-
-    go test github.com/spf13/pflag
-
-## Usage
-
-pflag is a drop-in replacement of Go's native flag package. If you import
-pflag under the name "flag" then all code should continue to function
-with no changes.
-
-``` go
-import flag "github.com/spf13/pflag"
-```
-
-There is one exception to this: if you directly instantiate the Flag struct
-there is one more field "Shorthand" that you will need to set.
-Most code never instantiates this struct directly, and instead uses
-functions such as String(), BoolVar(), and Var(), and is therefore
-unaffected.
-
-Define flags using flag.String(), Bool(), Int(), etc.
-
-This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
-
-``` go
-var ip *int = flag.Int("flagname", 1234, "help message for flagname")
-```
-
-If you like, you can bind the flag to a variable using the Var() functions.
-
-``` go
-var flagvar int
-func init() {
-    flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
-}
-```
-
-Or you can create custom flags that satisfy the Value interface (with
-pointer receivers) and couple them to flag parsing by
-
-``` go
-flag.Var(&flagVal, "name", "help message for flagname")
-```
-
-For such flags, the default value is just the initial value of the variable.
-
-After all flags are defined, call
-
-``` go
-flag.Parse()
-```
-
-to parse the command line into the defined flags.
-
-Flags may then be used directly. If you're using the flags themselves,
-they are all pointers; if you bind to variables, they're values.
-
-``` go
-fmt.Println("ip has value ", *ip)
-fmt.Println("flagvar has value ", flagvar)
-```
-
-There are helpers function to get values later if you have the FlagSet but
-it was difficult to keep up with all of the flag pointers in your code.
-If you have a pflag.FlagSet with a flag called 'flagname' of type int you
-can use GetInt() to get the int value. But notice that 'flagname' must exist
-and it must be an int. GetString("flagname") will fail.
-
-``` go
-i, err := flagset.GetInt("flagname")
-```
-
-After parsing, the arguments after the flag are available as the
-slice flag.Args() or individually as flag.Arg(i).
-The arguments are indexed from 0 through flag.NArg()-1.
-
-The pflag package also defines some new functions that are not in flag,
-that give one-letter shorthands for flags. You can use these by appending
-'P' to the name of any function that defines a flag.
-
-``` go
-var ip = flag.IntP("flagname", "f", 1234, "help message")
-var flagvar bool
-func init() {
-	flag.BoolVarP(&flagvar, "boolname", "b", true, "help message")
-}
-flag.VarP(&flagVal, "varname", "v", "help message")
-```
-
-Shorthand letters can be used with single dashes on the command line.
-Boolean shorthand flags can be combined with other shorthand flags.
-
-The default set of command-line flags is controlled by
-top-level functions.  The FlagSet type allows one to define
-independent sets of flags, such as to implement subcommands
-in a command-line interface. The methods of FlagSet are
-analogous to the top-level functions for the command-line
-flag set.
-
-## Setting no option default values for flags
-
-After you create a flag it is possible to set the pflag.NoOptDefVal for
-the given flag. Doing this changes the meaning of the flag slightly. If
-a flag has a NoOptDefVal and the flag is set on the command line without
-an option the flag will be set to the NoOptDefVal. For example given:
-
-``` go
-var ip = flag.IntP("flagname", "f", 1234, "help message")
-flag.Lookup("flagname").NoOptDefVal = "4321"
-```
-
-Would result in something like
-
-| Parsed Arguments | Resulting Value |
-| -------------    | -------------   |
-| --flagname=1357  | ip=1357         |
-| --flagname       | ip=4321         |
-| [nothing]        | ip=1234         |
-
-## Command line flag syntax
-
-```
---flag    // boolean flags, or flags with no option default values
---flag x  // only on flags without a default value
---flag=x
-```
-
-Unlike the flag package, a single dash before an option means something
-different than a double dash. Single dashes signify a series of shorthand
-letters for flags. All but the last shorthand letter must be boolean flags
-or a flag with a default value
-
-```
-// boolean or flags where the 'no option default value' is set
--f
--f=true
--abc
-but
--b true is INVALID
-
-// non-boolean and flags without a 'no option default value'
--n 1234
--n=1234
--n1234
-
-// mixed
--abcs "hello"
--absd="hello"
--abcs1234
-```
-
-Flag parsing stops after the terminator "--". Unlike the flag package,
-flags can be interspersed with arguments anywhere on the command line
-before this terminator.
-
-Integer flags accept 1234, 0664, 0x1234 and may be negative.
-Boolean flags (in their long form) accept 1, 0, t, f, true, false,
-TRUE, FALSE, True, False.
-Duration flags accept any input valid for time.ParseDuration.
-
-## Mutating or "Normalizing" Flag names
-
-It is possible to set a custom flag name 'normalization function.' It allows flag names to be mutated both when created in the code and when used on the command line to some 'normalized' form. The 'normalized' form is used for comparison. Two examples of using the custom normalization func follow.
-
-**Example #1**: You want -, _, and . in flags to compare the same. aka --my-flag == --my_flag == --my.flag
-
-``` go
-func wordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
-	from := []string{"-", "_"}
-	to := "."
-	for _, sep := range from {
-		name = strings.Replace(name, sep, to, -1)
-	}
-	return pflag.NormalizedName(name)
-}
-
-myFlagSet.SetNormalizeFunc(wordSepNormalizeFunc)
-```
-
-**Example #2**: You want to alias two flags. aka --old-flag-name == --new-flag-name
-
-``` go
-func aliasNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
-	switch name {
-	case "old-flag-name":
-		name = "new-flag-name"
-		break
-	}
-	return pflag.NormalizedName(name)
-}
-
-myFlagSet.SetNormalizeFunc(aliasNormalizeFunc)
-```
-
-## Deprecating a flag or its shorthand
-It is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used.
-
-**Example #1**: You want to deprecate a flag named "badflag" as well as inform the users what flag they should use instead.
-```go
-// deprecate a flag by specifying its name and a usage message
-flags.MarkDeprecated("badflag", "please use --good-flag instead")
-```
-This hides "badflag" from help text, and prints `Flag --badflag has been deprecated, please use --good-flag instead` when "badflag" is used.
-
-**Example #2**: You want to keep a flag name "noshorthandflag" but deprecate its shortname "n".
-```go
-// deprecate a flag shorthand by specifying its flag name and a usage message
-flags.MarkShorthandDeprecated("noshorthandflag", "please use --noshorthandflag only")
-```
-This hides the shortname "n" from help text, and prints `Flag shorthand -n has been deprecated, please use --noshorthandflag only` when the shorthand "n" is used.
-
-Note that usage message is essential here, and it should not be empty.
-
-## Hidden flags
-It is possible to mark a flag as hidden, meaning it will still function as normal, however will not show up in usage/help text.
-
-**Example**: You have a flag named "secretFlag" that you need for internal use only and don't want it showing up in help text, or for its usage text to be available.
-```go
-// hide a flag by specifying its name
-flags.MarkHidden("secretFlag")
-```
-
-## Disable sorting of flags
-`pflag` allows you to disable sorting of flags for help and usage message.
-
-**Example**:
-```go
-flags.BoolP("verbose", "v", false, "verbose output")
-flags.String("coolflag", "yeaah", "it's really cool flag")
-flags.Int("usefulflag", 777, "sometimes it's very useful")
-flags.SortFlags = false
-flags.PrintDefaults()
-```
-**Output**:
-```
-  -v, --verbose           verbose output
-      --coolflag string   it's really cool flag (default "yeaah")
-      --usefulflag int    sometimes it's very useful (default 777)
-```
-
-
-## Supporting Go flags when using pflag
-In order to support flags defined using Go's `flag` package, they must be added to the `pflag` flagset. This is usually necessary
-to support flags defined by third-party dependencies (e.g. `golang/glog`).
-
-**Example**: You want to add the Go flags to the `CommandLine` flagset
-```go
-import (
-	goflag "flag"
-	flag "github.com/spf13/pflag"
-)
-
-var ip *int = flag.Int("flagname", 1234, "help message for flagname")
-
-func main() {
-	flag.CommandLine.AddGoFlagSet(goflag.CommandLine)
-	flag.Parse()
-}
-```
-
-## More info
-
-You can see the full reference documentation of the pflag package
-[at godoc.org][3], or through go's standard documentation system by
-running `godoc -http=:6060` and browsing to
-[http://localhost:6060/pkg/github.com/spf13/pflag][2] after
-installation.
-
-[2]: http://localhost:6060/pkg/github.com/spf13/pflag
-[3]: http://godoc.org/github.com/spf13/pflag
diff --git a/vendor/github.com/spf13/pflag/bool.go b/vendor/github.com/spf13/pflag/bool.go
deleted file mode 100644
index c4c5c0b..0000000
--- a/vendor/github.com/spf13/pflag/bool.go
+++ /dev/null
@@ -1,94 +0,0 @@
-package pflag
-
-import "strconv"
-
-// optional interface to indicate boolean flags that can be
-// supplied without "=value" text
-type boolFlag interface {
-	Value
-	IsBoolFlag() bool
-}
-
-// -- bool Value
-type boolValue bool
-
-func newBoolValue(val bool, p *bool) *boolValue {
-	*p = val
-	return (*boolValue)(p)
-}
-
-func (b *boolValue) Set(s string) error {
-	v, err := strconv.ParseBool(s)
-	*b = boolValue(v)
-	return err
-}
-
-func (b *boolValue) Type() string {
-	return "bool"
-}
-
-func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
-
-func (b *boolValue) IsBoolFlag() bool { return true }
-
-func boolConv(sval string) (interface{}, error) {
-	return strconv.ParseBool(sval)
-}
-
-// GetBool return the bool value of a flag with the given name
-func (f *FlagSet) GetBool(name string) (bool, error) {
-	val, err := f.getFlagType(name, "bool", boolConv)
-	if err != nil {
-		return false, err
-	}
-	return val.(bool), nil
-}
-
-// BoolVar defines a bool flag with specified name, default value, and usage string.
-// The argument p points to a bool variable in which to store the value of the flag.
-func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
-	f.BoolVarP(p, name, "", value, usage)
-}
-
-// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
-	flag := f.VarPF(newBoolValue(value, p), name, shorthand, usage)
-	flag.NoOptDefVal = "true"
-}
-
-// BoolVar defines a bool flag with specified name, default value, and usage string.
-// The argument p points to a bool variable in which to store the value of the flag.
-func BoolVar(p *bool, name string, value bool, usage string) {
-	BoolVarP(p, name, "", value, usage)
-}
-
-// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
-func BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
-	flag := CommandLine.VarPF(newBoolValue(value, p), name, shorthand, usage)
-	flag.NoOptDefVal = "true"
-}
-
-// Bool defines a bool flag with specified name, default value, and usage string.
-// The return value is the address of a bool variable that stores the value of the flag.
-func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
-	return f.BoolP(name, "", value, usage)
-}
-
-// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool {
-	p := new(bool)
-	f.BoolVarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Bool defines a bool flag with specified name, default value, and usage string.
-// The return value is the address of a bool variable that stores the value of the flag.
-func Bool(name string, value bool, usage string) *bool {
-	return BoolP(name, "", value, usage)
-}
-
-// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.
-func BoolP(name, shorthand string, value bool, usage string) *bool {
-	b := CommandLine.BoolP(name, shorthand, value, usage)
-	return b
-}
diff --git a/vendor/github.com/spf13/pflag/bool_slice.go b/vendor/github.com/spf13/pflag/bool_slice.go
deleted file mode 100644
index 5af02f1..0000000
--- a/vendor/github.com/spf13/pflag/bool_slice.go
+++ /dev/null
@@ -1,147 +0,0 @@
-package pflag
-
-import (
-	"io"
-	"strconv"
-	"strings"
-)
-
-// -- boolSlice Value
-type boolSliceValue struct {
-	value   *[]bool
-	changed bool
-}
-
-func newBoolSliceValue(val []bool, p *[]bool) *boolSliceValue {
-	bsv := new(boolSliceValue)
-	bsv.value = p
-	*bsv.value = val
-	return bsv
-}
-
-// Set converts, and assigns, the comma-separated boolean argument string representation as the []bool value of this flag.
-// If Set is called on a flag that already has a []bool assigned, the newly converted values will be appended.
-func (s *boolSliceValue) Set(val string) error {
-
-	// remove all quote characters
-	rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
-
-	// read flag arguments with CSV parser
-	boolStrSlice, err := readAsCSV(rmQuote.Replace(val))
-	if err != nil && err != io.EOF {
-		return err
-	}
-
-	// parse boolean values into slice
-	out := make([]bool, 0, len(boolStrSlice))
-	for _, boolStr := range boolStrSlice {
-		b, err := strconv.ParseBool(strings.TrimSpace(boolStr))
-		if err != nil {
-			return err
-		}
-		out = append(out, b)
-	}
-
-	if !s.changed {
-		*s.value = out
-	} else {
-		*s.value = append(*s.value, out...)
-	}
-
-	s.changed = true
-
-	return nil
-}
-
-// Type returns a string that uniquely represents this flag's type.
-func (s *boolSliceValue) Type() string {
-	return "boolSlice"
-}
-
-// String defines a "native" format for this boolean slice flag value.
-func (s *boolSliceValue) String() string {
-
-	boolStrSlice := make([]string, len(*s.value))
-	for i, b := range *s.value {
-		boolStrSlice[i] = strconv.FormatBool(b)
-	}
-
-	out, _ := writeAsCSV(boolStrSlice)
-
-	return "[" + out + "]"
-}
-
-func boolSliceConv(val string) (interface{}, error) {
-	val = strings.Trim(val, "[]")
-	// Empty string would cause a slice with one (empty) entry
-	if len(val) == 0 {
-		return []bool{}, nil
-	}
-	ss := strings.Split(val, ",")
-	out := make([]bool, len(ss))
-	for i, t := range ss {
-		var err error
-		out[i], err = strconv.ParseBool(t)
-		if err != nil {
-			return nil, err
-		}
-	}
-	return out, nil
-}
-
-// GetBoolSlice returns the []bool value of a flag with the given name.
-func (f *FlagSet) GetBoolSlice(name string) ([]bool, error) {
-	val, err := f.getFlagType(name, "boolSlice", boolSliceConv)
-	if err != nil {
-		return []bool{}, err
-	}
-	return val.([]bool), nil
-}
-
-// BoolSliceVar defines a boolSlice flag with specified name, default value, and usage string.
-// The argument p points to a []bool variable in which to store the value of the flag.
-func (f *FlagSet) BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
-	f.VarP(newBoolSliceValue(value, p), name, "", usage)
-}
-
-// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
-	f.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
-}
-
-// BoolSliceVar defines a []bool flag with specified name, default value, and usage string.
-// The argument p points to a []bool variable in which to store the value of the flag.
-func BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
-	CommandLine.VarP(newBoolSliceValue(value, p), name, "", usage)
-}
-
-// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
-	CommandLine.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
-}
-
-// BoolSlice defines a []bool flag with specified name, default value, and usage string.
-// The return value is the address of a []bool variable that stores the value of the flag.
-func (f *FlagSet) BoolSlice(name string, value []bool, usage string) *[]bool {
-	p := []bool{}
-	f.BoolSliceVarP(&p, name, "", value, usage)
-	return &p
-}
-
-// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
-	p := []bool{}
-	f.BoolSliceVarP(&p, name, shorthand, value, usage)
-	return &p
-}
-
-// BoolSlice defines a []bool flag with specified name, default value, and usage string.
-// The return value is the address of a []bool variable that stores the value of the flag.
-func BoolSlice(name string, value []bool, usage string) *[]bool {
-	return CommandLine.BoolSliceP(name, "", value, usage)
-}
-
-// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
-func BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
-	return CommandLine.BoolSliceP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/bytes.go b/vendor/github.com/spf13/pflag/bytes.go
deleted file mode 100644
index 67d5304..0000000
--- a/vendor/github.com/spf13/pflag/bytes.go
+++ /dev/null
@@ -1,209 +0,0 @@
-package pflag
-
-import (
-	"encoding/base64"
-	"encoding/hex"
-	"fmt"
-	"strings"
-)
-
-// BytesHex adapts []byte for use as a flag. Value of flag is HEX encoded
-type bytesHexValue []byte
-
-// String implements pflag.Value.String.
-func (bytesHex bytesHexValue) String() string {
-	return fmt.Sprintf("%X", []byte(bytesHex))
-}
-
-// Set implements pflag.Value.Set.
-func (bytesHex *bytesHexValue) Set(value string) error {
-	bin, err := hex.DecodeString(strings.TrimSpace(value))
-
-	if err != nil {
-		return err
-	}
-
-	*bytesHex = bin
-
-	return nil
-}
-
-// Type implements pflag.Value.Type.
-func (*bytesHexValue) Type() string {
-	return "bytesHex"
-}
-
-func newBytesHexValue(val []byte, p *[]byte) *bytesHexValue {
-	*p = val
-	return (*bytesHexValue)(p)
-}
-
-func bytesHexConv(sval string) (interface{}, error) {
-
-	bin, err := hex.DecodeString(sval)
-
-	if err == nil {
-		return bin, nil
-	}
-
-	return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err)
-}
-
-// GetBytesHex return the []byte value of a flag with the given name
-func (f *FlagSet) GetBytesHex(name string) ([]byte, error) {
-	val, err := f.getFlagType(name, "bytesHex", bytesHexConv)
-
-	if err != nil {
-		return []byte{}, err
-	}
-
-	return val.([]byte), nil
-}
-
-// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
-// The argument p points to an []byte variable in which to store the value of the flag.
-func (f *FlagSet) BytesHexVar(p *[]byte, name string, value []byte, usage string) {
-	f.VarP(newBytesHexValue(value, p), name, "", usage)
-}
-
-// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
-	f.VarP(newBytesHexValue(value, p), name, shorthand, usage)
-}
-
-// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
-// The argument p points to an []byte variable in which to store the value of the flag.
-func BytesHexVar(p *[]byte, name string, value []byte, usage string) {
-	CommandLine.VarP(newBytesHexValue(value, p), name, "", usage)
-}
-
-// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
-func BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
-	CommandLine.VarP(newBytesHexValue(value, p), name, shorthand, usage)
-}
-
-// BytesHex defines an []byte flag with specified name, default value, and usage string.
-// The return value is the address of an []byte variable that stores the value of the flag.
-func (f *FlagSet) BytesHex(name string, value []byte, usage string) *[]byte {
-	p := new([]byte)
-	f.BytesHexVarP(p, name, "", value, usage)
-	return p
-}
-
-// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
-	p := new([]byte)
-	f.BytesHexVarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// BytesHex defines an []byte flag with specified name, default value, and usage string.
-// The return value is the address of an []byte variable that stores the value of the flag.
-func BytesHex(name string, value []byte, usage string) *[]byte {
-	return CommandLine.BytesHexP(name, "", value, usage)
-}
-
-// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
-func BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
-	return CommandLine.BytesHexP(name, shorthand, value, usage)
-}
-
-// BytesBase64 adapts []byte for use as a flag. Value of flag is Base64 encoded
-type bytesBase64Value []byte
-
-// String implements pflag.Value.String.
-func (bytesBase64 bytesBase64Value) String() string {
-	return base64.StdEncoding.EncodeToString([]byte(bytesBase64))
-}
-
-// Set implements pflag.Value.Set.
-func (bytesBase64 *bytesBase64Value) Set(value string) error {
-	bin, err := base64.StdEncoding.DecodeString(strings.TrimSpace(value))
-
-	if err != nil {
-		return err
-	}
-
-	*bytesBase64 = bin
-
-	return nil
-}
-
-// Type implements pflag.Value.Type.
-func (*bytesBase64Value) Type() string {
-	return "bytesBase64"
-}
-
-func newBytesBase64Value(val []byte, p *[]byte) *bytesBase64Value {
-	*p = val
-	return (*bytesBase64Value)(p)
-}
-
-func bytesBase64ValueConv(sval string) (interface{}, error) {
-
-	bin, err := base64.StdEncoding.DecodeString(sval)
-	if err == nil {
-		return bin, nil
-	}
-
-	return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err)
-}
-
-// GetBytesBase64 return the []byte value of a flag with the given name
-func (f *FlagSet) GetBytesBase64(name string) ([]byte, error) {
-	val, err := f.getFlagType(name, "bytesBase64", bytesBase64ValueConv)
-
-	if err != nil {
-		return []byte{}, err
-	}
-
-	return val.([]byte), nil
-}
-
-// BytesBase64Var defines an []byte flag with specified name, default value, and usage string.
-// The argument p points to an []byte variable in which to store the value of the flag.
-func (f *FlagSet) BytesBase64Var(p *[]byte, name string, value []byte, usage string) {
-	f.VarP(newBytesBase64Value(value, p), name, "", usage)
-}
-
-// BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) {
-	f.VarP(newBytesBase64Value(value, p), name, shorthand, usage)
-}
-
-// BytesBase64Var defines an []byte flag with specified name, default value, and usage string.
-// The argument p points to an []byte variable in which to store the value of the flag.
-func BytesBase64Var(p *[]byte, name string, value []byte, usage string) {
-	CommandLine.VarP(newBytesBase64Value(value, p), name, "", usage)
-}
-
-// BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash.
-func BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) {
-	CommandLine.VarP(newBytesBase64Value(value, p), name, shorthand, usage)
-}
-
-// BytesBase64 defines an []byte flag with specified name, default value, and usage string.
-// The return value is the address of an []byte variable that stores the value of the flag.
-func (f *FlagSet) BytesBase64(name string, value []byte, usage string) *[]byte {
-	p := new([]byte)
-	f.BytesBase64VarP(p, name, "", value, usage)
-	return p
-}
-
-// BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte {
-	p := new([]byte)
-	f.BytesBase64VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// BytesBase64 defines an []byte flag with specified name, default value, and usage string.
-// The return value is the address of an []byte variable that stores the value of the flag.
-func BytesBase64(name string, value []byte, usage string) *[]byte {
-	return CommandLine.BytesBase64P(name, "", value, usage)
-}
-
-// BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash.
-func BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte {
-	return CommandLine.BytesBase64P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/count.go b/vendor/github.com/spf13/pflag/count.go
deleted file mode 100644
index aa126e4..0000000
--- a/vendor/github.com/spf13/pflag/count.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- count Value
-type countValue int
-
-func newCountValue(val int, p *int) *countValue {
-	*p = val
-	return (*countValue)(p)
-}
-
-func (i *countValue) Set(s string) error {
-	// "+1" means that no specific value was passed, so increment
-	if s == "+1" {
-		*i = countValue(*i + 1)
-		return nil
-	}
-	v, err := strconv.ParseInt(s, 0, 0)
-	*i = countValue(v)
-	return err
-}
-
-func (i *countValue) Type() string {
-	return "count"
-}
-
-func (i *countValue) String() string { return strconv.Itoa(int(*i)) }
-
-func countConv(sval string) (interface{}, error) {
-	i, err := strconv.Atoi(sval)
-	if err != nil {
-		return nil, err
-	}
-	return i, nil
-}
-
-// GetCount return the int value of a flag with the given name
-func (f *FlagSet) GetCount(name string) (int, error) {
-	val, err := f.getFlagType(name, "count", countConv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(int), nil
-}
-
-// CountVar defines a count flag with specified name, default value, and usage string.
-// The argument p points to an int variable in which to store the value of the flag.
-// A count flag will add 1 to its value evey time it is found on the command line
-func (f *FlagSet) CountVar(p *int, name string, usage string) {
-	f.CountVarP(p, name, "", usage)
-}
-
-// CountVarP is like CountVar only take a shorthand for the flag name.
-func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {
-	flag := f.VarPF(newCountValue(0, p), name, shorthand, usage)
-	flag.NoOptDefVal = "+1"
-}
-
-// CountVar like CountVar only the flag is placed on the CommandLine instead of a given flag set
-func CountVar(p *int, name string, usage string) {
-	CommandLine.CountVar(p, name, usage)
-}
-
-// CountVarP is like CountVar only take a shorthand for the flag name.
-func CountVarP(p *int, name, shorthand string, usage string) {
-	CommandLine.CountVarP(p, name, shorthand, usage)
-}
-
-// Count defines a count flag with specified name, default value, and usage string.
-// The return value is the address of an int variable that stores the value of the flag.
-// A count flag will add 1 to its value evey time it is found on the command line
-func (f *FlagSet) Count(name string, usage string) *int {
-	p := new(int)
-	f.CountVarP(p, name, "", usage)
-	return p
-}
-
-// CountP is like Count only takes a shorthand for the flag name.
-func (f *FlagSet) CountP(name, shorthand string, usage string) *int {
-	p := new(int)
-	f.CountVarP(p, name, shorthand, usage)
-	return p
-}
-
-// Count defines a count flag with specified name, default value, and usage string.
-// The return value is the address of an int variable that stores the value of the flag.
-// A count flag will add 1 to its value evey time it is found on the command line
-func Count(name string, usage string) *int {
-	return CommandLine.CountP(name, "", usage)
-}
-
-// CountP is like Count only takes a shorthand for the flag name.
-func CountP(name, shorthand string, usage string) *int {
-	return CommandLine.CountP(name, shorthand, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/duration.go b/vendor/github.com/spf13/pflag/duration.go
deleted file mode 100644
index e9debef..0000000
--- a/vendor/github.com/spf13/pflag/duration.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package pflag
-
-import (
-	"time"
-)
-
-// -- time.Duration Value
-type durationValue time.Duration
-
-func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
-	*p = val
-	return (*durationValue)(p)
-}
-
-func (d *durationValue) Set(s string) error {
-	v, err := time.ParseDuration(s)
-	*d = durationValue(v)
-	return err
-}
-
-func (d *durationValue) Type() string {
-	return "duration"
-}
-
-func (d *durationValue) String() string { return (*time.Duration)(d).String() }
-
-func durationConv(sval string) (interface{}, error) {
-	return time.ParseDuration(sval)
-}
-
-// GetDuration return the duration value of a flag with the given name
-func (f *FlagSet) GetDuration(name string) (time.Duration, error) {
-	val, err := f.getFlagType(name, "duration", durationConv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(time.Duration), nil
-}
-
-// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
-// The argument p points to a time.Duration variable in which to store the value of the flag.
-func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
-	f.VarP(newDurationValue(value, p), name, "", usage)
-}
-
-// DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {
-	f.VarP(newDurationValue(value, p), name, shorthand, usage)
-}
-
-// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
-// The argument p points to a time.Duration variable in which to store the value of the flag.
-func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
-	CommandLine.VarP(newDurationValue(value, p), name, "", usage)
-}
-
-// DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash.
-func DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {
-	CommandLine.VarP(newDurationValue(value, p), name, shorthand, usage)
-}
-
-// Duration defines a time.Duration flag with specified name, default value, and usage string.
-// The return value is the address of a time.Duration variable that stores the value of the flag.
-func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
-	p := new(time.Duration)
-	f.DurationVarP(p, name, "", value, usage)
-	return p
-}
-
-// DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {
-	p := new(time.Duration)
-	f.DurationVarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Duration defines a time.Duration flag with specified name, default value, and usage string.
-// The return value is the address of a time.Duration variable that stores the value of the flag.
-func Duration(name string, value time.Duration, usage string) *time.Duration {
-	return CommandLine.DurationP(name, "", value, usage)
-}
-
-// DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash.
-func DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {
-	return CommandLine.DurationP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/duration_slice.go b/vendor/github.com/spf13/pflag/duration_slice.go
deleted file mode 100644
index 52c6b6d..0000000
--- a/vendor/github.com/spf13/pflag/duration_slice.go
+++ /dev/null
@@ -1,128 +0,0 @@
-package pflag
-
-import (
-	"fmt"
-	"strings"
-	"time"
-)
-
-// -- durationSlice Value
-type durationSliceValue struct {
-	value   *[]time.Duration
-	changed bool
-}
-
-func newDurationSliceValue(val []time.Duration, p *[]time.Duration) *durationSliceValue {
-	dsv := new(durationSliceValue)
-	dsv.value = p
-	*dsv.value = val
-	return dsv
-}
-
-func (s *durationSliceValue) Set(val string) error {
-	ss := strings.Split(val, ",")
-	out := make([]time.Duration, len(ss))
-	for i, d := range ss {
-		var err error
-		out[i], err = time.ParseDuration(d)
-		if err != nil {
-			return err
-		}
-
-	}
-	if !s.changed {
-		*s.value = out
-	} else {
-		*s.value = append(*s.value, out...)
-	}
-	s.changed = true
-	return nil
-}
-
-func (s *durationSliceValue) Type() string {
-	return "durationSlice"
-}
-
-func (s *durationSliceValue) String() string {
-	out := make([]string, len(*s.value))
-	for i, d := range *s.value {
-		out[i] = fmt.Sprintf("%s", d)
-	}
-	return "[" + strings.Join(out, ",") + "]"
-}
-
-func durationSliceConv(val string) (interface{}, error) {
-	val = strings.Trim(val, "[]")
-	// Empty string would cause a slice with one (empty) entry
-	if len(val) == 0 {
-		return []time.Duration{}, nil
-	}
-	ss := strings.Split(val, ",")
-	out := make([]time.Duration, len(ss))
-	for i, d := range ss {
-		var err error
-		out[i], err = time.ParseDuration(d)
-		if err != nil {
-			return nil, err
-		}
-
-	}
-	return out, nil
-}
-
-// GetDurationSlice returns the []time.Duration value of a flag with the given name
-func (f *FlagSet) GetDurationSlice(name string) ([]time.Duration, error) {
-	val, err := f.getFlagType(name, "durationSlice", durationSliceConv)
-	if err != nil {
-		return []time.Duration{}, err
-	}
-	return val.([]time.Duration), nil
-}
-
-// DurationSliceVar defines a durationSlice flag with specified name, default value, and usage string.
-// The argument p points to a []time.Duration variable in which to store the value of the flag.
-func (f *FlagSet) DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
-	f.VarP(newDurationSliceValue(value, p), name, "", usage)
-}
-
-// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
-	f.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
-}
-
-// DurationSliceVar defines a duration[] flag with specified name, default value, and usage string.
-// The argument p points to a duration[] variable in which to store the value of the flag.
-func DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
-	CommandLine.VarP(newDurationSliceValue(value, p), name, "", usage)
-}
-
-// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
-	CommandLine.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
-}
-
-// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
-// The return value is the address of a []time.Duration variable that stores the value of the flag.
-func (f *FlagSet) DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
-	p := []time.Duration{}
-	f.DurationSliceVarP(&p, name, "", value, usage)
-	return &p
-}
-
-// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
-	p := []time.Duration{}
-	f.DurationSliceVarP(&p, name, shorthand, value, usage)
-	return &p
-}
-
-// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
-// The return value is the address of a []time.Duration variable that stores the value of the flag.
-func DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
-	return CommandLine.DurationSliceP(name, "", value, usage)
-}
-
-// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
-func DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
-	return CommandLine.DurationSliceP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go
deleted file mode 100644
index 9beeda8..0000000
--- a/vendor/github.com/spf13/pflag/flag.go
+++ /dev/null
@@ -1,1227 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package pflag is a drop-in replacement for Go's flag package, implementing
-POSIX/GNU-style --flags.
-
-pflag is compatible with the GNU extensions to the POSIX recommendations
-for command-line options. See
-http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
-
-Usage:
-
-pflag is a drop-in replacement of Go's native flag package. If you import
-pflag under the name "flag" then all code should continue to function
-with no changes.
-
-	import flag "github.com/spf13/pflag"
-
-There is one exception to this: if you directly instantiate the Flag struct
-there is one more field "Shorthand" that you will need to set.
-Most code never instantiates this struct directly, and instead uses
-functions such as String(), BoolVar(), and Var(), and is therefore
-unaffected.
-
-Define flags using flag.String(), Bool(), Int(), etc.
-
-This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
-	var ip = flag.Int("flagname", 1234, "help message for flagname")
-If you like, you can bind the flag to a variable using the Var() functions.
-	var flagvar int
-	func init() {
-		flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
-	}
-Or you can create custom flags that satisfy the Value interface (with
-pointer receivers) and couple them to flag parsing by
-	flag.Var(&flagVal, "name", "help message for flagname")
-For such flags, the default value is just the initial value of the variable.
-
-After all flags are defined, call
-	flag.Parse()
-to parse the command line into the defined flags.
-
-Flags may then be used directly. If you're using the flags themselves,
-they are all pointers; if you bind to variables, they're values.
-	fmt.Println("ip has value ", *ip)
-	fmt.Println("flagvar has value ", flagvar)
-
-After parsing, the arguments after the flag are available as the
-slice flag.Args() or individually as flag.Arg(i).
-The arguments are indexed from 0 through flag.NArg()-1.
-
-The pflag package also defines some new functions that are not in flag,
-that give one-letter shorthands for flags. You can use these by appending
-'P' to the name of any function that defines a flag.
-	var ip = flag.IntP("flagname", "f", 1234, "help message")
-	var flagvar bool
-	func init() {
-		flag.BoolVarP("boolname", "b", true, "help message")
-	}
-	flag.VarP(&flagVar, "varname", "v", 1234, "help message")
-Shorthand letters can be used with single dashes on the command line.
-Boolean shorthand flags can be combined with other shorthand flags.
-
-Command line flag syntax:
-	--flag    // boolean flags only
-	--flag=x
-
-Unlike the flag package, a single dash before an option means something
-different than a double dash. Single dashes signify a series of shorthand
-letters for flags. All but the last shorthand letter must be boolean flags.
-	// boolean flags
-	-f
-	-abc
-	// non-boolean flags
-	-n 1234
-	-Ifile
-	// mixed
-	-abcs "hello"
-	-abcn1234
-
-Flag parsing stops after the terminator "--". Unlike the flag package,
-flags can be interspersed with arguments anywhere on the command line
-before this terminator.
-
-Integer flags accept 1234, 0664, 0x1234 and may be negative.
-Boolean flags (in their long form) accept 1, 0, t, f, true, false,
-TRUE, FALSE, True, False.
-Duration flags accept any input valid for time.ParseDuration.
-
-The default set of command-line flags is controlled by
-top-level functions.  The FlagSet type allows one to define
-independent sets of flags, such as to implement subcommands
-in a command-line interface. The methods of FlagSet are
-analogous to the top-level functions for the command-line
-flag set.
-*/
-package pflag
-
-import (
-	"bytes"
-	"errors"
-	goflag "flag"
-	"fmt"
-	"io"
-	"os"
-	"sort"
-	"strings"
-)
-
-// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
-var ErrHelp = errors.New("pflag: help requested")
-
-// ErrorHandling defines how to handle flag parsing errors.
-type ErrorHandling int
-
-const (
-	// ContinueOnError will return an err from Parse() if an error is found
-	ContinueOnError ErrorHandling = iota
-	// ExitOnError will call os.Exit(2) if an error is found when parsing
-	ExitOnError
-	// PanicOnError will panic() if an error is found when parsing flags
-	PanicOnError
-)
-
-// ParseErrorsWhitelist defines the parsing errors that can be ignored
-type ParseErrorsWhitelist struct {
-	// UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags
-	UnknownFlags bool
-}
-
-// NormalizedName is a flag name that has been normalized according to rules
-// for the FlagSet (e.g. making '-' and '_' equivalent).
-type NormalizedName string
-
-// A FlagSet represents a set of defined flags.
-type FlagSet struct {
-	// Usage is the function called when an error occurs while parsing flags.
-	// The field is a function (not a method) that may be changed to point to
-	// a custom error handler.
-	Usage func()
-
-	// SortFlags is used to indicate, if user wants to have sorted flags in
-	// help/usage messages.
-	SortFlags bool
-
-	// ParseErrorsWhitelist is used to configure a whitelist of errors
-	ParseErrorsWhitelist ParseErrorsWhitelist
-
-	name              string
-	parsed            bool
-	actual            map[NormalizedName]*Flag
-	orderedActual     []*Flag
-	sortedActual      []*Flag
-	formal            map[NormalizedName]*Flag
-	orderedFormal     []*Flag
-	sortedFormal      []*Flag
-	shorthands        map[byte]*Flag
-	args              []string // arguments after flags
-	argsLenAtDash     int      // len(args) when a '--' was located when parsing, or -1 if no --
-	errorHandling     ErrorHandling
-	output            io.Writer // nil means stderr; use out() accessor
-	interspersed      bool      // allow interspersed option/non-option args
-	normalizeNameFunc func(f *FlagSet, name string) NormalizedName
-
-	addedGoFlagSets []*goflag.FlagSet
-}
-
-// A Flag represents the state of a flag.
-type Flag struct {
-	Name                string              // name as it appears on command line
-	Shorthand           string              // one-letter abbreviated flag
-	Usage               string              // help message
-	Value               Value               // value as set
-	DefValue            string              // default value (as text); for usage message
-	Changed             bool                // If the user set the value (or if left to default)
-	NoOptDefVal         string              // default value (as text); if the flag is on the command line without any options
-	Deprecated          string              // If this flag is deprecated, this string is the new or now thing to use
-	Hidden              bool                // used by cobra.Command to allow flags to be hidden from help/usage text
-	ShorthandDeprecated string              // If the shorthand of this flag is deprecated, this string is the new or now thing to use
-	Annotations         map[string][]string // used by cobra.Command bash autocomple code
-}
-
-// Value is the interface to the dynamic value stored in a flag.
-// (The default value is represented as a string.)
-type Value interface {
-	String() string
-	Set(string) error
-	Type() string
-}
-
-// sortFlags returns the flags as a slice in lexicographical sorted order.
-func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
-	list := make(sort.StringSlice, len(flags))
-	i := 0
-	for k := range flags {
-		list[i] = string(k)
-		i++
-	}
-	list.Sort()
-	result := make([]*Flag, len(list))
-	for i, name := range list {
-		result[i] = flags[NormalizedName(name)]
-	}
-	return result
-}
-
-// SetNormalizeFunc allows you to add a function which can translate flag names.
-// Flags added to the FlagSet will be translated and then when anything tries to
-// look up the flag that will also be translated. So it would be possible to create
-// a flag named "getURL" and have it translated to "geturl".  A user could then pass
-// "--getUrl" which may also be translated to "geturl" and everything will work.
-func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
-	f.normalizeNameFunc = n
-	f.sortedFormal = f.sortedFormal[:0]
-	for fname, flag := range f.formal {
-		nname := f.normalizeFlagName(flag.Name)
-		if fname == nname {
-			continue
-		}
-		flag.Name = string(nname)
-		delete(f.formal, fname)
-		f.formal[nname] = flag
-		if _, set := f.actual[fname]; set {
-			delete(f.actual, fname)
-			f.actual[nname] = flag
-		}
-	}
-}
-
-// GetNormalizeFunc returns the previously set NormalizeFunc of a function which
-// does no translation, if not set previously.
-func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
-	if f.normalizeNameFunc != nil {
-		return f.normalizeNameFunc
-	}
-	return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
-}
-
-func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
-	n := f.GetNormalizeFunc()
-	return n(f, name)
-}
-
-func (f *FlagSet) out() io.Writer {
-	if f.output == nil {
-		return os.Stderr
-	}
-	return f.output
-}
-
-// SetOutput sets the destination for usage and error messages.
-// If output is nil, os.Stderr is used.
-func (f *FlagSet) SetOutput(output io.Writer) {
-	f.output = output
-}
-
-// VisitAll visits the flags in lexicographical order or
-// in primordial order if f.SortFlags is false, calling fn for each.
-// It visits all flags, even those not set.
-func (f *FlagSet) VisitAll(fn func(*Flag)) {
-	if len(f.formal) == 0 {
-		return
-	}
-
-	var flags []*Flag
-	if f.SortFlags {
-		if len(f.formal) != len(f.sortedFormal) {
-			f.sortedFormal = sortFlags(f.formal)
-		}
-		flags = f.sortedFormal
-	} else {
-		flags = f.orderedFormal
-	}
-
-	for _, flag := range flags {
-		fn(flag)
-	}
-}
-
-// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
-func (f *FlagSet) HasFlags() bool {
-	return len(f.formal) > 0
-}
-
-// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
-// that are not hidden.
-func (f *FlagSet) HasAvailableFlags() bool {
-	for _, flag := range f.formal {
-		if !flag.Hidden {
-			return true
-		}
-	}
-	return false
-}
-
-// VisitAll visits the command-line flags in lexicographical order or
-// in primordial order if f.SortFlags is false, calling fn for each.
-// It visits all flags, even those not set.
-func VisitAll(fn func(*Flag)) {
-	CommandLine.VisitAll(fn)
-}
-
-// Visit visits the flags in lexicographical order or
-// in primordial order if f.SortFlags is false, calling fn for each.
-// It visits only those flags that have been set.
-func (f *FlagSet) Visit(fn func(*Flag)) {
-	if len(f.actual) == 0 {
-		return
-	}
-
-	var flags []*Flag
-	if f.SortFlags {
-		if len(f.actual) != len(f.sortedActual) {
-			f.sortedActual = sortFlags(f.actual)
-		}
-		flags = f.sortedActual
-	} else {
-		flags = f.orderedActual
-	}
-
-	for _, flag := range flags {
-		fn(flag)
-	}
-}
-
-// Visit visits the command-line flags in lexicographical order or
-// in primordial order if f.SortFlags is false, calling fn for each.
-// It visits only those flags that have been set.
-func Visit(fn func(*Flag)) {
-	CommandLine.Visit(fn)
-}
-
-// Lookup returns the Flag structure of the named flag, returning nil if none exists.
-func (f *FlagSet) Lookup(name string) *Flag {
-	return f.lookup(f.normalizeFlagName(name))
-}
-
-// ShorthandLookup returns the Flag structure of the short handed flag,
-// returning nil if none exists.
-// It panics, if len(name) > 1.
-func (f *FlagSet) ShorthandLookup(name string) *Flag {
-	if name == "" {
-		return nil
-	}
-	if len(name) > 1 {
-		msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
-		fmt.Fprintf(f.out(), msg)
-		panic(msg)
-	}
-	c := name[0]
-	return f.shorthands[c]
-}
-
-// lookup returns the Flag structure of the named flag, returning nil if none exists.
-func (f *FlagSet) lookup(name NormalizedName) *Flag {
-	return f.formal[name]
-}
-
-// func to return a given type for a given flag name
-func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
-	flag := f.Lookup(name)
-	if flag == nil {
-		err := fmt.Errorf("flag accessed but not defined: %s", name)
-		return nil, err
-	}
-
-	if flag.Value.Type() != ftype {
-		err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
-		return nil, err
-	}
-
-	sval := flag.Value.String()
-	result, err := convFunc(sval)
-	if err != nil {
-		return nil, err
-	}
-	return result, nil
-}
-
-// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
-// found during arg parsing. This allows your program to know which args were
-// before the -- and which came after.
-func (f *FlagSet) ArgsLenAtDash() int {
-	return f.argsLenAtDash
-}
-
-// MarkDeprecated indicated that a flag is deprecated in your program. It will
-// continue to function but will not show up in help or usage messages. Using
-// this flag will also print the given usageMessage.
-func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
-	flag := f.Lookup(name)
-	if flag == nil {
-		return fmt.Errorf("flag %q does not exist", name)
-	}
-	if usageMessage == "" {
-		return fmt.Errorf("deprecated message for flag %q must be set", name)
-	}
-	flag.Deprecated = usageMessage
-	flag.Hidden = true
-	return nil
-}
-
-// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
-// program. It will continue to function but will not show up in help or usage
-// messages. Using this flag will also print the given usageMessage.
-func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
-	flag := f.Lookup(name)
-	if flag == nil {
-		return fmt.Errorf("flag %q does not exist", name)
-	}
-	if usageMessage == "" {
-		return fmt.Errorf("deprecated message for flag %q must be set", name)
-	}
-	flag.ShorthandDeprecated = usageMessage
-	return nil
-}
-
-// MarkHidden sets a flag to 'hidden' in your program. It will continue to
-// function but will not show up in help or usage messages.
-func (f *FlagSet) MarkHidden(name string) error {
-	flag := f.Lookup(name)
-	if flag == nil {
-		return fmt.Errorf("flag %q does not exist", name)
-	}
-	flag.Hidden = true
-	return nil
-}
-
-// Lookup returns the Flag structure of the named command-line flag,
-// returning nil if none exists.
-func Lookup(name string) *Flag {
-	return CommandLine.Lookup(name)
-}
-
-// ShorthandLookup returns the Flag structure of the short handed flag,
-// returning nil if none exists.
-func ShorthandLookup(name string) *Flag {
-	return CommandLine.ShorthandLookup(name)
-}
-
-// Set sets the value of the named flag.
-func (f *FlagSet) Set(name, value string) error {
-	normalName := f.normalizeFlagName(name)
-	flag, ok := f.formal[normalName]
-	if !ok {
-		return fmt.Errorf("no such flag -%v", name)
-	}
-
-	err := flag.Value.Set(value)
-	if err != nil {
-		var flagName string
-		if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
-			flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
-		} else {
-			flagName = fmt.Sprintf("--%s", flag.Name)
-		}
-		return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
-	}
-
-	if !flag.Changed {
-		if f.actual == nil {
-			f.actual = make(map[NormalizedName]*Flag)
-		}
-		f.actual[normalName] = flag
-		f.orderedActual = append(f.orderedActual, flag)
-
-		flag.Changed = true
-	}
-
-	if flag.Deprecated != "" {
-		fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
-	}
-	return nil
-}
-
-// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
-// This is sometimes used by spf13/cobra programs which want to generate additional
-// bash completion information.
-func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
-	normalName := f.normalizeFlagName(name)
-	flag, ok := f.formal[normalName]
-	if !ok {
-		return fmt.Errorf("no such flag -%v", name)
-	}
-	if flag.Annotations == nil {
-		flag.Annotations = map[string][]string{}
-	}
-	flag.Annotations[key] = values
-	return nil
-}
-
-// Changed returns true if the flag was explicitly set during Parse() and false
-// otherwise
-func (f *FlagSet) Changed(name string) bool {
-	flag := f.Lookup(name)
-	// If a flag doesn't exist, it wasn't changed....
-	if flag == nil {
-		return false
-	}
-	return flag.Changed
-}
-
-// Set sets the value of the named command-line flag.
-func Set(name, value string) error {
-	return CommandLine.Set(name, value)
-}
-
-// PrintDefaults prints, to standard error unless configured
-// otherwise, the default values of all defined flags in the set.
-func (f *FlagSet) PrintDefaults() {
-	usages := f.FlagUsages()
-	fmt.Fprint(f.out(), usages)
-}
-
-// defaultIsZeroValue returns true if the default value for this flag represents
-// a zero value.
-func (f *Flag) defaultIsZeroValue() bool {
-	switch f.Value.(type) {
-	case boolFlag:
-		return f.DefValue == "false"
-	case *durationValue:
-		// Beginning in Go 1.7, duration zero values are "0s"
-		return f.DefValue == "0" || f.DefValue == "0s"
-	case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
-		return f.DefValue == "0"
-	case *stringValue:
-		return f.DefValue == ""
-	case *ipValue, *ipMaskValue, *ipNetValue:
-		return f.DefValue == "<nil>"
-	case *intSliceValue, *stringSliceValue, *stringArrayValue:
-		return f.DefValue == "[]"
-	default:
-		switch f.Value.String() {
-		case "false":
-			return true
-		case "<nil>":
-			return true
-		case "":
-			return true
-		case "0":
-			return true
-		}
-		return false
-	}
-}
-
-// UnquoteUsage extracts a back-quoted name from the usage
-// string for a flag and returns it and the un-quoted usage.
-// Given "a `name` to show" it returns ("name", "a name to show").
-// If there are no back quotes, the name is an educated guess of the
-// type of the flag's value, or the empty string if the flag is boolean.
-func UnquoteUsage(flag *Flag) (name string, usage string) {
-	// Look for a back-quoted name, but avoid the strings package.
-	usage = flag.Usage
-	for i := 0; i < len(usage); i++ {
-		if usage[i] == '`' {
-			for j := i + 1; j < len(usage); j++ {
-				if usage[j] == '`' {
-					name = usage[i+1 : j]
-					usage = usage[:i] + name + usage[j+1:]
-					return name, usage
-				}
-			}
-			break // Only one back quote; use type name.
-		}
-	}
-
-	name = flag.Value.Type()
-	switch name {
-	case "bool":
-		name = ""
-	case "float64":
-		name = "float"
-	case "int64":
-		name = "int"
-	case "uint64":
-		name = "uint"
-	case "stringSlice":
-		name = "strings"
-	case "intSlice":
-		name = "ints"
-	case "uintSlice":
-		name = "uints"
-	case "boolSlice":
-		name = "bools"
-	}
-
-	return
-}
-
-// Splits the string `s` on whitespace into an initial substring up to
-// `i` runes in length and the remainder. Will go `slop` over `i` if
-// that encompasses the entire string (which allows the caller to
-// avoid short orphan words on the final line).
-func wrapN(i, slop int, s string) (string, string) {
-	if i+slop > len(s) {
-		return s, ""
-	}
-
-	w := strings.LastIndexAny(s[:i], " \t\n")
-	if w <= 0 {
-		return s, ""
-	}
-	nlPos := strings.LastIndex(s[:i], "\n")
-	if nlPos > 0 && nlPos < w {
-		return s[:nlPos], s[nlPos+1:]
-	}
-	return s[:w], s[w+1:]
-}
-
-// Wraps the string `s` to a maximum width `w` with leading indent
-// `i`. The first line is not indented (this is assumed to be done by
-// caller). Pass `w` == 0 to do no wrapping
-func wrap(i, w int, s string) string {
-	if w == 0 {
-		return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
-	}
-
-	// space between indent i and end of line width w into which
-	// we should wrap the text.
-	wrap := w - i
-
-	var r, l string
-
-	// Not enough space for sensible wrapping. Wrap as a block on
-	// the next line instead.
-	if wrap < 24 {
-		i = 16
-		wrap = w - i
-		r += "\n" + strings.Repeat(" ", i)
-	}
-	// If still not enough space then don't even try to wrap.
-	if wrap < 24 {
-		return strings.Replace(s, "\n", r, -1)
-	}
-
-	// Try to avoid short orphan words on the final line, by
-	// allowing wrapN to go a bit over if that would fit in the
-	// remainder of the line.
-	slop := 5
-	wrap = wrap - slop
-
-	// Handle first line, which is indented by the caller (or the
-	// special case above)
-	l, s = wrapN(wrap, slop, s)
-	r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
-
-	// Now wrap the rest
-	for s != "" {
-		var t string
-
-		t, s = wrapN(wrap, slop, s)
-		r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
-	}
-
-	return r
-
-}
-
-// FlagUsagesWrapped returns a string containing the usage information
-// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
-// wrapping)
-func (f *FlagSet) FlagUsagesWrapped(cols int) string {
-	buf := new(bytes.Buffer)
-
-	lines := make([]string, 0, len(f.formal))
-
-	maxlen := 0
-	f.VisitAll(func(flag *Flag) {
-		if flag.Hidden {
-			return
-		}
-
-		line := ""
-		if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
-			line = fmt.Sprintf("  -%s, --%s", flag.Shorthand, flag.Name)
-		} else {
-			line = fmt.Sprintf("      --%s", flag.Name)
-		}
-
-		varname, usage := UnquoteUsage(flag)
-		if varname != "" {
-			line += " " + varname
-		}
-		if flag.NoOptDefVal != "" {
-			switch flag.Value.Type() {
-			case "string":
-				line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
-			case "bool":
-				if flag.NoOptDefVal != "true" {
-					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
-				}
-			case "count":
-				if flag.NoOptDefVal != "+1" {
-					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
-				}
-			default:
-				line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
-			}
-		}
-
-		// This special character will be replaced with spacing once the
-		// correct alignment is calculated
-		line += "\x00"
-		if len(line) > maxlen {
-			maxlen = len(line)
-		}
-
-		line += usage
-		if !flag.defaultIsZeroValue() {
-			if flag.Value.Type() == "string" {
-				line += fmt.Sprintf(" (default %q)", flag.DefValue)
-			} else {
-				line += fmt.Sprintf(" (default %s)", flag.DefValue)
-			}
-		}
-		if len(flag.Deprecated) != 0 {
-			line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
-		}
-
-		lines = append(lines, line)
-	})
-
-	for _, line := range lines {
-		sidx := strings.Index(line, "\x00")
-		spacing := strings.Repeat(" ", maxlen-sidx)
-		// maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
-		fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
-	}
-
-	return buf.String()
-}
-
-// FlagUsages returns a string containing the usage information for all flags in
-// the FlagSet
-func (f *FlagSet) FlagUsages() string {
-	return f.FlagUsagesWrapped(0)
-}
-
-// PrintDefaults prints to standard error the default values of all defined command-line flags.
-func PrintDefaults() {
-	CommandLine.PrintDefaults()
-}
-
-// defaultUsage is the default function to print a usage message.
-func defaultUsage(f *FlagSet) {
-	fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
-	f.PrintDefaults()
-}
-
-// NOTE: Usage is not just defaultUsage(CommandLine)
-// because it serves (via godoc flag Usage) as the example
-// for how to write your own usage function.
-
-// Usage prints to standard error a usage message documenting all defined command-line flags.
-// The function is a variable that may be changed to point to a custom function.
-// By default it prints a simple header and calls PrintDefaults; for details about the
-// format of the output and how to control it, see the documentation for PrintDefaults.
-var Usage = func() {
-	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
-	PrintDefaults()
-}
-
-// NFlag returns the number of flags that have been set.
-func (f *FlagSet) NFlag() int { return len(f.actual) }
-
-// NFlag returns the number of command-line flags that have been set.
-func NFlag() int { return len(CommandLine.actual) }
-
-// Arg returns the i'th argument.  Arg(0) is the first remaining argument
-// after flags have been processed.
-func (f *FlagSet) Arg(i int) string {
-	if i < 0 || i >= len(f.args) {
-		return ""
-	}
-	return f.args[i]
-}
-
-// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
-// after flags have been processed.
-func Arg(i int) string {
-	return CommandLine.Arg(i)
-}
-
-// NArg is the number of arguments remaining after flags have been processed.
-func (f *FlagSet) NArg() int { return len(f.args) }
-
-// NArg is the number of arguments remaining after flags have been processed.
-func NArg() int { return len(CommandLine.args) }
-
-// Args returns the non-flag arguments.
-func (f *FlagSet) Args() []string { return f.args }
-
-// Args returns the non-flag command-line arguments.
-func Args() []string { return CommandLine.args }
-
-// Var defines a flag with the specified name and usage string. The type and
-// value of the flag are represented by the first argument, of type Value, which
-// typically holds a user-defined implementation of Value. For instance, the
-// caller could create a flag that turns a comma-separated string into a slice
-// of strings by giving the slice the methods of Value; in particular, Set would
-// decompose the comma-separated string into the slice.
-func (f *FlagSet) Var(value Value, name string, usage string) {
-	f.VarP(value, name, "", usage)
-}
-
-// VarPF is like VarP, but returns the flag created
-func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
-	// Remember the default value as a string; it won't change.
-	flag := &Flag{
-		Name:      name,
-		Shorthand: shorthand,
-		Usage:     usage,
-		Value:     value,
-		DefValue:  value.String(),
-	}
-	f.AddFlag(flag)
-	return flag
-}
-
-// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
-	f.VarPF(value, name, shorthand, usage)
-}
-
-// AddFlag will add the flag to the FlagSet
-func (f *FlagSet) AddFlag(flag *Flag) {
-	normalizedFlagName := f.normalizeFlagName(flag.Name)
-
-	_, alreadyThere := f.formal[normalizedFlagName]
-	if alreadyThere {
-		msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
-		fmt.Fprintln(f.out(), msg)
-		panic(msg) // Happens only if flags are declared with identical names
-	}
-	if f.formal == nil {
-		f.formal = make(map[NormalizedName]*Flag)
-	}
-
-	flag.Name = string(normalizedFlagName)
-	f.formal[normalizedFlagName] = flag
-	f.orderedFormal = append(f.orderedFormal, flag)
-
-	if flag.Shorthand == "" {
-		return
-	}
-	if len(flag.Shorthand) > 1 {
-		msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
-		fmt.Fprintf(f.out(), msg)
-		panic(msg)
-	}
-	if f.shorthands == nil {
-		f.shorthands = make(map[byte]*Flag)
-	}
-	c := flag.Shorthand[0]
-	used, alreadyThere := f.shorthands[c]
-	if alreadyThere {
-		msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
-		fmt.Fprintf(f.out(), msg)
-		panic(msg)
-	}
-	f.shorthands[c] = flag
-}
-
-// AddFlagSet adds one FlagSet to another. If a flag is already present in f
-// the flag from newSet will be ignored.
-func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
-	if newSet == nil {
-		return
-	}
-	newSet.VisitAll(func(flag *Flag) {
-		if f.Lookup(flag.Name) == nil {
-			f.AddFlag(flag)
-		}
-	})
-}
-
-// Var defines a flag with the specified name and usage string. The type and
-// value of the flag are represented by the first argument, of type Value, which
-// typically holds a user-defined implementation of Value. For instance, the
-// caller could create a flag that turns a comma-separated string into a slice
-// of strings by giving the slice the methods of Value; in particular, Set would
-// decompose the comma-separated string into the slice.
-func Var(value Value, name string, usage string) {
-	CommandLine.VarP(value, name, "", usage)
-}
-
-// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
-func VarP(value Value, name, shorthand, usage string) {
-	CommandLine.VarP(value, name, shorthand, usage)
-}
-
-// failf prints to standard error a formatted error and usage message and
-// returns the error.
-func (f *FlagSet) failf(format string, a ...interface{}) error {
-	err := fmt.Errorf(format, a...)
-	if f.errorHandling != ContinueOnError {
-		fmt.Fprintln(f.out(), err)
-		f.usage()
-	}
-	return err
-}
-
-// usage calls the Usage method for the flag set, or the usage function if
-// the flag set is CommandLine.
-func (f *FlagSet) usage() {
-	if f == CommandLine {
-		Usage()
-	} else if f.Usage == nil {
-		defaultUsage(f)
-	} else {
-		f.Usage()
-	}
-}
-
-//--unknown (args will be empty)
-//--unknown --next-flag ... (args will be --next-flag ...)
-//--unknown arg ... (args will be arg ...)
-func stripUnknownFlagValue(args []string) []string {
-	if len(args) == 0 {
-		//--unknown
-		return args
-	}
-
-	first := args[0]
-	if len(first) > 0 && first[0] == '-' {
-		//--unknown --next-flag ...
-		return args
-	}
-
-	//--unknown arg ... (args will be arg ...)
-	if len(args) > 1 {
-		return args[1:]
-	}
-	return nil
-}
-
-func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
-	a = args
-	name := s[2:]
-	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
-		err = f.failf("bad flag syntax: %s", s)
-		return
-	}
-
-	split := strings.SplitN(name, "=", 2)
-	name = split[0]
-	flag, exists := f.formal[f.normalizeFlagName(name)]
-
-	if !exists {
-		switch {
-		case name == "help":
-			f.usage()
-			return a, ErrHelp
-		case f.ParseErrorsWhitelist.UnknownFlags:
-			// --unknown=unknownval arg ...
-			// we do not want to lose arg in this case
-			if len(split) >= 2 {
-				return a, nil
-			}
-
-			return stripUnknownFlagValue(a), nil
-		default:
-			err = f.failf("unknown flag: --%s", name)
-			return
-		}
-	}
-
-	var value string
-	if len(split) == 2 {
-		// '--flag=arg'
-		value = split[1]
-	} else if flag.NoOptDefVal != "" {
-		// '--flag' (arg was optional)
-		value = flag.NoOptDefVal
-	} else if len(a) > 0 {
-		// '--flag arg'
-		value = a[0]
-		a = a[1:]
-	} else {
-		// '--flag' (arg was required)
-		err = f.failf("flag needs an argument: %s", s)
-		return
-	}
-
-	err = fn(flag, value)
-	if err != nil {
-		f.failf(err.Error())
-	}
-	return
-}
-
-func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
-	outArgs = args
-
-	if strings.HasPrefix(shorthands, "test.") {
-		return
-	}
-
-	outShorts = shorthands[1:]
-	c := shorthands[0]
-
-	flag, exists := f.shorthands[c]
-	if !exists {
-		switch {
-		case c == 'h':
-			f.usage()
-			err = ErrHelp
-			return
-		case f.ParseErrorsWhitelist.UnknownFlags:
-			// '-f=arg arg ...'
-			// we do not want to lose arg in this case
-			if len(shorthands) > 2 && shorthands[1] == '=' {
-				outShorts = ""
-				return
-			}
-
-			outArgs = stripUnknownFlagValue(outArgs)
-			return
-		default:
-			err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
-			return
-		}
-	}
-
-	var value string
-	if len(shorthands) > 2 && shorthands[1] == '=' {
-		// '-f=arg'
-		value = shorthands[2:]
-		outShorts = ""
-	} else if flag.NoOptDefVal != "" {
-		// '-f' (arg was optional)
-		value = flag.NoOptDefVal
-	} else if len(shorthands) > 1 {
-		// '-farg'
-		value = shorthands[1:]
-		outShorts = ""
-	} else if len(args) > 0 {
-		// '-f arg'
-		value = args[0]
-		outArgs = args[1:]
-	} else {
-		// '-f' (arg was required)
-		err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
-		return
-	}
-
-	if flag.ShorthandDeprecated != "" {
-		fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
-	}
-
-	err = fn(flag, value)
-	if err != nil {
-		f.failf(err.Error())
-	}
-	return
-}
-
-func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
-	a = args
-	shorthands := s[1:]
-
-	// "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
-	for len(shorthands) > 0 {
-		shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
-		if err != nil {
-			return
-		}
-	}
-
-	return
-}
-
-func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
-	for len(args) > 0 {
-		s := args[0]
-		args = args[1:]
-		if len(s) == 0 || s[0] != '-' || len(s) == 1 {
-			if !f.interspersed {
-				f.args = append(f.args, s)
-				f.args = append(f.args, args...)
-				return nil
-			}
-			f.args = append(f.args, s)
-			continue
-		}
-
-		if s[1] == '-' {
-			if len(s) == 2 { // "--" terminates the flags
-				f.argsLenAtDash = len(f.args)
-				f.args = append(f.args, args...)
-				break
-			}
-			args, err = f.parseLongArg(s, args, fn)
-		} else {
-			args, err = f.parseShortArg(s, args, fn)
-		}
-		if err != nil {
-			return
-		}
-	}
-	return
-}
-
-// Parse parses flag definitions from the argument list, which should not
-// include the command name.  Must be called after all flags in the FlagSet
-// are defined and before flags are accessed by the program.
-// The return value will be ErrHelp if -help was set but not defined.
-func (f *FlagSet) Parse(arguments []string) error {
-	if f.addedGoFlagSets != nil {
-		for _, goFlagSet := range f.addedGoFlagSets {
-			goFlagSet.Parse(nil)
-		}
-	}
-	f.parsed = true
-
-	if len(arguments) < 0 {
-		return nil
-	}
-
-	f.args = make([]string, 0, len(arguments))
-
-	set := func(flag *Flag, value string) error {
-		return f.Set(flag.Name, value)
-	}
-
-	err := f.parseArgs(arguments, set)
-	if err != nil {
-		switch f.errorHandling {
-		case ContinueOnError:
-			return err
-		case ExitOnError:
-			fmt.Println(err)
-			os.Exit(2)
-		case PanicOnError:
-			panic(err)
-		}
-	}
-	return nil
-}
-
-type parseFunc func(flag *Flag, value string) error
-
-// ParseAll parses flag definitions from the argument list, which should not
-// include the command name. The arguments for fn are flag and value. Must be
-// called after all flags in the FlagSet are defined and before flags are
-// accessed by the program. The return value will be ErrHelp if -help was set
-// but not defined.
-func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
-	f.parsed = true
-	f.args = make([]string, 0, len(arguments))
-
-	err := f.parseArgs(arguments, fn)
-	if err != nil {
-		switch f.errorHandling {
-		case ContinueOnError:
-			return err
-		case ExitOnError:
-			os.Exit(2)
-		case PanicOnError:
-			panic(err)
-		}
-	}
-	return nil
-}
-
-// Parsed reports whether f.Parse has been called.
-func (f *FlagSet) Parsed() bool {
-	return f.parsed
-}
-
-// Parse parses the command-line flags from os.Args[1:].  Must be called
-// after all flags are defined and before flags are accessed by the program.
-func Parse() {
-	// Ignore errors; CommandLine is set for ExitOnError.
-	CommandLine.Parse(os.Args[1:])
-}
-
-// ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
-// The arguments for fn are flag and value. Must be called after all flags are
-// defined and before flags are accessed by the program.
-func ParseAll(fn func(flag *Flag, value string) error) {
-	// Ignore errors; CommandLine is set for ExitOnError.
-	CommandLine.ParseAll(os.Args[1:], fn)
-}
-
-// SetInterspersed sets whether to support interspersed option/non-option arguments.
-func SetInterspersed(interspersed bool) {
-	CommandLine.SetInterspersed(interspersed)
-}
-
-// Parsed returns true if the command-line flags have been parsed.
-func Parsed() bool {
-	return CommandLine.Parsed()
-}
-
-// CommandLine is the default set of command-line flags, parsed from os.Args.
-var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
-
-// NewFlagSet returns a new, empty flag set with the specified name,
-// error handling property and SortFlags set to true.
-func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
-	f := &FlagSet{
-		name:          name,
-		errorHandling: errorHandling,
-		argsLenAtDash: -1,
-		interspersed:  true,
-		SortFlags:     true,
-	}
-	return f
-}
-
-// SetInterspersed sets whether to support interspersed option/non-option arguments.
-func (f *FlagSet) SetInterspersed(interspersed bool) {
-	f.interspersed = interspersed
-}
-
-// Init sets the name and error handling property for a flag set.
-// By default, the zero FlagSet uses an empty name and the
-// ContinueOnError error handling policy.
-func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
-	f.name = name
-	f.errorHandling = errorHandling
-	f.argsLenAtDash = -1
-}
diff --git a/vendor/github.com/spf13/pflag/float32.go b/vendor/github.com/spf13/pflag/float32.go
deleted file mode 100644
index a243f81..0000000
--- a/vendor/github.com/spf13/pflag/float32.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- float32 Value
-type float32Value float32
-
-func newFloat32Value(val float32, p *float32) *float32Value {
-	*p = val
-	return (*float32Value)(p)
-}
-
-func (f *float32Value) Set(s string) error {
-	v, err := strconv.ParseFloat(s, 32)
-	*f = float32Value(v)
-	return err
-}
-
-func (f *float32Value) Type() string {
-	return "float32"
-}
-
-func (f *float32Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 32) }
-
-func float32Conv(sval string) (interface{}, error) {
-	v, err := strconv.ParseFloat(sval, 32)
-	if err != nil {
-		return 0, err
-	}
-	return float32(v), nil
-}
-
-// GetFloat32 return the float32 value of a flag with the given name
-func (f *FlagSet) GetFloat32(name string) (float32, error) {
-	val, err := f.getFlagType(name, "float32", float32Conv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(float32), nil
-}
-
-// Float32Var defines a float32 flag with specified name, default value, and usage string.
-// The argument p points to a float32 variable in which to store the value of the flag.
-func (f *FlagSet) Float32Var(p *float32, name string, value float32, usage string) {
-	f.VarP(newFloat32Value(value, p), name, "", usage)
-}
-
-// Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Float32VarP(p *float32, name, shorthand string, value float32, usage string) {
-	f.VarP(newFloat32Value(value, p), name, shorthand, usage)
-}
-
-// Float32Var defines a float32 flag with specified name, default value, and usage string.
-// The argument p points to a float32 variable in which to store the value of the flag.
-func Float32Var(p *float32, name string, value float32, usage string) {
-	CommandLine.VarP(newFloat32Value(value, p), name, "", usage)
-}
-
-// Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash.
-func Float32VarP(p *float32, name, shorthand string, value float32, usage string) {
-	CommandLine.VarP(newFloat32Value(value, p), name, shorthand, usage)
-}
-
-// Float32 defines a float32 flag with specified name, default value, and usage string.
-// The return value is the address of a float32 variable that stores the value of the flag.
-func (f *FlagSet) Float32(name string, value float32, usage string) *float32 {
-	p := new(float32)
-	f.Float32VarP(p, name, "", value, usage)
-	return p
-}
-
-// Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Float32P(name, shorthand string, value float32, usage string) *float32 {
-	p := new(float32)
-	f.Float32VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Float32 defines a float32 flag with specified name, default value, and usage string.
-// The return value is the address of a float32 variable that stores the value of the flag.
-func Float32(name string, value float32, usage string) *float32 {
-	return CommandLine.Float32P(name, "", value, usage)
-}
-
-// Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash.
-func Float32P(name, shorthand string, value float32, usage string) *float32 {
-	return CommandLine.Float32P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/float64.go b/vendor/github.com/spf13/pflag/float64.go
deleted file mode 100644
index 04b5492..0000000
--- a/vendor/github.com/spf13/pflag/float64.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- float64 Value
-type float64Value float64
-
-func newFloat64Value(val float64, p *float64) *float64Value {
-	*p = val
-	return (*float64Value)(p)
-}
-
-func (f *float64Value) Set(s string) error {
-	v, err := strconv.ParseFloat(s, 64)
-	*f = float64Value(v)
-	return err
-}
-
-func (f *float64Value) Type() string {
-	return "float64"
-}
-
-func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
-
-func float64Conv(sval string) (interface{}, error) {
-	return strconv.ParseFloat(sval, 64)
-}
-
-// GetFloat64 return the float64 value of a flag with the given name
-func (f *FlagSet) GetFloat64(name string) (float64, error) {
-	val, err := f.getFlagType(name, "float64", float64Conv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(float64), nil
-}
-
-// Float64Var defines a float64 flag with specified name, default value, and usage string.
-// The argument p points to a float64 variable in which to store the value of the flag.
-func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
-	f.VarP(newFloat64Value(value, p), name, "", usage)
-}
-
-// Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value float64, usage string) {
-	f.VarP(newFloat64Value(value, p), name, shorthand, usage)
-}
-
-// Float64Var defines a float64 flag with specified name, default value, and usage string.
-// The argument p points to a float64 variable in which to store the value of the flag.
-func Float64Var(p *float64, name string, value float64, usage string) {
-	CommandLine.VarP(newFloat64Value(value, p), name, "", usage)
-}
-
-// Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash.
-func Float64VarP(p *float64, name, shorthand string, value float64, usage string) {
-	CommandLine.VarP(newFloat64Value(value, p), name, shorthand, usage)
-}
-
-// Float64 defines a float64 flag with specified name, default value, and usage string.
-// The return value is the address of a float64 variable that stores the value of the flag.
-func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
-	p := new(float64)
-	f.Float64VarP(p, name, "", value, usage)
-	return p
-}
-
-// Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Float64P(name, shorthand string, value float64, usage string) *float64 {
-	p := new(float64)
-	f.Float64VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Float64 defines a float64 flag with specified name, default value, and usage string.
-// The return value is the address of a float64 variable that stores the value of the flag.
-func Float64(name string, value float64, usage string) *float64 {
-	return CommandLine.Float64P(name, "", value, usage)
-}
-
-// Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash.
-func Float64P(name, shorthand string, value float64, usage string) *float64 {
-	return CommandLine.Float64P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/golangflag.go b/vendor/github.com/spf13/pflag/golangflag.go
deleted file mode 100644
index d3dd72b..0000000
--- a/vendor/github.com/spf13/pflag/golangflag.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package pflag
-
-import (
-	goflag "flag"
-	"reflect"
-	"strings"
-)
-
-// flagValueWrapper implements pflag.Value around a flag.Value.  The main
-// difference here is the addition of the Type method that returns a string
-// name of the type.  As this is generally unknown, we approximate that with
-// reflection.
-type flagValueWrapper struct {
-	inner    goflag.Value
-	flagType string
-}
-
-// We are just copying the boolFlag interface out of goflag as that is what
-// they use to decide if a flag should get "true" when no arg is given.
-type goBoolFlag interface {
-	goflag.Value
-	IsBoolFlag() bool
-}
-
-func wrapFlagValue(v goflag.Value) Value {
-	// If the flag.Value happens to also be a pflag.Value, just use it directly.
-	if pv, ok := v.(Value); ok {
-		return pv
-	}
-
-	pv := &flagValueWrapper{
-		inner: v,
-	}
-
-	t := reflect.TypeOf(v)
-	if t.Kind() == reflect.Interface || t.Kind() == reflect.Ptr {
-		t = t.Elem()
-	}
-
-	pv.flagType = strings.TrimSuffix(t.Name(), "Value")
-	return pv
-}
-
-func (v *flagValueWrapper) String() string {
-	return v.inner.String()
-}
-
-func (v *flagValueWrapper) Set(s string) error {
-	return v.inner.Set(s)
-}
-
-func (v *flagValueWrapper) Type() string {
-	return v.flagType
-}
-
-// PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag
-// If the *flag.Flag.Name was a single character (ex: `v`) it will be accessiblei
-// with both `-v` and `--v` in flags. If the golang flag was more than a single
-// character (ex: `verbose`) it will only be accessible via `--verbose`
-func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
-	// Remember the default value as a string; it won't change.
-	flag := &Flag{
-		Name:  goflag.Name,
-		Usage: goflag.Usage,
-		Value: wrapFlagValue(goflag.Value),
-		// Looks like golang flags don't set DefValue correctly  :-(
-		//DefValue: goflag.DefValue,
-		DefValue: goflag.Value.String(),
-	}
-	// Ex: if the golang flag was -v, allow both -v and --v to work
-	if len(flag.Name) == 1 {
-		flag.Shorthand = flag.Name
-	}
-	if fv, ok := goflag.Value.(goBoolFlag); ok && fv.IsBoolFlag() {
-		flag.NoOptDefVal = "true"
-	}
-	return flag
-}
-
-// AddGoFlag will add the given *flag.Flag to the pflag.FlagSet
-func (f *FlagSet) AddGoFlag(goflag *goflag.Flag) {
-	if f.Lookup(goflag.Name) != nil {
-		return
-	}
-	newflag := PFlagFromGoFlag(goflag)
-	f.AddFlag(newflag)
-}
-
-// AddGoFlagSet will add the given *flag.FlagSet to the pflag.FlagSet
-func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
-	if newSet == nil {
-		return
-	}
-	newSet.VisitAll(func(goflag *goflag.Flag) {
-		f.AddGoFlag(goflag)
-	})
-	if f.addedGoFlagSets == nil {
-		f.addedGoFlagSets = make([]*goflag.FlagSet, 0)
-	}
-	f.addedGoFlagSets = append(f.addedGoFlagSets, newSet)
-}
diff --git a/vendor/github.com/spf13/pflag/int.go b/vendor/github.com/spf13/pflag/int.go
deleted file mode 100644
index 1474b89..0000000
--- a/vendor/github.com/spf13/pflag/int.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- int Value
-type intValue int
-
-func newIntValue(val int, p *int) *intValue {
-	*p = val
-	return (*intValue)(p)
-}
-
-func (i *intValue) Set(s string) error {
-	v, err := strconv.ParseInt(s, 0, 64)
-	*i = intValue(v)
-	return err
-}
-
-func (i *intValue) Type() string {
-	return "int"
-}
-
-func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
-
-func intConv(sval string) (interface{}, error) {
-	return strconv.Atoi(sval)
-}
-
-// GetInt return the int value of a flag with the given name
-func (f *FlagSet) GetInt(name string) (int, error) {
-	val, err := f.getFlagType(name, "int", intConv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(int), nil
-}
-
-// IntVar defines an int flag with specified name, default value, and usage string.
-// The argument p points to an int variable in which to store the value of the flag.
-func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
-	f.VarP(newIntValue(value, p), name, "", usage)
-}
-
-// IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usage string) {
-	f.VarP(newIntValue(value, p), name, shorthand, usage)
-}
-
-// IntVar defines an int flag with specified name, default value, and usage string.
-// The argument p points to an int variable in which to store the value of the flag.
-func IntVar(p *int, name string, value int, usage string) {
-	CommandLine.VarP(newIntValue(value, p), name, "", usage)
-}
-
-// IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash.
-func IntVarP(p *int, name, shorthand string, value int, usage string) {
-	CommandLine.VarP(newIntValue(value, p), name, shorthand, usage)
-}
-
-// Int defines an int flag with specified name, default value, and usage string.
-// The return value is the address of an int variable that stores the value of the flag.
-func (f *FlagSet) Int(name string, value int, usage string) *int {
-	p := new(int)
-	f.IntVarP(p, name, "", value, usage)
-	return p
-}
-
-// IntP is like Int, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IntP(name, shorthand string, value int, usage string) *int {
-	p := new(int)
-	f.IntVarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Int defines an int flag with specified name, default value, and usage string.
-// The return value is the address of an int variable that stores the value of the flag.
-func Int(name string, value int, usage string) *int {
-	return CommandLine.IntP(name, "", value, usage)
-}
-
-// IntP is like Int, but accepts a shorthand letter that can be used after a single dash.
-func IntP(name, shorthand string, value int, usage string) *int {
-	return CommandLine.IntP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/int16.go b/vendor/github.com/spf13/pflag/int16.go
deleted file mode 100644
index f1a01d0..0000000
--- a/vendor/github.com/spf13/pflag/int16.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- int16 Value
-type int16Value int16
-
-func newInt16Value(val int16, p *int16) *int16Value {
-	*p = val
-	return (*int16Value)(p)
-}
-
-func (i *int16Value) Set(s string) error {
-	v, err := strconv.ParseInt(s, 0, 16)
-	*i = int16Value(v)
-	return err
-}
-
-func (i *int16Value) Type() string {
-	return "int16"
-}
-
-func (i *int16Value) String() string { return strconv.FormatInt(int64(*i), 10) }
-
-func int16Conv(sval string) (interface{}, error) {
-	v, err := strconv.ParseInt(sval, 0, 16)
-	if err != nil {
-		return 0, err
-	}
-	return int16(v), nil
-}
-
-// GetInt16 returns the int16 value of a flag with the given name
-func (f *FlagSet) GetInt16(name string) (int16, error) {
-	val, err := f.getFlagType(name, "int16", int16Conv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(int16), nil
-}
-
-// Int16Var defines an int16 flag with specified name, default value, and usage string.
-// The argument p points to an int16 variable in which to store the value of the flag.
-func (f *FlagSet) Int16Var(p *int16, name string, value int16, usage string) {
-	f.VarP(newInt16Value(value, p), name, "", usage)
-}
-
-// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
-	f.VarP(newInt16Value(value, p), name, shorthand, usage)
-}
-
-// Int16Var defines an int16 flag with specified name, default value, and usage string.
-// The argument p points to an int16 variable in which to store the value of the flag.
-func Int16Var(p *int16, name string, value int16, usage string) {
-	CommandLine.VarP(newInt16Value(value, p), name, "", usage)
-}
-
-// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
-func Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
-	CommandLine.VarP(newInt16Value(value, p), name, shorthand, usage)
-}
-
-// Int16 defines an int16 flag with specified name, default value, and usage string.
-// The return value is the address of an int16 variable that stores the value of the flag.
-func (f *FlagSet) Int16(name string, value int16, usage string) *int16 {
-	p := new(int16)
-	f.Int16VarP(p, name, "", value, usage)
-	return p
-}
-
-// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Int16P(name, shorthand string, value int16, usage string) *int16 {
-	p := new(int16)
-	f.Int16VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Int16 defines an int16 flag with specified name, default value, and usage string.
-// The return value is the address of an int16 variable that stores the value of the flag.
-func Int16(name string, value int16, usage string) *int16 {
-	return CommandLine.Int16P(name, "", value, usage)
-}
-
-// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
-func Int16P(name, shorthand string, value int16, usage string) *int16 {
-	return CommandLine.Int16P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/int32.go b/vendor/github.com/spf13/pflag/int32.go
deleted file mode 100644
index 9b95944..0000000
--- a/vendor/github.com/spf13/pflag/int32.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- int32 Value
-type int32Value int32
-
-func newInt32Value(val int32, p *int32) *int32Value {
-	*p = val
-	return (*int32Value)(p)
-}
-
-func (i *int32Value) Set(s string) error {
-	v, err := strconv.ParseInt(s, 0, 32)
-	*i = int32Value(v)
-	return err
-}
-
-func (i *int32Value) Type() string {
-	return "int32"
-}
-
-func (i *int32Value) String() string { return strconv.FormatInt(int64(*i), 10) }
-
-func int32Conv(sval string) (interface{}, error) {
-	v, err := strconv.ParseInt(sval, 0, 32)
-	if err != nil {
-		return 0, err
-	}
-	return int32(v), nil
-}
-
-// GetInt32 return the int32 value of a flag with the given name
-func (f *FlagSet) GetInt32(name string) (int32, error) {
-	val, err := f.getFlagType(name, "int32", int32Conv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(int32), nil
-}
-
-// Int32Var defines an int32 flag with specified name, default value, and usage string.
-// The argument p points to an int32 variable in which to store the value of the flag.
-func (f *FlagSet) Int32Var(p *int32, name string, value int32, usage string) {
-	f.VarP(newInt32Value(value, p), name, "", usage)
-}
-
-// Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Int32VarP(p *int32, name, shorthand string, value int32, usage string) {
-	f.VarP(newInt32Value(value, p), name, shorthand, usage)
-}
-
-// Int32Var defines an int32 flag with specified name, default value, and usage string.
-// The argument p points to an int32 variable in which to store the value of the flag.
-func Int32Var(p *int32, name string, value int32, usage string) {
-	CommandLine.VarP(newInt32Value(value, p), name, "", usage)
-}
-
-// Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash.
-func Int32VarP(p *int32, name, shorthand string, value int32, usage string) {
-	CommandLine.VarP(newInt32Value(value, p), name, shorthand, usage)
-}
-
-// Int32 defines an int32 flag with specified name, default value, and usage string.
-// The return value is the address of an int32 variable that stores the value of the flag.
-func (f *FlagSet) Int32(name string, value int32, usage string) *int32 {
-	p := new(int32)
-	f.Int32VarP(p, name, "", value, usage)
-	return p
-}
-
-// Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Int32P(name, shorthand string, value int32, usage string) *int32 {
-	p := new(int32)
-	f.Int32VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Int32 defines an int32 flag with specified name, default value, and usage string.
-// The return value is the address of an int32 variable that stores the value of the flag.
-func Int32(name string, value int32, usage string) *int32 {
-	return CommandLine.Int32P(name, "", value, usage)
-}
-
-// Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash.
-func Int32P(name, shorthand string, value int32, usage string) *int32 {
-	return CommandLine.Int32P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/int64.go b/vendor/github.com/spf13/pflag/int64.go
deleted file mode 100644
index 0026d78..0000000
--- a/vendor/github.com/spf13/pflag/int64.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- int64 Value
-type int64Value int64
-
-func newInt64Value(val int64, p *int64) *int64Value {
-	*p = val
-	return (*int64Value)(p)
-}
-
-func (i *int64Value) Set(s string) error {
-	v, err := strconv.ParseInt(s, 0, 64)
-	*i = int64Value(v)
-	return err
-}
-
-func (i *int64Value) Type() string {
-	return "int64"
-}
-
-func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
-
-func int64Conv(sval string) (interface{}, error) {
-	return strconv.ParseInt(sval, 0, 64)
-}
-
-// GetInt64 return the int64 value of a flag with the given name
-func (f *FlagSet) GetInt64(name string) (int64, error) {
-	val, err := f.getFlagType(name, "int64", int64Conv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(int64), nil
-}
-
-// Int64Var defines an int64 flag with specified name, default value, and usage string.
-// The argument p points to an int64 variable in which to store the value of the flag.
-func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
-	f.VarP(newInt64Value(value, p), name, "", usage)
-}
-
-// Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int64, usage string) {
-	f.VarP(newInt64Value(value, p), name, shorthand, usage)
-}
-
-// Int64Var defines an int64 flag with specified name, default value, and usage string.
-// The argument p points to an int64 variable in which to store the value of the flag.
-func Int64Var(p *int64, name string, value int64, usage string) {
-	CommandLine.VarP(newInt64Value(value, p), name, "", usage)
-}
-
-// Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash.
-func Int64VarP(p *int64, name, shorthand string, value int64, usage string) {
-	CommandLine.VarP(newInt64Value(value, p), name, shorthand, usage)
-}
-
-// Int64 defines an int64 flag with specified name, default value, and usage string.
-// The return value is the address of an int64 variable that stores the value of the flag.
-func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
-	p := new(int64)
-	f.Int64VarP(p, name, "", value, usage)
-	return p
-}
-
-// Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Int64P(name, shorthand string, value int64, usage string) *int64 {
-	p := new(int64)
-	f.Int64VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Int64 defines an int64 flag with specified name, default value, and usage string.
-// The return value is the address of an int64 variable that stores the value of the flag.
-func Int64(name string, value int64, usage string) *int64 {
-	return CommandLine.Int64P(name, "", value, usage)
-}
-
-// Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash.
-func Int64P(name, shorthand string, value int64, usage string) *int64 {
-	return CommandLine.Int64P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/int8.go b/vendor/github.com/spf13/pflag/int8.go
deleted file mode 100644
index 4da9222..0000000
--- a/vendor/github.com/spf13/pflag/int8.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- int8 Value
-type int8Value int8
-
-func newInt8Value(val int8, p *int8) *int8Value {
-	*p = val
-	return (*int8Value)(p)
-}
-
-func (i *int8Value) Set(s string) error {
-	v, err := strconv.ParseInt(s, 0, 8)
-	*i = int8Value(v)
-	return err
-}
-
-func (i *int8Value) Type() string {
-	return "int8"
-}
-
-func (i *int8Value) String() string { return strconv.FormatInt(int64(*i), 10) }
-
-func int8Conv(sval string) (interface{}, error) {
-	v, err := strconv.ParseInt(sval, 0, 8)
-	if err != nil {
-		return 0, err
-	}
-	return int8(v), nil
-}
-
-// GetInt8 return the int8 value of a flag with the given name
-func (f *FlagSet) GetInt8(name string) (int8, error) {
-	val, err := f.getFlagType(name, "int8", int8Conv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(int8), nil
-}
-
-// Int8Var defines an int8 flag with specified name, default value, and usage string.
-// The argument p points to an int8 variable in which to store the value of the flag.
-func (f *FlagSet) Int8Var(p *int8, name string, value int8, usage string) {
-	f.VarP(newInt8Value(value, p), name, "", usage)
-}
-
-// Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
-	f.VarP(newInt8Value(value, p), name, shorthand, usage)
-}
-
-// Int8Var defines an int8 flag with specified name, default value, and usage string.
-// The argument p points to an int8 variable in which to store the value of the flag.
-func Int8Var(p *int8, name string, value int8, usage string) {
-	CommandLine.VarP(newInt8Value(value, p), name, "", usage)
-}
-
-// Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash.
-func Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
-	CommandLine.VarP(newInt8Value(value, p), name, shorthand, usage)
-}
-
-// Int8 defines an int8 flag with specified name, default value, and usage string.
-// The return value is the address of an int8 variable that stores the value of the flag.
-func (f *FlagSet) Int8(name string, value int8, usage string) *int8 {
-	p := new(int8)
-	f.Int8VarP(p, name, "", value, usage)
-	return p
-}
-
-// Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Int8P(name, shorthand string, value int8, usage string) *int8 {
-	p := new(int8)
-	f.Int8VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Int8 defines an int8 flag with specified name, default value, and usage string.
-// The return value is the address of an int8 variable that stores the value of the flag.
-func Int8(name string, value int8, usage string) *int8 {
-	return CommandLine.Int8P(name, "", value, usage)
-}
-
-// Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash.
-func Int8P(name, shorthand string, value int8, usage string) *int8 {
-	return CommandLine.Int8P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/int_slice.go b/vendor/github.com/spf13/pflag/int_slice.go
deleted file mode 100644
index 1e7c9ed..0000000
--- a/vendor/github.com/spf13/pflag/int_slice.go
+++ /dev/null
@@ -1,128 +0,0 @@
-package pflag
-
-import (
-	"fmt"
-	"strconv"
-	"strings"
-)
-
-// -- intSlice Value
-type intSliceValue struct {
-	value   *[]int
-	changed bool
-}
-
-func newIntSliceValue(val []int, p *[]int) *intSliceValue {
-	isv := new(intSliceValue)
-	isv.value = p
-	*isv.value = val
-	return isv
-}
-
-func (s *intSliceValue) Set(val string) error {
-	ss := strings.Split(val, ",")
-	out := make([]int, len(ss))
-	for i, d := range ss {
-		var err error
-		out[i], err = strconv.Atoi(d)
-		if err != nil {
-			return err
-		}
-
-	}
-	if !s.changed {
-		*s.value = out
-	} else {
-		*s.value = append(*s.value, out...)
-	}
-	s.changed = true
-	return nil
-}
-
-func (s *intSliceValue) Type() string {
-	return "intSlice"
-}
-
-func (s *intSliceValue) String() string {
-	out := make([]string, len(*s.value))
-	for i, d := range *s.value {
-		out[i] = fmt.Sprintf("%d", d)
-	}
-	return "[" + strings.Join(out, ",") + "]"
-}
-
-func intSliceConv(val string) (interface{}, error) {
-	val = strings.Trim(val, "[]")
-	// Empty string would cause a slice with one (empty) entry
-	if len(val) == 0 {
-		return []int{}, nil
-	}
-	ss := strings.Split(val, ",")
-	out := make([]int, len(ss))
-	for i, d := range ss {
-		var err error
-		out[i], err = strconv.Atoi(d)
-		if err != nil {
-			return nil, err
-		}
-
-	}
-	return out, nil
-}
-
-// GetIntSlice return the []int value of a flag with the given name
-func (f *FlagSet) GetIntSlice(name string) ([]int, error) {
-	val, err := f.getFlagType(name, "intSlice", intSliceConv)
-	if err != nil {
-		return []int{}, err
-	}
-	return val.([]int), nil
-}
-
-// IntSliceVar defines a intSlice flag with specified name, default value, and usage string.
-// The argument p points to a []int variable in which to store the value of the flag.
-func (f *FlagSet) IntSliceVar(p *[]int, name string, value []int, usage string) {
-	f.VarP(newIntSliceValue(value, p), name, "", usage)
-}
-
-// IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) {
-	f.VarP(newIntSliceValue(value, p), name, shorthand, usage)
-}
-
-// IntSliceVar defines a int[] flag with specified name, default value, and usage string.
-// The argument p points to a int[] variable in which to store the value of the flag.
-func IntSliceVar(p *[]int, name string, value []int, usage string) {
-	CommandLine.VarP(newIntSliceValue(value, p), name, "", usage)
-}
-
-// IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) {
-	CommandLine.VarP(newIntSliceValue(value, p), name, shorthand, usage)
-}
-
-// IntSlice defines a []int flag with specified name, default value, and usage string.
-// The return value is the address of a []int variable that stores the value of the flag.
-func (f *FlagSet) IntSlice(name string, value []int, usage string) *[]int {
-	p := []int{}
-	f.IntSliceVarP(&p, name, "", value, usage)
-	return &p
-}
-
-// IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IntSliceP(name, shorthand string, value []int, usage string) *[]int {
-	p := []int{}
-	f.IntSliceVarP(&p, name, shorthand, value, usage)
-	return &p
-}
-
-// IntSlice defines a []int flag with specified name, default value, and usage string.
-// The return value is the address of a []int variable that stores the value of the flag.
-func IntSlice(name string, value []int, usage string) *[]int {
-	return CommandLine.IntSliceP(name, "", value, usage)
-}
-
-// IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash.
-func IntSliceP(name, shorthand string, value []int, usage string) *[]int {
-	return CommandLine.IntSliceP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/ip.go b/vendor/github.com/spf13/pflag/ip.go
deleted file mode 100644
index 3d414ba..0000000
--- a/vendor/github.com/spf13/pflag/ip.go
+++ /dev/null
@@ -1,94 +0,0 @@
-package pflag
-
-import (
-	"fmt"
-	"net"
-	"strings"
-)
-
-// -- net.IP value
-type ipValue net.IP
-
-func newIPValue(val net.IP, p *net.IP) *ipValue {
-	*p = val
-	return (*ipValue)(p)
-}
-
-func (i *ipValue) String() string { return net.IP(*i).String() }
-func (i *ipValue) Set(s string) error {
-	ip := net.ParseIP(strings.TrimSpace(s))
-	if ip == nil {
-		return fmt.Errorf("failed to parse IP: %q", s)
-	}
-	*i = ipValue(ip)
-	return nil
-}
-
-func (i *ipValue) Type() string {
-	return "ip"
-}
-
-func ipConv(sval string) (interface{}, error) {
-	ip := net.ParseIP(sval)
-	if ip != nil {
-		return ip, nil
-	}
-	return nil, fmt.Errorf("invalid string being converted to IP address: %s", sval)
-}
-
-// GetIP return the net.IP value of a flag with the given name
-func (f *FlagSet) GetIP(name string) (net.IP, error) {
-	val, err := f.getFlagType(name, "ip", ipConv)
-	if err != nil {
-		return nil, err
-	}
-	return val.(net.IP), nil
-}
-
-// IPVar defines an net.IP flag with specified name, default value, and usage string.
-// The argument p points to an net.IP variable in which to store the value of the flag.
-func (f *FlagSet) IPVar(p *net.IP, name string, value net.IP, usage string) {
-	f.VarP(newIPValue(value, p), name, "", usage)
-}
-
-// IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {
-	f.VarP(newIPValue(value, p), name, shorthand, usage)
-}
-
-// IPVar defines an net.IP flag with specified name, default value, and usage string.
-// The argument p points to an net.IP variable in which to store the value of the flag.
-func IPVar(p *net.IP, name string, value net.IP, usage string) {
-	CommandLine.VarP(newIPValue(value, p), name, "", usage)
-}
-
-// IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash.
-func IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {
-	CommandLine.VarP(newIPValue(value, p), name, shorthand, usage)
-}
-
-// IP defines an net.IP flag with specified name, default value, and usage string.
-// The return value is the address of an net.IP variable that stores the value of the flag.
-func (f *FlagSet) IP(name string, value net.IP, usage string) *net.IP {
-	p := new(net.IP)
-	f.IPVarP(p, name, "", value, usage)
-	return p
-}
-
-// IPP is like IP, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IPP(name, shorthand string, value net.IP, usage string) *net.IP {
-	p := new(net.IP)
-	f.IPVarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// IP defines an net.IP flag with specified name, default value, and usage string.
-// The return value is the address of an net.IP variable that stores the value of the flag.
-func IP(name string, value net.IP, usage string) *net.IP {
-	return CommandLine.IPP(name, "", value, usage)
-}
-
-// IPP is like IP, but accepts a shorthand letter that can be used after a single dash.
-func IPP(name, shorthand string, value net.IP, usage string) *net.IP {
-	return CommandLine.IPP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/ip_slice.go b/vendor/github.com/spf13/pflag/ip_slice.go
deleted file mode 100644
index 7dd196f..0000000
--- a/vendor/github.com/spf13/pflag/ip_slice.go
+++ /dev/null
@@ -1,148 +0,0 @@
-package pflag
-
-import (
-	"fmt"
-	"io"
-	"net"
-	"strings"
-)
-
-// -- ipSlice Value
-type ipSliceValue struct {
-	value   *[]net.IP
-	changed bool
-}
-
-func newIPSliceValue(val []net.IP, p *[]net.IP) *ipSliceValue {
-	ipsv := new(ipSliceValue)
-	ipsv.value = p
-	*ipsv.value = val
-	return ipsv
-}
-
-// Set converts, and assigns, the comma-separated IP argument string representation as the []net.IP value of this flag.
-// If Set is called on a flag that already has a []net.IP assigned, the newly converted values will be appended.
-func (s *ipSliceValue) Set(val string) error {
-
-	// remove all quote characters
-	rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
-
-	// read flag arguments with CSV parser
-	ipStrSlice, err := readAsCSV(rmQuote.Replace(val))
-	if err != nil && err != io.EOF {
-		return err
-	}
-
-	// parse ip values into slice
-	out := make([]net.IP, 0, len(ipStrSlice))
-	for _, ipStr := range ipStrSlice {
-		ip := net.ParseIP(strings.TrimSpace(ipStr))
-		if ip == nil {
-			return fmt.Errorf("invalid string being converted to IP address: %s", ipStr)
-		}
-		out = append(out, ip)
-	}
-
-	if !s.changed {
-		*s.value = out
-	} else {
-		*s.value = append(*s.value, out...)
-	}
-
-	s.changed = true
-
-	return nil
-}
-
-// Type returns a string that uniquely represents this flag's type.
-func (s *ipSliceValue) Type() string {
-	return "ipSlice"
-}
-
-// String defines a "native" format for this net.IP slice flag value.
-func (s *ipSliceValue) String() string {
-
-	ipStrSlice := make([]string, len(*s.value))
-	for i, ip := range *s.value {
-		ipStrSlice[i] = ip.String()
-	}
-
-	out, _ := writeAsCSV(ipStrSlice)
-
-	return "[" + out + "]"
-}
-
-func ipSliceConv(val string) (interface{}, error) {
-	val = strings.Trim(val, "[]")
-	// Emtpy string would cause a slice with one (empty) entry
-	if len(val) == 0 {
-		return []net.IP{}, nil
-	}
-	ss := strings.Split(val, ",")
-	out := make([]net.IP, len(ss))
-	for i, sval := range ss {
-		ip := net.ParseIP(strings.TrimSpace(sval))
-		if ip == nil {
-			return nil, fmt.Errorf("invalid string being converted to IP address: %s", sval)
-		}
-		out[i] = ip
-	}
-	return out, nil
-}
-
-// GetIPSlice returns the []net.IP value of a flag with the given name
-func (f *FlagSet) GetIPSlice(name string) ([]net.IP, error) {
-	val, err := f.getFlagType(name, "ipSlice", ipSliceConv)
-	if err != nil {
-		return []net.IP{}, err
-	}
-	return val.([]net.IP), nil
-}
-
-// IPSliceVar defines a ipSlice flag with specified name, default value, and usage string.
-// The argument p points to a []net.IP variable in which to store the value of the flag.
-func (f *FlagSet) IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) {
-	f.VarP(newIPSliceValue(value, p), name, "", usage)
-}
-
-// IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) {
-	f.VarP(newIPSliceValue(value, p), name, shorthand, usage)
-}
-
-// IPSliceVar defines a []net.IP flag with specified name, default value, and usage string.
-// The argument p points to a []net.IP variable in which to store the value of the flag.
-func IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) {
-	CommandLine.VarP(newIPSliceValue(value, p), name, "", usage)
-}
-
-// IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) {
-	CommandLine.VarP(newIPSliceValue(value, p), name, shorthand, usage)
-}
-
-// IPSlice defines a []net.IP flag with specified name, default value, and usage string.
-// The return value is the address of a []net.IP variable that stores the value of that flag.
-func (f *FlagSet) IPSlice(name string, value []net.IP, usage string) *[]net.IP {
-	p := []net.IP{}
-	f.IPSliceVarP(&p, name, "", value, usage)
-	return &p
-}
-
-// IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP {
-	p := []net.IP{}
-	f.IPSliceVarP(&p, name, shorthand, value, usage)
-	return &p
-}
-
-// IPSlice defines a []net.IP flag with specified name, default value, and usage string.
-// The return value is the address of a []net.IP variable that stores the value of the flag.
-func IPSlice(name string, value []net.IP, usage string) *[]net.IP {
-	return CommandLine.IPSliceP(name, "", value, usage)
-}
-
-// IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash.
-func IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP {
-	return CommandLine.IPSliceP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/ipmask.go b/vendor/github.com/spf13/pflag/ipmask.go
deleted file mode 100644
index 5bd44bd..0000000
--- a/vendor/github.com/spf13/pflag/ipmask.go
+++ /dev/null
@@ -1,122 +0,0 @@
-package pflag
-
-import (
-	"fmt"
-	"net"
-	"strconv"
-)
-
-// -- net.IPMask value
-type ipMaskValue net.IPMask
-
-func newIPMaskValue(val net.IPMask, p *net.IPMask) *ipMaskValue {
-	*p = val
-	return (*ipMaskValue)(p)
-}
-
-func (i *ipMaskValue) String() string { return net.IPMask(*i).String() }
-func (i *ipMaskValue) Set(s string) error {
-	ip := ParseIPv4Mask(s)
-	if ip == nil {
-		return fmt.Errorf("failed to parse IP mask: %q", s)
-	}
-	*i = ipMaskValue(ip)
-	return nil
-}
-
-func (i *ipMaskValue) Type() string {
-	return "ipMask"
-}
-
-// ParseIPv4Mask written in IP form (e.g. 255.255.255.0).
-// This function should really belong to the net package.
-func ParseIPv4Mask(s string) net.IPMask {
-	mask := net.ParseIP(s)
-	if mask == nil {
-		if len(s) != 8 {
-			return nil
-		}
-		// net.IPMask.String() actually outputs things like ffffff00
-		// so write a horrible parser for that as well  :-(
-		m := []int{}
-		for i := 0; i < 4; i++ {
-			b := "0x" + s[2*i:2*i+2]
-			d, err := strconv.ParseInt(b, 0, 0)
-			if err != nil {
-				return nil
-			}
-			m = append(m, int(d))
-		}
-		s := fmt.Sprintf("%d.%d.%d.%d", m[0], m[1], m[2], m[3])
-		mask = net.ParseIP(s)
-		if mask == nil {
-			return nil
-		}
-	}
-	return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15])
-}
-
-func parseIPv4Mask(sval string) (interface{}, error) {
-	mask := ParseIPv4Mask(sval)
-	if mask == nil {
-		return nil, fmt.Errorf("unable to parse %s as net.IPMask", sval)
-	}
-	return mask, nil
-}
-
-// GetIPv4Mask return the net.IPv4Mask value of a flag with the given name
-func (f *FlagSet) GetIPv4Mask(name string) (net.IPMask, error) {
-	val, err := f.getFlagType(name, "ipMask", parseIPv4Mask)
-	if err != nil {
-		return nil, err
-	}
-	return val.(net.IPMask), nil
-}
-
-// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string.
-// The argument p points to an net.IPMask variable in which to store the value of the flag.
-func (f *FlagSet) IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {
-	f.VarP(newIPMaskValue(value, p), name, "", usage)
-}
-
-// IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {
-	f.VarP(newIPMaskValue(value, p), name, shorthand, usage)
-}
-
-// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string.
-// The argument p points to an net.IPMask variable in which to store the value of the flag.
-func IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {
-	CommandLine.VarP(newIPMaskValue(value, p), name, "", usage)
-}
-
-// IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.
-func IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {
-	CommandLine.VarP(newIPMaskValue(value, p), name, shorthand, usage)
-}
-
-// IPMask defines an net.IPMask flag with specified name, default value, and usage string.
-// The return value is the address of an net.IPMask variable that stores the value of the flag.
-func (f *FlagSet) IPMask(name string, value net.IPMask, usage string) *net.IPMask {
-	p := new(net.IPMask)
-	f.IPMaskVarP(p, name, "", value, usage)
-	return p
-}
-
-// IPMaskP is like IPMask, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {
-	p := new(net.IPMask)
-	f.IPMaskVarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// IPMask defines an net.IPMask flag with specified name, default value, and usage string.
-// The return value is the address of an net.IPMask variable that stores the value of the flag.
-func IPMask(name string, value net.IPMask, usage string) *net.IPMask {
-	return CommandLine.IPMaskP(name, "", value, usage)
-}
-
-// IPMaskP is like IP, but accepts a shorthand letter that can be used after a single dash.
-func IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {
-	return CommandLine.IPMaskP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/ipnet.go b/vendor/github.com/spf13/pflag/ipnet.go
deleted file mode 100644
index e2c1b8b..0000000
--- a/vendor/github.com/spf13/pflag/ipnet.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package pflag
-
-import (
-	"fmt"
-	"net"
-	"strings"
-)
-
-// IPNet adapts net.IPNet for use as a flag.
-type ipNetValue net.IPNet
-
-func (ipnet ipNetValue) String() string {
-	n := net.IPNet(ipnet)
-	return n.String()
-}
-
-func (ipnet *ipNetValue) Set(value string) error {
-	_, n, err := net.ParseCIDR(strings.TrimSpace(value))
-	if err != nil {
-		return err
-	}
-	*ipnet = ipNetValue(*n)
-	return nil
-}
-
-func (*ipNetValue) Type() string {
-	return "ipNet"
-}
-
-func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {
-	*p = val
-	return (*ipNetValue)(p)
-}
-
-func ipNetConv(sval string) (interface{}, error) {
-	_, n, err := net.ParseCIDR(strings.TrimSpace(sval))
-	if err == nil {
-		return *n, nil
-	}
-	return nil, fmt.Errorf("invalid string being converted to IPNet: %s", sval)
-}
-
-// GetIPNet return the net.IPNet value of a flag with the given name
-func (f *FlagSet) GetIPNet(name string) (net.IPNet, error) {
-	val, err := f.getFlagType(name, "ipNet", ipNetConv)
-	if err != nil {
-		return net.IPNet{}, err
-	}
-	return val.(net.IPNet), nil
-}
-
-// IPNetVar defines an net.IPNet flag with specified name, default value, and usage string.
-// The argument p points to an net.IPNet variable in which to store the value of the flag.
-func (f *FlagSet) IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {
-	f.VarP(newIPNetValue(value, p), name, "", usage)
-}
-
-// IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) {
-	f.VarP(newIPNetValue(value, p), name, shorthand, usage)
-}
-
-// IPNetVar defines an net.IPNet flag with specified name, default value, and usage string.
-// The argument p points to an net.IPNet variable in which to store the value of the flag.
-func IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {
-	CommandLine.VarP(newIPNetValue(value, p), name, "", usage)
-}
-
-// IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash.
-func IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) {
-	CommandLine.VarP(newIPNetValue(value, p), name, shorthand, usage)
-}
-
-// IPNet defines an net.IPNet flag with specified name, default value, and usage string.
-// The return value is the address of an net.IPNet variable that stores the value of the flag.
-func (f *FlagSet) IPNet(name string, value net.IPNet, usage string) *net.IPNet {
-	p := new(net.IPNet)
-	f.IPNetVarP(p, name, "", value, usage)
-	return p
-}
-
-// IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet {
-	p := new(net.IPNet)
-	f.IPNetVarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// IPNet defines an net.IPNet flag with specified name, default value, and usage string.
-// The return value is the address of an net.IPNet variable that stores the value of the flag.
-func IPNet(name string, value net.IPNet, usage string) *net.IPNet {
-	return CommandLine.IPNetP(name, "", value, usage)
-}
-
-// IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash.
-func IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet {
-	return CommandLine.IPNetP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/string.go b/vendor/github.com/spf13/pflag/string.go
deleted file mode 100644
index 04e0a26..0000000
--- a/vendor/github.com/spf13/pflag/string.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package pflag
-
-// -- string Value
-type stringValue string
-
-func newStringValue(val string, p *string) *stringValue {
-	*p = val
-	return (*stringValue)(p)
-}
-
-func (s *stringValue) Set(val string) error {
-	*s = stringValue(val)
-	return nil
-}
-func (s *stringValue) Type() string {
-	return "string"
-}
-
-func (s *stringValue) String() string { return string(*s) }
-
-func stringConv(sval string) (interface{}, error) {
-	return sval, nil
-}
-
-// GetString return the string value of a flag with the given name
-func (f *FlagSet) GetString(name string) (string, error) {
-	val, err := f.getFlagType(name, "string", stringConv)
-	if err != nil {
-		return "", err
-	}
-	return val.(string), nil
-}
-
-// StringVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a string variable in which to store the value of the flag.
-func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
-	f.VarP(newStringValue(value, p), name, "", usage)
-}
-
-// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) StringVarP(p *string, name, shorthand string, value string, usage string) {
-	f.VarP(newStringValue(value, p), name, shorthand, usage)
-}
-
-// StringVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a string variable in which to store the value of the flag.
-func StringVar(p *string, name string, value string, usage string) {
-	CommandLine.VarP(newStringValue(value, p), name, "", usage)
-}
-
-// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.
-func StringVarP(p *string, name, shorthand string, value string, usage string) {
-	CommandLine.VarP(newStringValue(value, p), name, shorthand, usage)
-}
-
-// String defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a string variable that stores the value of the flag.
-func (f *FlagSet) String(name string, value string, usage string) *string {
-	p := new(string)
-	f.StringVarP(p, name, "", value, usage)
-	return p
-}
-
-// StringP is like String, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) StringP(name, shorthand string, value string, usage string) *string {
-	p := new(string)
-	f.StringVarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// String defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a string variable that stores the value of the flag.
-func String(name string, value string, usage string) *string {
-	return CommandLine.StringP(name, "", value, usage)
-}
-
-// StringP is like String, but accepts a shorthand letter that can be used after a single dash.
-func StringP(name, shorthand string, value string, usage string) *string {
-	return CommandLine.StringP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/string_array.go b/vendor/github.com/spf13/pflag/string_array.go
deleted file mode 100644
index fa7bc60..0000000
--- a/vendor/github.com/spf13/pflag/string_array.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package pflag
-
-// -- stringArray Value
-type stringArrayValue struct {
-	value   *[]string
-	changed bool
-}
-
-func newStringArrayValue(val []string, p *[]string) *stringArrayValue {
-	ssv := new(stringArrayValue)
-	ssv.value = p
-	*ssv.value = val
-	return ssv
-}
-
-func (s *stringArrayValue) Set(val string) error {
-	if !s.changed {
-		*s.value = []string{val}
-		s.changed = true
-	} else {
-		*s.value = append(*s.value, val)
-	}
-	return nil
-}
-
-func (s *stringArrayValue) Type() string {
-	return "stringArray"
-}
-
-func (s *stringArrayValue) String() string {
-	str, _ := writeAsCSV(*s.value)
-	return "[" + str + "]"
-}
-
-func stringArrayConv(sval string) (interface{}, error) {
-	sval = sval[1 : len(sval)-1]
-	// An empty string would cause a array with one (empty) string
-	if len(sval) == 0 {
-		return []string{}, nil
-	}
-	return readAsCSV(sval)
-}
-
-// GetStringArray return the []string value of a flag with the given name
-func (f *FlagSet) GetStringArray(name string) ([]string, error) {
-	val, err := f.getFlagType(name, "stringArray", stringArrayConv)
-	if err != nil {
-		return []string{}, err
-	}
-	return val.([]string), nil
-}
-
-// StringArrayVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a []string variable in which to store the values of the multiple flags.
-// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
-func (f *FlagSet) StringArrayVar(p *[]string, name string, value []string, usage string) {
-	f.VarP(newStringArrayValue(value, p), name, "", usage)
-}
-
-// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {
-	f.VarP(newStringArrayValue(value, p), name, shorthand, usage)
-}
-
-// StringArrayVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a []string variable in which to store the value of the flag.
-// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
-func StringArrayVar(p *[]string, name string, value []string, usage string) {
-	CommandLine.VarP(newStringArrayValue(value, p), name, "", usage)
-}
-
-// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.
-func StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {
-	CommandLine.VarP(newStringArrayValue(value, p), name, shorthand, usage)
-}
-
-// StringArray defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a []string variable that stores the value of the flag.
-// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
-func (f *FlagSet) StringArray(name string, value []string, usage string) *[]string {
-	p := []string{}
-	f.StringArrayVarP(&p, name, "", value, usage)
-	return &p
-}
-
-// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) StringArrayP(name, shorthand string, value []string, usage string) *[]string {
-	p := []string{}
-	f.StringArrayVarP(&p, name, shorthand, value, usage)
-	return &p
-}
-
-// StringArray defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a []string variable that stores the value of the flag.
-// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
-func StringArray(name string, value []string, usage string) *[]string {
-	return CommandLine.StringArrayP(name, "", value, usage)
-}
-
-// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.
-func StringArrayP(name, shorthand string, value []string, usage string) *[]string {
-	return CommandLine.StringArrayP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/string_slice.go b/vendor/github.com/spf13/pflag/string_slice.go
deleted file mode 100644
index 0cd3ccc..0000000
--- a/vendor/github.com/spf13/pflag/string_slice.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package pflag
-
-import (
-	"bytes"
-	"encoding/csv"
-	"strings"
-)
-
-// -- stringSlice Value
-type stringSliceValue struct {
-	value   *[]string
-	changed bool
-}
-
-func newStringSliceValue(val []string, p *[]string) *stringSliceValue {
-	ssv := new(stringSliceValue)
-	ssv.value = p
-	*ssv.value = val
-	return ssv
-}
-
-func readAsCSV(val string) ([]string, error) {
-	if val == "" {
-		return []string{}, nil
-	}
-	stringReader := strings.NewReader(val)
-	csvReader := csv.NewReader(stringReader)
-	return csvReader.Read()
-}
-
-func writeAsCSV(vals []string) (string, error) {
-	b := &bytes.Buffer{}
-	w := csv.NewWriter(b)
-	err := w.Write(vals)
-	if err != nil {
-		return "", err
-	}
-	w.Flush()
-	return strings.TrimSuffix(b.String(), "\n"), nil
-}
-
-func (s *stringSliceValue) Set(val string) error {
-	v, err := readAsCSV(val)
-	if err != nil {
-		return err
-	}
-	if !s.changed {
-		*s.value = v
-	} else {
-		*s.value = append(*s.value, v...)
-	}
-	s.changed = true
-	return nil
-}
-
-func (s *stringSliceValue) Type() string {
-	return "stringSlice"
-}
-
-func (s *stringSliceValue) String() string {
-	str, _ := writeAsCSV(*s.value)
-	return "[" + str + "]"
-}
-
-func stringSliceConv(sval string) (interface{}, error) {
-	sval = sval[1 : len(sval)-1]
-	// An empty string would cause a slice with one (empty) string
-	if len(sval) == 0 {
-		return []string{}, nil
-	}
-	return readAsCSV(sval)
-}
-
-// GetStringSlice return the []string value of a flag with the given name
-func (f *FlagSet) GetStringSlice(name string) ([]string, error) {
-	val, err := f.getFlagType(name, "stringSlice", stringSliceConv)
-	if err != nil {
-		return []string{}, err
-	}
-	return val.([]string), nil
-}
-
-// StringSliceVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a []string variable in which to store the value of the flag.
-// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
-// For example:
-//   --ss="v1,v2" -ss="v3"
-// will result in
-//   []string{"v1", "v2", "v3"}
-func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {
-	f.VarP(newStringSliceValue(value, p), name, "", usage)
-}
-
-// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) {
-	f.VarP(newStringSliceValue(value, p), name, shorthand, usage)
-}
-
-// StringSliceVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a []string variable in which to store the value of the flag.
-// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
-// For example:
-//   --ss="v1,v2" -ss="v3"
-// will result in
-//   []string{"v1", "v2", "v3"}
-func StringSliceVar(p *[]string, name string, value []string, usage string) {
-	CommandLine.VarP(newStringSliceValue(value, p), name, "", usage)
-}
-
-// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) {
-	CommandLine.VarP(newStringSliceValue(value, p), name, shorthand, usage)
-}
-
-// StringSlice defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a []string variable that stores the value of the flag.
-// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
-// For example:
-//   --ss="v1,v2" -ss="v3"
-// will result in
-//   []string{"v1", "v2", "v3"}
-func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {
-	p := []string{}
-	f.StringSliceVarP(&p, name, "", value, usage)
-	return &p
-}
-
-// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage string) *[]string {
-	p := []string{}
-	f.StringSliceVarP(&p, name, shorthand, value, usage)
-	return &p
-}
-
-// StringSlice defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a []string variable that stores the value of the flag.
-// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
-// For example:
-//   --ss="v1,v2" -ss="v3"
-// will result in
-//   []string{"v1", "v2", "v3"}
-func StringSlice(name string, value []string, usage string) *[]string {
-	return CommandLine.StringSliceP(name, "", value, usage)
-}
-
-// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash.
-func StringSliceP(name, shorthand string, value []string, usage string) *[]string {
-	return CommandLine.StringSliceP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/string_to_int.go b/vendor/github.com/spf13/pflag/string_to_int.go
deleted file mode 100644
index 5ceda39..0000000
--- a/vendor/github.com/spf13/pflag/string_to_int.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package pflag
-
-import (
-	"bytes"
-	"fmt"
-	"strconv"
-	"strings"
-)
-
-// -- stringToInt Value
-type stringToIntValue struct {
-	value   *map[string]int
-	changed bool
-}
-
-func newStringToIntValue(val map[string]int, p *map[string]int) *stringToIntValue {
-	ssv := new(stringToIntValue)
-	ssv.value = p
-	*ssv.value = val
-	return ssv
-}
-
-// Format: a=1,b=2
-func (s *stringToIntValue) Set(val string) error {
-	ss := strings.Split(val, ",")
-	out := make(map[string]int, len(ss))
-	for _, pair := range ss {
-		kv := strings.SplitN(pair, "=", 2)
-		if len(kv) != 2 {
-			return fmt.Errorf("%s must be formatted as key=value", pair)
-		}
-		var err error
-		out[kv[0]], err = strconv.Atoi(kv[1])
-		if err != nil {
-			return err
-		}
-	}
-	if !s.changed {
-		*s.value = out
-	} else {
-		for k, v := range out {
-			(*s.value)[k] = v
-		}
-	}
-	s.changed = true
-	return nil
-}
-
-func (s *stringToIntValue) Type() string {
-	return "stringToInt"
-}
-
-func (s *stringToIntValue) String() string {
-	var buf bytes.Buffer
-	i := 0
-	for k, v := range *s.value {
-		if i > 0 {
-			buf.WriteRune(',')
-		}
-		buf.WriteString(k)
-		buf.WriteRune('=')
-		buf.WriteString(strconv.Itoa(v))
-		i++
-	}
-	return "[" + buf.String() + "]"
-}
-
-func stringToIntConv(val string) (interface{}, error) {
-	val = strings.Trim(val, "[]")
-	// An empty string would cause an empty map
-	if len(val) == 0 {
-		return map[string]int{}, nil
-	}
-	ss := strings.Split(val, ",")
-	out := make(map[string]int, len(ss))
-	for _, pair := range ss {
-		kv := strings.SplitN(pair, "=", 2)
-		if len(kv) != 2 {
-			return nil, fmt.Errorf("%s must be formatted as key=value", pair)
-		}
-		var err error
-		out[kv[0]], err = strconv.Atoi(kv[1])
-		if err != nil {
-			return nil, err
-		}
-	}
-	return out, nil
-}
-
-// GetStringToInt return the map[string]int value of a flag with the given name
-func (f *FlagSet) GetStringToInt(name string) (map[string]int, error) {
-	val, err := f.getFlagType(name, "stringToInt", stringToIntConv)
-	if err != nil {
-		return map[string]int{}, err
-	}
-	return val.(map[string]int), nil
-}
-
-// StringToIntVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a map[string]int variable in which to store the values of the multiple flags.
-// The value of each argument will not try to be separated by comma
-func (f *FlagSet) StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) {
-	f.VarP(newStringToIntValue(value, p), name, "", usage)
-}
-
-// StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) {
-	f.VarP(newStringToIntValue(value, p), name, shorthand, usage)
-}
-
-// StringToIntVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a map[string]int variable in which to store the value of the flag.
-// The value of each argument will not try to be separated by comma
-func StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) {
-	CommandLine.VarP(newStringToIntValue(value, p), name, "", usage)
-}
-
-// StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash.
-func StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) {
-	CommandLine.VarP(newStringToIntValue(value, p), name, shorthand, usage)
-}
-
-// StringToInt defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a map[string]int variable that stores the value of the flag.
-// The value of each argument will not try to be separated by comma
-func (f *FlagSet) StringToInt(name string, value map[string]int, usage string) *map[string]int {
-	p := map[string]int{}
-	f.StringToIntVarP(&p, name, "", value, usage)
-	return &p
-}
-
-// StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int {
-	p := map[string]int{}
-	f.StringToIntVarP(&p, name, shorthand, value, usage)
-	return &p
-}
-
-// StringToInt defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a map[string]int variable that stores the value of the flag.
-// The value of each argument will not try to be separated by comma
-func StringToInt(name string, value map[string]int, usage string) *map[string]int {
-	return CommandLine.StringToIntP(name, "", value, usage)
-}
-
-// StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash.
-func StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int {
-	return CommandLine.StringToIntP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/string_to_string.go b/vendor/github.com/spf13/pflag/string_to_string.go
deleted file mode 100644
index 890a01a..0000000
--- a/vendor/github.com/spf13/pflag/string_to_string.go
+++ /dev/null
@@ -1,160 +0,0 @@
-package pflag
-
-import (
-	"bytes"
-	"encoding/csv"
-	"fmt"
-	"strings"
-)
-
-// -- stringToString Value
-type stringToStringValue struct {
-	value   *map[string]string
-	changed bool
-}
-
-func newStringToStringValue(val map[string]string, p *map[string]string) *stringToStringValue {
-	ssv := new(stringToStringValue)
-	ssv.value = p
-	*ssv.value = val
-	return ssv
-}
-
-// Format: a=1,b=2
-func (s *stringToStringValue) Set(val string) error {
-	var ss []string
-	n := strings.Count(val, "=")
-	switch n {
-	case 0:
-		return fmt.Errorf("%s must be formatted as key=value", val)
-	case 1:
-		ss = append(ss, strings.Trim(val, `"`))
-	default:
-		r := csv.NewReader(strings.NewReader(val))
-		var err error
-		ss, err = r.Read()
-		if err != nil {
-			return err
-		}
-	}
-
-	out := make(map[string]string, len(ss))
-	for _, pair := range ss {
-		kv := strings.SplitN(pair, "=", 2)
-		if len(kv) != 2 {
-			return fmt.Errorf("%s must be formatted as key=value", pair)
-		}
-		out[kv[0]] = kv[1]
-	}
-	if !s.changed {
-		*s.value = out
-	} else {
-		for k, v := range out {
-			(*s.value)[k] = v
-		}
-	}
-	s.changed = true
-	return nil
-}
-
-func (s *stringToStringValue) Type() string {
-	return "stringToString"
-}
-
-func (s *stringToStringValue) String() string {
-	records := make([]string, 0, len(*s.value)>>1)
-	for k, v := range *s.value {
-		records = append(records, k+"="+v)
-	}
-
-	var buf bytes.Buffer
-	w := csv.NewWriter(&buf)
-	if err := w.Write(records); err != nil {
-		panic(err)
-	}
-	w.Flush()
-	return "[" + strings.TrimSpace(buf.String()) + "]"
-}
-
-func stringToStringConv(val string) (interface{}, error) {
-	val = strings.Trim(val, "[]")
-	// An empty string would cause an empty map
-	if len(val) == 0 {
-		return map[string]string{}, nil
-	}
-	r := csv.NewReader(strings.NewReader(val))
-	ss, err := r.Read()
-	if err != nil {
-		return nil, err
-	}
-	out := make(map[string]string, len(ss))
-	for _, pair := range ss {
-		kv := strings.SplitN(pair, "=", 2)
-		if len(kv) != 2 {
-			return nil, fmt.Errorf("%s must be formatted as key=value", pair)
-		}
-		out[kv[0]] = kv[1]
-	}
-	return out, nil
-}
-
-// GetStringToString return the map[string]string value of a flag with the given name
-func (f *FlagSet) GetStringToString(name string) (map[string]string, error) {
-	val, err := f.getFlagType(name, "stringToString", stringToStringConv)
-	if err != nil {
-		return map[string]string{}, err
-	}
-	return val.(map[string]string), nil
-}
-
-// StringToStringVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a map[string]string variable in which to store the values of the multiple flags.
-// The value of each argument will not try to be separated by comma
-func (f *FlagSet) StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) {
-	f.VarP(newStringToStringValue(value, p), name, "", usage)
-}
-
-// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) {
-	f.VarP(newStringToStringValue(value, p), name, shorthand, usage)
-}
-
-// StringToStringVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a map[string]string variable in which to store the value of the flag.
-// The value of each argument will not try to be separated by comma
-func StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) {
-	CommandLine.VarP(newStringToStringValue(value, p), name, "", usage)
-}
-
-// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash.
-func StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) {
-	CommandLine.VarP(newStringToStringValue(value, p), name, shorthand, usage)
-}
-
-// StringToString defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a map[string]string variable that stores the value of the flag.
-// The value of each argument will not try to be separated by comma
-func (f *FlagSet) StringToString(name string, value map[string]string, usage string) *map[string]string {
-	p := map[string]string{}
-	f.StringToStringVarP(&p, name, "", value, usage)
-	return &p
-}
-
-// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string {
-	p := map[string]string{}
-	f.StringToStringVarP(&p, name, shorthand, value, usage)
-	return &p
-}
-
-// StringToString defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a map[string]string variable that stores the value of the flag.
-// The value of each argument will not try to be separated by comma
-func StringToString(name string, value map[string]string, usage string) *map[string]string {
-	return CommandLine.StringToStringP(name, "", value, usage)
-}
-
-// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash.
-func StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string {
-	return CommandLine.StringToStringP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/uint.go b/vendor/github.com/spf13/pflag/uint.go
deleted file mode 100644
index dcbc2b7..0000000
--- a/vendor/github.com/spf13/pflag/uint.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- uint Value
-type uintValue uint
-
-func newUintValue(val uint, p *uint) *uintValue {
-	*p = val
-	return (*uintValue)(p)
-}
-
-func (i *uintValue) Set(s string) error {
-	v, err := strconv.ParseUint(s, 0, 64)
-	*i = uintValue(v)
-	return err
-}
-
-func (i *uintValue) Type() string {
-	return "uint"
-}
-
-func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
-
-func uintConv(sval string) (interface{}, error) {
-	v, err := strconv.ParseUint(sval, 0, 0)
-	if err != nil {
-		return 0, err
-	}
-	return uint(v), nil
-}
-
-// GetUint return the uint value of a flag with the given name
-func (f *FlagSet) GetUint(name string) (uint, error) {
-	val, err := f.getFlagType(name, "uint", uintConv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(uint), nil
-}
-
-// UintVar defines a uint flag with specified name, default value, and usage string.
-// The argument p points to a uint variable in which to store the value of the flag.
-func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
-	f.VarP(newUintValue(value, p), name, "", usage)
-}
-
-// UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, usage string) {
-	f.VarP(newUintValue(value, p), name, shorthand, usage)
-}
-
-// UintVar defines a uint flag with specified name, default value, and usage string.
-// The argument p points to a uint  variable in which to store the value of the flag.
-func UintVar(p *uint, name string, value uint, usage string) {
-	CommandLine.VarP(newUintValue(value, p), name, "", usage)
-}
-
-// UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash.
-func UintVarP(p *uint, name, shorthand string, value uint, usage string) {
-	CommandLine.VarP(newUintValue(value, p), name, shorthand, usage)
-}
-
-// Uint defines a uint flag with specified name, default value, and usage string.
-// The return value is the address of a uint  variable that stores the value of the flag.
-func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
-	p := new(uint)
-	f.UintVarP(p, name, "", value, usage)
-	return p
-}
-
-// UintP is like Uint, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) UintP(name, shorthand string, value uint, usage string) *uint {
-	p := new(uint)
-	f.UintVarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Uint defines a uint flag with specified name, default value, and usage string.
-// The return value is the address of a uint  variable that stores the value of the flag.
-func Uint(name string, value uint, usage string) *uint {
-	return CommandLine.UintP(name, "", value, usage)
-}
-
-// UintP is like Uint, but accepts a shorthand letter that can be used after a single dash.
-func UintP(name, shorthand string, value uint, usage string) *uint {
-	return CommandLine.UintP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/uint16.go b/vendor/github.com/spf13/pflag/uint16.go
deleted file mode 100644
index 7e9914e..0000000
--- a/vendor/github.com/spf13/pflag/uint16.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- uint16 value
-type uint16Value uint16
-
-func newUint16Value(val uint16, p *uint16) *uint16Value {
-	*p = val
-	return (*uint16Value)(p)
-}
-
-func (i *uint16Value) Set(s string) error {
-	v, err := strconv.ParseUint(s, 0, 16)
-	*i = uint16Value(v)
-	return err
-}
-
-func (i *uint16Value) Type() string {
-	return "uint16"
-}
-
-func (i *uint16Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
-
-func uint16Conv(sval string) (interface{}, error) {
-	v, err := strconv.ParseUint(sval, 0, 16)
-	if err != nil {
-		return 0, err
-	}
-	return uint16(v), nil
-}
-
-// GetUint16 return the uint16 value of a flag with the given name
-func (f *FlagSet) GetUint16(name string) (uint16, error) {
-	val, err := f.getFlagType(name, "uint16", uint16Conv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(uint16), nil
-}
-
-// Uint16Var defines a uint flag with specified name, default value, and usage string.
-// The argument p points to a uint variable in which to store the value of the flag.
-func (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage string) {
-	f.VarP(newUint16Value(value, p), name, "", usage)
-}
-
-// Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
-	f.VarP(newUint16Value(value, p), name, shorthand, usage)
-}
-
-// Uint16Var defines a uint flag with specified name, default value, and usage string.
-// The argument p points to a uint  variable in which to store the value of the flag.
-func Uint16Var(p *uint16, name string, value uint16, usage string) {
-	CommandLine.VarP(newUint16Value(value, p), name, "", usage)
-}
-
-// Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
-func Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
-	CommandLine.VarP(newUint16Value(value, p), name, shorthand, usage)
-}
-
-// Uint16 defines a uint flag with specified name, default value, and usage string.
-// The return value is the address of a uint  variable that stores the value of the flag.
-func (f *FlagSet) Uint16(name string, value uint16, usage string) *uint16 {
-	p := new(uint16)
-	f.Uint16VarP(p, name, "", value, usage)
-	return p
-}
-
-// Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
-	p := new(uint16)
-	f.Uint16VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Uint16 defines a uint flag with specified name, default value, and usage string.
-// The return value is the address of a uint  variable that stores the value of the flag.
-func Uint16(name string, value uint16, usage string) *uint16 {
-	return CommandLine.Uint16P(name, "", value, usage)
-}
-
-// Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash.
-func Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
-	return CommandLine.Uint16P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/uint32.go b/vendor/github.com/spf13/pflag/uint32.go
deleted file mode 100644
index d802453..0000000
--- a/vendor/github.com/spf13/pflag/uint32.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- uint32 value
-type uint32Value uint32
-
-func newUint32Value(val uint32, p *uint32) *uint32Value {
-	*p = val
-	return (*uint32Value)(p)
-}
-
-func (i *uint32Value) Set(s string) error {
-	v, err := strconv.ParseUint(s, 0, 32)
-	*i = uint32Value(v)
-	return err
-}
-
-func (i *uint32Value) Type() string {
-	return "uint32"
-}
-
-func (i *uint32Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
-
-func uint32Conv(sval string) (interface{}, error) {
-	v, err := strconv.ParseUint(sval, 0, 32)
-	if err != nil {
-		return 0, err
-	}
-	return uint32(v), nil
-}
-
-// GetUint32 return the uint32 value of a flag with the given name
-func (f *FlagSet) GetUint32(name string) (uint32, error) {
-	val, err := f.getFlagType(name, "uint32", uint32Conv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(uint32), nil
-}
-
-// Uint32Var defines a uint32 flag with specified name, default value, and usage string.
-// The argument p points to a uint32 variable in which to store the value of the flag.
-func (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage string) {
-	f.VarP(newUint32Value(value, p), name, "", usage)
-}
-
-// Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
-	f.VarP(newUint32Value(value, p), name, shorthand, usage)
-}
-
-// Uint32Var defines a uint32 flag with specified name, default value, and usage string.
-// The argument p points to a uint32  variable in which to store the value of the flag.
-func Uint32Var(p *uint32, name string, value uint32, usage string) {
-	CommandLine.VarP(newUint32Value(value, p), name, "", usage)
-}
-
-// Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
-func Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
-	CommandLine.VarP(newUint32Value(value, p), name, shorthand, usage)
-}
-
-// Uint32 defines a uint32 flag with specified name, default value, and usage string.
-// The return value is the address of a uint32  variable that stores the value of the flag.
-func (f *FlagSet) Uint32(name string, value uint32, usage string) *uint32 {
-	p := new(uint32)
-	f.Uint32VarP(p, name, "", value, usage)
-	return p
-}
-
-// Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
-	p := new(uint32)
-	f.Uint32VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Uint32 defines a uint32 flag with specified name, default value, and usage string.
-// The return value is the address of a uint32  variable that stores the value of the flag.
-func Uint32(name string, value uint32, usage string) *uint32 {
-	return CommandLine.Uint32P(name, "", value, usage)
-}
-
-// Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash.
-func Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
-	return CommandLine.Uint32P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/uint64.go b/vendor/github.com/spf13/pflag/uint64.go
deleted file mode 100644
index f62240f..0000000
--- a/vendor/github.com/spf13/pflag/uint64.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- uint64 Value
-type uint64Value uint64
-
-func newUint64Value(val uint64, p *uint64) *uint64Value {
-	*p = val
-	return (*uint64Value)(p)
-}
-
-func (i *uint64Value) Set(s string) error {
-	v, err := strconv.ParseUint(s, 0, 64)
-	*i = uint64Value(v)
-	return err
-}
-
-func (i *uint64Value) Type() string {
-	return "uint64"
-}
-
-func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
-
-func uint64Conv(sval string) (interface{}, error) {
-	v, err := strconv.ParseUint(sval, 0, 64)
-	if err != nil {
-		return 0, err
-	}
-	return uint64(v), nil
-}
-
-// GetUint64 return the uint64 value of a flag with the given name
-func (f *FlagSet) GetUint64(name string) (uint64, error) {
-	val, err := f.getFlagType(name, "uint64", uint64Conv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(uint64), nil
-}
-
-// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
-// The argument p points to a uint64 variable in which to store the value of the flag.
-func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
-	f.VarP(newUint64Value(value, p), name, "", usage)
-}
-
-// Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
-	f.VarP(newUint64Value(value, p), name, shorthand, usage)
-}
-
-// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
-// The argument p points to a uint64 variable in which to store the value of the flag.
-func Uint64Var(p *uint64, name string, value uint64, usage string) {
-	CommandLine.VarP(newUint64Value(value, p), name, "", usage)
-}
-
-// Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
-func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
-	CommandLine.VarP(newUint64Value(value, p), name, shorthand, usage)
-}
-
-// Uint64 defines a uint64 flag with specified name, default value, and usage string.
-// The return value is the address of a uint64 variable that stores the value of the flag.
-func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
-	p := new(uint64)
-	f.Uint64VarP(p, name, "", value, usage)
-	return p
-}
-
-// Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
-	p := new(uint64)
-	f.Uint64VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Uint64 defines a uint64 flag with specified name, default value, and usage string.
-// The return value is the address of a uint64 variable that stores the value of the flag.
-func Uint64(name string, value uint64, usage string) *uint64 {
-	return CommandLine.Uint64P(name, "", value, usage)
-}
-
-// Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash.
-func Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
-	return CommandLine.Uint64P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/uint8.go b/vendor/github.com/spf13/pflag/uint8.go
deleted file mode 100644
index bb0e83c..0000000
--- a/vendor/github.com/spf13/pflag/uint8.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package pflag
-
-import "strconv"
-
-// -- uint8 Value
-type uint8Value uint8
-
-func newUint8Value(val uint8, p *uint8) *uint8Value {
-	*p = val
-	return (*uint8Value)(p)
-}
-
-func (i *uint8Value) Set(s string) error {
-	v, err := strconv.ParseUint(s, 0, 8)
-	*i = uint8Value(v)
-	return err
-}
-
-func (i *uint8Value) Type() string {
-	return "uint8"
-}
-
-func (i *uint8Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
-
-func uint8Conv(sval string) (interface{}, error) {
-	v, err := strconv.ParseUint(sval, 0, 8)
-	if err != nil {
-		return 0, err
-	}
-	return uint8(v), nil
-}
-
-// GetUint8 return the uint8 value of a flag with the given name
-func (f *FlagSet) GetUint8(name string) (uint8, error) {
-	val, err := f.getFlagType(name, "uint8", uint8Conv)
-	if err != nil {
-		return 0, err
-	}
-	return val.(uint8), nil
-}
-
-// Uint8Var defines a uint8 flag with specified name, default value, and usage string.
-// The argument p points to a uint8 variable in which to store the value of the flag.
-func (f *FlagSet) Uint8Var(p *uint8, name string, value uint8, usage string) {
-	f.VarP(newUint8Value(value, p), name, "", usage)
-}
-
-// Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
-	f.VarP(newUint8Value(value, p), name, shorthand, usage)
-}
-
-// Uint8Var defines a uint8 flag with specified name, default value, and usage string.
-// The argument p points to a uint8 variable in which to store the value of the flag.
-func Uint8Var(p *uint8, name string, value uint8, usage string) {
-	CommandLine.VarP(newUint8Value(value, p), name, "", usage)
-}
-
-// Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
-func Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
-	CommandLine.VarP(newUint8Value(value, p), name, shorthand, usage)
-}
-
-// Uint8 defines a uint8 flag with specified name, default value, and usage string.
-// The return value is the address of a uint8 variable that stores the value of the flag.
-func (f *FlagSet) Uint8(name string, value uint8, usage string) *uint8 {
-	p := new(uint8)
-	f.Uint8VarP(p, name, "", value, usage)
-	return p
-}
-
-// Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
-	p := new(uint8)
-	f.Uint8VarP(p, name, shorthand, value, usage)
-	return p
-}
-
-// Uint8 defines a uint8 flag with specified name, default value, and usage string.
-// The return value is the address of a uint8 variable that stores the value of the flag.
-func Uint8(name string, value uint8, usage string) *uint8 {
-	return CommandLine.Uint8P(name, "", value, usage)
-}
-
-// Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash.
-func Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
-	return CommandLine.Uint8P(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/spf13/pflag/uint_slice.go b/vendor/github.com/spf13/pflag/uint_slice.go
deleted file mode 100644
index edd94c6..0000000
--- a/vendor/github.com/spf13/pflag/uint_slice.go
+++ /dev/null
@@ -1,126 +0,0 @@
-package pflag
-
-import (
-	"fmt"
-	"strconv"
-	"strings"
-)
-
-// -- uintSlice Value
-type uintSliceValue struct {
-	value   *[]uint
-	changed bool
-}
-
-func newUintSliceValue(val []uint, p *[]uint) *uintSliceValue {
-	uisv := new(uintSliceValue)
-	uisv.value = p
-	*uisv.value = val
-	return uisv
-}
-
-func (s *uintSliceValue) Set(val string) error {
-	ss := strings.Split(val, ",")
-	out := make([]uint, len(ss))
-	for i, d := range ss {
-		u, err := strconv.ParseUint(d, 10, 0)
-		if err != nil {
-			return err
-		}
-		out[i] = uint(u)
-	}
-	if !s.changed {
-		*s.value = out
-	} else {
-		*s.value = append(*s.value, out...)
-	}
-	s.changed = true
-	return nil
-}
-
-func (s *uintSliceValue) Type() string {
-	return "uintSlice"
-}
-
-func (s *uintSliceValue) String() string {
-	out := make([]string, len(*s.value))
-	for i, d := range *s.value {
-		out[i] = fmt.Sprintf("%d", d)
-	}
-	return "[" + strings.Join(out, ",") + "]"
-}
-
-func uintSliceConv(val string) (interface{}, error) {
-	val = strings.Trim(val, "[]")
-	// Empty string would cause a slice with one (empty) entry
-	if len(val) == 0 {
-		return []uint{}, nil
-	}
-	ss := strings.Split(val, ",")
-	out := make([]uint, len(ss))
-	for i, d := range ss {
-		u, err := strconv.ParseUint(d, 10, 0)
-		if err != nil {
-			return nil, err
-		}
-		out[i] = uint(u)
-	}
-	return out, nil
-}
-
-// GetUintSlice returns the []uint value of a flag with the given name.
-func (f *FlagSet) GetUintSlice(name string) ([]uint, error) {
-	val, err := f.getFlagType(name, "uintSlice", uintSliceConv)
-	if err != nil {
-		return []uint{}, err
-	}
-	return val.([]uint), nil
-}
-
-// UintSliceVar defines a uintSlice flag with specified name, default value, and usage string.
-// The argument p points to a []uint variable in which to store the value of the flag.
-func (f *FlagSet) UintSliceVar(p *[]uint, name string, value []uint, usage string) {
-	f.VarP(newUintSliceValue(value, p), name, "", usage)
-}
-
-// UintSliceVarP is like UintSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) {
-	f.VarP(newUintSliceValue(value, p), name, shorthand, usage)
-}
-
-// UintSliceVar defines a uint[] flag with specified name, default value, and usage string.
-// The argument p points to a uint[] variable in which to store the value of the flag.
-func UintSliceVar(p *[]uint, name string, value []uint, usage string) {
-	CommandLine.VarP(newUintSliceValue(value, p), name, "", usage)
-}
-
-// UintSliceVarP is like the UintSliceVar, but accepts a shorthand letter that can be used after a single dash.
-func UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) {
-	CommandLine.VarP(newUintSliceValue(value, p), name, shorthand, usage)
-}
-
-// UintSlice defines a []uint flag with specified name, default value, and usage string.
-// The return value is the address of a []uint variable that stores the value of the flag.
-func (f *FlagSet) UintSlice(name string, value []uint, usage string) *[]uint {
-	p := []uint{}
-	f.UintSliceVarP(&p, name, "", value, usage)
-	return &p
-}
-
-// UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash.
-func (f *FlagSet) UintSliceP(name, shorthand string, value []uint, usage string) *[]uint {
-	p := []uint{}
-	f.UintSliceVarP(&p, name, shorthand, value, usage)
-	return &p
-}
-
-// UintSlice defines a []uint flag with specified name, default value, and usage string.
-// The return value is the address of a []uint variable that stores the value of the flag.
-func UintSlice(name string, value []uint, usage string) *[]uint {
-	return CommandLine.UintSliceP(name, "", value, usage)
-}
-
-// UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash.
-func UintSliceP(name, shorthand string, value []uint, usage string) *[]uint {
-	return CommandLine.UintSliceP(name, shorthand, value, usage)
-}
diff --git a/vendor/github.com/tmc/grpc-websocket-proxy/LICENSE b/vendor/github.com/tmc/grpc-websocket-proxy/LICENSE
deleted file mode 100644
index 95d0bc8..0000000
--- a/vendor/github.com/tmc/grpc-websocket-proxy/LICENSE
+++ /dev/null
@@ -1,7 +0,0 @@
-Copyright (C) 2016 Travis Cline
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/tmc/grpc-websocket-proxy/wsproxy/doc.go b/vendor/github.com/tmc/grpc-websocket-proxy/wsproxy/doc.go
deleted file mode 100644
index baf9545..0000000
--- a/vendor/github.com/tmc/grpc-websocket-proxy/wsproxy/doc.go
+++ /dev/null
@@ -1,2 +0,0 @@
-// Package wsproxy implements a websocket proxy for grpc-gateway backed services
-package wsproxy
diff --git a/vendor/github.com/tmc/grpc-websocket-proxy/wsproxy/websocket_proxy.go b/vendor/github.com/tmc/grpc-websocket-proxy/wsproxy/websocket_proxy.go
deleted file mode 100644
index ada4c4e..0000000
--- a/vendor/github.com/tmc/grpc-websocket-proxy/wsproxy/websocket_proxy.go
+++ /dev/null
@@ -1,291 +0,0 @@
-package wsproxy
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"net/http"
-	"strings"
-
-	"github.com/gorilla/websocket"
-	"github.com/sirupsen/logrus"
-	"golang.org/x/net/context"
-)
-
-// MethodOverrideParam defines the special URL parameter that is translated into the subsequent proxied streaming http request's method.
-//
-// Deprecated: it is preferable to use the Options parameters to WebSocketProxy to supply parameters.
-var MethodOverrideParam = "method"
-
-// TokenCookieName defines the cookie name that is translated to an 'Authorization: Bearer' header in the streaming http request's headers.
-//
-// Deprecated: it is preferable to use the Options parameters to WebSocketProxy to supply parameters.
-var TokenCookieName = "token"
-
-// RequestMutatorFunc can supply an alternate outgoing request.
-type RequestMutatorFunc func(incoming *http.Request, outgoing *http.Request) *http.Request
-
-// Proxy provides websocket transport upgrade to compatible endpoints.
-type Proxy struct {
-	h                   http.Handler
-	logger              Logger
-	methodOverrideParam string
-	tokenCookieName     string
-	requestMutator      RequestMutatorFunc
-	headerForwarder     func(header string) bool
-}
-
-// Logger collects log messages.
-type Logger interface {
-	Warnln(...interface{})
-	Debugln(...interface{})
-}
-
-func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if !websocket.IsWebSocketUpgrade(r) {
-		p.h.ServeHTTP(w, r)
-		return
-	}
-	p.proxy(w, r)
-}
-
-// Option allows customization of the proxy.
-type Option func(*Proxy)
-
-// WithMethodParamOverride allows specification of the special http parameter that is used in the proxied streaming request.
-func WithMethodParamOverride(param string) Option {
-	return func(p *Proxy) {
-		p.methodOverrideParam = param
-	}
-}
-
-// WithTokenCookieName allows specification of the cookie that is supplied as an upstream 'Authorization: Bearer' http header.
-func WithTokenCookieName(param string) Option {
-	return func(p *Proxy) {
-		p.tokenCookieName = param
-	}
-}
-
-// WithRequestMutator allows a custom RequestMutatorFunc to be supplied.
-func WithRequestMutator(fn RequestMutatorFunc) Option {
-	return func(p *Proxy) {
-		p.requestMutator = fn
-	}
-}
-
-// WithForwardedHeaders allows controlling which headers are forwarded.
-func WithForwardedHeaders(fn func(header string) bool) Option {
-	return func(p *Proxy) {
-		p.headerForwarder = fn
-	}
-}
-
-// WithLogger allows a custom FieldLogger to be supplied
-func WithLogger(logger Logger) Option {
-	return func(p *Proxy) {
-		p.logger = logger
-	}
-}
-
-var defaultHeadersToForward = map[string]bool{
-	"Origin":  true,
-	"origin":  true,
-	"Referer": true,
-	"referer": true,
-}
-
-func defaultHeaderForwarder(header string) bool {
-	return defaultHeadersToForward[header]
-}
-
-// WebsocketProxy attempts to expose the underlying handler as a bidi websocket stream with newline-delimited
-// JSON as the content encoding.
-//
-// The HTTP Authorization header is either populated from the Sec-Websocket-Protocol field or by a cookie.
-// The cookie name is specified by the TokenCookieName value.
-//
-// example:
-//   Sec-Websocket-Protocol: Bearer, foobar
-// is converted to:
-//   Authorization: Bearer foobar
-//
-// Method can be overwritten with the MethodOverrideParam get parameter in the requested URL
-func WebsocketProxy(h http.Handler, opts ...Option) http.Handler {
-	p := &Proxy{
-		h:                   h,
-		logger:              logrus.New(),
-		methodOverrideParam: MethodOverrideParam,
-		tokenCookieName:     TokenCookieName,
-		headerForwarder:     defaultHeaderForwarder,
-	}
-	for _, o := range opts {
-		o(p)
-	}
-	return p
-}
-
-// TODO(tmc): allow modification of upgrader settings?
-var upgrader = websocket.Upgrader{
-	ReadBufferSize:  1024,
-	WriteBufferSize: 1024,
-	CheckOrigin:     func(r *http.Request) bool { return true },
-}
-
-func isClosedConnError(err error) bool {
-	str := err.Error()
-	if strings.Contains(str, "use of closed network connection") {
-		return true
-	}
-	return websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway)
-}
-
-func (p *Proxy) proxy(w http.ResponseWriter, r *http.Request) {
-	var responseHeader http.Header
-	// If Sec-WebSocket-Protocol starts with "Bearer", respond in kind.
-	// TODO(tmc): consider customizability/extension point here.
-	if strings.HasPrefix(r.Header.Get("Sec-WebSocket-Protocol"), "Bearer") {
-		responseHeader = http.Header{
-			"Sec-WebSocket-Protocol": []string{"Bearer"},
-		}
-	}
-	conn, err := upgrader.Upgrade(w, r, responseHeader)
-	if err != nil {
-		p.logger.Warnln("error upgrading websocket:", err)
-		return
-	}
-	defer conn.Close()
-
-	ctx, cancelFn := context.WithCancel(context.Background())
-	defer cancelFn()
-
-	requestBodyR, requestBodyW := io.Pipe()
-	request, err := http.NewRequest(r.Method, r.URL.String(), requestBodyR)
-	if err != nil {
-		p.logger.Warnln("error preparing request:", err)
-		return
-	}
-	if swsp := r.Header.Get("Sec-WebSocket-Protocol"); swsp != "" {
-		request.Header.Set("Authorization", transformSubProtocolHeader(swsp))
-	}
-	for header := range r.Header {
-		if p.headerForwarder(header) {
-			request.Header.Set(header, r.Header.Get(header))
-		}
-	}
-	// If token cookie is present, populate Authorization header from the cookie instead.
-	if cookie, err := r.Cookie(p.tokenCookieName); err == nil {
-		request.Header.Set("Authorization", "Bearer "+cookie.Value)
-	}
-	if m := r.URL.Query().Get(p.methodOverrideParam); m != "" {
-		request.Method = m
-	}
-
-	if p.requestMutator != nil {
-		request = p.requestMutator(r, request)
-	}
-
-	responseBodyR, responseBodyW := io.Pipe()
-	response := newInMemoryResponseWriter(responseBodyW)
-	go func() {
-		<-ctx.Done()
-		p.logger.Debugln("closing pipes")
-		requestBodyW.CloseWithError(io.EOF)
-		responseBodyW.CloseWithError(io.EOF)
-		response.closed <- true
-	}()
-
-	go func() {
-		defer cancelFn()
-		p.h.ServeHTTP(response, request)
-	}()
-
-	// read loop -- take messages from websocket and write to http request
-	go func() {
-		defer func() {
-			cancelFn()
-		}()
-		for {
-			select {
-			case <-ctx.Done():
-				p.logger.Debugln("read loop done")
-				return
-			default:
-			}
-			p.logger.Debugln("[read] reading from socket.")
-			_, payload, err := conn.ReadMessage()
-			if err != nil {
-				if isClosedConnError(err) {
-					p.logger.Debugln("[read] websocket closed:", err)
-					return
-				}
-				p.logger.Warnln("error reading websocket message:", err)
-				return
-			}
-			p.logger.Debugln("[read] read payload:", string(payload))
-			p.logger.Debugln("[read] writing to requestBody:")
-			n, err := requestBodyW.Write(payload)
-			requestBodyW.Write([]byte("\n"))
-			p.logger.Debugln("[read] wrote to requestBody", n)
-			if err != nil {
-				p.logger.Warnln("[read] error writing message to upstream http server:", err)
-				return
-			}
-		}
-	}()
-	// write loop -- take messages from response and write to websocket
-	scanner := bufio.NewScanner(responseBodyR)
-	for scanner.Scan() {
-		if len(scanner.Bytes()) == 0 {
-			p.logger.Warnln("[write] empty scan", scanner.Err())
-			continue
-		}
-		p.logger.Debugln("[write] scanned", scanner.Text())
-		if err = conn.WriteMessage(websocket.TextMessage, scanner.Bytes()); err != nil {
-			p.logger.Warnln("[write] error writing websocket message:", err)
-			return
-		}
-	}
-	if err := scanner.Err(); err != nil {
-		p.logger.Warnln("scanner err:", err)
-	}
-}
-
-type inMemoryResponseWriter struct {
-	io.Writer
-	header http.Header
-	code   int
-	closed chan bool
-}
-
-func newInMemoryResponseWriter(w io.Writer) *inMemoryResponseWriter {
-	return &inMemoryResponseWriter{
-		Writer: w,
-		header: http.Header{},
-		closed: make(chan bool, 1),
-	}
-}
-
-// IE and Edge do not delimit Sec-WebSocket-Protocol strings with spaces
-func transformSubProtocolHeader(header string) string {
-	tokens := strings.SplitN(header, "Bearer,", 2)
-
-	if len(tokens) < 2 {
-		return ""
-	}
-
-	return fmt.Sprintf("Bearer %v", strings.Trim(tokens[1], " "))
-}
-
-func (w *inMemoryResponseWriter) Write(b []byte) (int, error) {
-	return w.Writer.Write(b)
-}
-func (w *inMemoryResponseWriter) Header() http.Header {
-	return w.header
-}
-func (w *inMemoryResponseWriter) WriteHeader(code int) {
-	w.code = code
-}
-func (w *inMemoryResponseWriter) CloseNotify() <-chan bool {
-	return w.closed
-}
-func (w *inMemoryResponseWriter) Flush() {}
diff --git a/vendor/github.com/ugorji/go/LICENSE b/vendor/github.com/ugorji/go/LICENSE
deleted file mode 100644
index 95a0f05..0000000
--- a/vendor/github.com/ugorji/go/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2012-2015 Ugorji Nwoke.
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/vendor/github.com/ugorji/go/codec/0doc.go b/vendor/github.com/ugorji/go/codec/0doc.go
deleted file mode 100644
index b61a818..0000000
--- a/vendor/github.com/ugorji/go/codec/0doc.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-/*
-Package codec provides a
-High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library
-for binc, msgpack, cbor, json.
-
-Supported Serialization formats are:
-
-  - msgpack: https://github.com/msgpack/msgpack
-  - binc:    http://github.com/ugorji/binc
-  - cbor:    http://cbor.io http://tools.ietf.org/html/rfc7049
-  - json:    http://json.org http://tools.ietf.org/html/rfc7159
-  - simple:
-
-To install:
-
-    go get github.com/ugorji/go/codec
-
-This package will carefully use 'unsafe' for performance reasons in specific places.
-You can build without unsafe use by passing the safe or appengine tag
-i.e. 'go install -tags=safe ...'. Note that unsafe is only supported for the last 3
-go sdk versions e.g. current go release is go 1.9, so we support unsafe use only from
-go 1.7+ . This is because supporting unsafe requires knowledge of implementation details.
-
-For detailed usage information, read the primer at http://ugorji.net/blog/go-codec-primer .
-
-The idiomatic Go support is as seen in other encoding packages in
-the standard library (ie json, xml, gob, etc).
-
-Rich Feature Set includes:
-
-  - Simple but extremely powerful and feature-rich API
-  - Support for go1.4 and above, while selectively using newer APIs for later releases
-  - Excellent code coverage ( > 90% )
-  - Very High Performance.
-    Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
-  - Careful selected use of 'unsafe' for targeted performance gains.
-    100% mode exists where 'unsafe' is not used at all.
-  - Lock-free (sans mutex) concurrency for scaling to 100's of cores
-  - Coerce types where appropriate
-    e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
-  - Corner Cases:
-    Overflows, nil maps/slices, nil values in streams are handled correctly
-  - Standard field renaming via tags
-  - Support for omitting empty fields during an encoding
-  - Encoding from any value and decoding into pointer to any value
-    (struct, slice, map, primitives, pointers, interface{}, etc)
-  - Extensions to support efficient encoding/decoding of any named types
-  - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
-  - Support IsZero() bool to determine if a value is a zero value.
-    Analogous to time.Time.IsZero() bool.
-  - Decoding without a schema (into a interface{}).
-    Includes Options to configure what specific map or slice type to use
-    when decoding an encoded list or map into a nil interface{}
-  - Mapping a non-interface type to an interface, so we can decode appropriately
-    into any interface type with a correctly configured non-interface value.
-  - Encode a struct as an array, and decode struct from an array in the data stream
-  - Option to encode struct keys as numbers (instead of strings)
-    (to support structured streams with fields encoded as numeric codes)
-  - Comprehensive support for anonymous fields
-  - Fast (no-reflection) encoding/decoding of common maps and slices
-  - Code-generation for faster performance.
-  - Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
-  - Support indefinite-length formats to enable true streaming
-    (for formats which support it e.g. json, cbor)
-  - Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes.
-    This mostly applies to maps, where iteration order is non-deterministic.
-  - NIL in data stream decoded as zero value
-  - Never silently skip data when decoding.
-    User decides whether to return an error or silently skip data when keys or indexes
-    in the data stream do not map to fields in the struct.
-  - Detect and error when encoding a cyclic reference (instead of stack overflow shutdown)
-  - Encode/Decode from/to chan types (for iterative streaming support)
-  - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
-  - Provides a RPC Server and Client Codec for net/rpc communication protocol.
-  - Handle unique idiosyncrasies of codecs e.g.
-    - For messagepack, configure how ambiguities in handling raw bytes are resolved
-    - For messagepack, provide rpc server/client codec to support
-      msgpack-rpc protocol defined at:
-      https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
-
-Extension Support
-
-Users can register a function to handle the encoding or decoding of
-their custom types.
-
-There are no restrictions on what the custom type can be. Some examples:
-
-    type BisSet   []int
-    type BitSet64 uint64
-    type UUID     string
-    type MyStructWithUnexportedFields struct { a int; b bool; c []int; }
-    type GifImage struct { ... }
-
-As an illustration, MyStructWithUnexportedFields would normally be
-encoded as an empty map because it has no exported fields, while UUID
-would be encoded as a string. However, with extension support, you can
-encode any of these however you like.
-
-Custom Encoding and Decoding
-
-This package maintains symmetry in the encoding and decoding halfs.
-We determine how to encode or decode by walking this decision tree
-
-  - is type a codec.Selfer?
-  - is there an extension registered for the type?
-  - is format binary, and is type a encoding.BinaryMarshaler and BinaryUnmarshaler?
-  - is format specifically json, and is type a encoding/json.Marshaler and Unmarshaler?
-  - is format text-based, and type an encoding.TextMarshaler?
-  - else we use a pair of functions based on the "kind" of the type e.g. map, slice, int64, etc
-
-This symmetry is important to reduce chances of issues happening because the
-encoding and decoding sides are out of sync e.g. decoded via very specific
-encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
-
-Consequently, if a type only defines one-half of the symmetry
-(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
-then that type doesn't satisfy the check and we will continue walking down the
-decision tree.
-
-RPC
-
-RPC Client and Server Codecs are implemented, so the codecs can be used
-with the standard net/rpc package.
-
-Usage
-
-The Handle is SAFE for concurrent READ, but NOT SAFE for concurrent modification.
-
-The Encoder and Decoder are NOT safe for concurrent use.
-
-Consequently, the usage model is basically:
-
-    - Create and initialize the Handle before any use.
-      Once created, DO NOT modify it.
-    - Multiple Encoders or Decoders can now use the Handle concurrently.
-      They only read information off the Handle (never write).
-    - However, each Encoder or Decoder MUST not be used concurrently
-    - To re-use an Encoder/Decoder, call Reset(...) on it first.
-      This allows you use state maintained on the Encoder/Decoder.
-
-Sample usage model:
-
-    // create and configure Handle
-    var (
-      bh codec.BincHandle
-      mh codec.MsgpackHandle
-      ch codec.CborHandle
-    )
-
-    mh.MapType = reflect.TypeOf(map[string]interface{}(nil))
-
-    // configure extensions
-    // e.g. for msgpack, define functions and enable Time support for tag 1
-    // mh.SetExt(reflect.TypeOf(time.Time{}), 1, myExt)
-
-    // create and use decoder/encoder
-    var (
-      r io.Reader
-      w io.Writer
-      b []byte
-      h = &bh // or mh to use msgpack
-    )
-
-    dec = codec.NewDecoder(r, h)
-    dec = codec.NewDecoderBytes(b, h)
-    err = dec.Decode(&v)
-
-    enc = codec.NewEncoder(w, h)
-    enc = codec.NewEncoderBytes(&b, h)
-    err = enc.Encode(v)
-
-    //RPC Server
-    go func() {
-        for {
-            conn, err := listener.Accept()
-            rpcCodec := codec.GoRpc.ServerCodec(conn, h)
-            //OR rpcCodec := codec.MsgpackSpecRpc.ServerCodec(conn, h)
-            rpc.ServeCodec(rpcCodec)
-        }
-    }()
-
-    //RPC Communication (client side)
-    conn, err = net.Dial("tcp", "localhost:5555")
-    rpcCodec := codec.GoRpc.ClientCodec(conn, h)
-    //OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
-    client := rpc.NewClientWithCodec(rpcCodec)
-
-Running Tests
-
-To run tests, use the following:
-
-    go test
-
-To run the full suite of tests, use the following:
-
-    go test -tags alltests -run Suite
-
-You can run the tag 'safe' to run tests or build in safe mode. e.g.
-
-    go test -tags safe -run Json
-    go test -tags "alltests safe" -run Suite
-
-Running Benchmarks
-
-Please see http://github.com/ugorji/go-codec-bench .
-
-Caveats
-
-Struct fields matching the following are ignored during encoding and decoding
-    - struct tag value set to -
-    - func, complex numbers, unsafe pointers
-    - unexported and not embedded
-    - unexported and embedded and not struct kind
-    - unexported and embedded pointers (from go1.10)
-
-Every other field in a struct will be encoded/decoded.
-
-Embedded fields are encoded as if they exist in the top-level struct,
-with some caveats. See Encode documentation.
-
-*/
-package codec
-
-// TODO:
-//   - For Go 1.11, when mid-stack inlining is enabled,
-//     we should use committed functions for writeXXX and readXXX calls.
-//     This involves uncommenting the methods for decReaderSwitch and encWriterSwitch
-//     and using those (decReaderSwitch and encWriterSwitch) in all handles
-//     instead of encWriter and decReader.
-//     The benefit is that, for the (En|De)coder over []byte, the encWriter/decReader
-//     will be inlined, giving a performance bump for that typical case.
-//     However, it will only  be inlined if mid-stack inlining is enabled,
-//     as we call panic to raise errors, and panic currently prevents inlining.
-//
-// PUNTED:
-//   - To make Handle comparable, make extHandle in BasicHandle a non-embedded pointer,
-//     and use overlay methods on *BasicHandle to call through to extHandle after initializing
-//     the "xh *extHandle" to point to a real slice.
-//
-// BEFORE EACH RELEASE:
-//   - Look through and fix padding for each type, to eliminate false sharing
-//     - critical shared objects that are read many times
-//       TypeInfos
-//     - pooled objects:
-//       decNaked, decNakedContainers, codecFner, typeInfoLoadArray, 
-//     - small objects allocated independently, that we read/use much across threads:
-//       codecFn, typeInfo
-//     - Objects allocated independently and used a lot
-//       Decoder, Encoder,
-//       xxxHandle, xxxEncDriver, xxxDecDriver (xxx = json, msgpack, cbor, binc, simple)
-//     - In all above, arrange values modified together to be close to each other.
-//
-//     For all of these, either ensure that they occupy full cache lines,
-//     or ensure that the things just past the cache line boundary are hardly read/written
-//     e.g. JsonHandle.RawBytesExt - which is copied into json(En|De)cDriver at init
-//
-//     Occupying full cache lines means they occupy 8*N words (where N is an integer).
-//     Check this out by running: ./run.sh -z
-//     - look at those tagged ****, meaning they are not occupying full cache lines
-//     - look at those tagged <<<<, meaning they are larger than 32 words (something to watch)
-//   - Run "golint -min_confidence 0.81"
diff --git a/vendor/github.com/ugorji/go/codec/README.md b/vendor/github.com/ugorji/go/codec/README.md
deleted file mode 100644
index 50d65e5..0000000
--- a/vendor/github.com/ugorji/go/codec/README.md
+++ /dev/null
@@ -1,206 +0,0 @@
-# Codec
-
-High Performance, Feature-Rich Idiomatic Go codec/encoding library for
-binc, msgpack, cbor, json.
-
-Supported Serialization formats are:
-
-  - msgpack: https://github.com/msgpack/msgpack
-  - binc:    http://github.com/ugorji/binc
-  - cbor:    http://cbor.io http://tools.ietf.org/html/rfc7049
-  - json:    http://json.org http://tools.ietf.org/html/rfc7159
-  - simple: 
-
-To install:
-
-    go get github.com/ugorji/go/codec
-
-This package will carefully use 'unsafe' for performance reasons in specific places.
-You can build without unsafe use by passing the safe or appengine tag
-i.e. 'go install -tags=safe ...'. Note that unsafe is only supported for the last 3
-go sdk versions e.g. current go release is go 1.9, so we support unsafe use only from
-go 1.7+ . This is because supporting unsafe requires knowledge of implementation details.
-
-Online documentation: http://godoc.org/github.com/ugorji/go/codec  
-Detailed Usage/How-to Primer: http://ugorji.net/blog/go-codec-primer
-
-The idiomatic Go support is as seen in other encoding packages in
-the standard library (ie json, xml, gob, etc).
-
-Rich Feature Set includes:
-
-  - Simple but extremely powerful and feature-rich API
-  - Support for go1.4 and above, while selectively using newer APIs for later releases
-  - Excellent code coverage ( > 90% )
-  - Very High Performance.
-    Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
-  - Careful selected use of 'unsafe' for targeted performance gains.
-    100% mode exists where 'unsafe' is not used at all.
-  - Lock-free (sans mutex) concurrency for scaling to 100's of cores
-  - Coerce types where appropriate
-    e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
-  - Corner Cases: 
-    Overflows, nil maps/slices, nil values in streams are handled correctly
-  - Standard field renaming via tags
-  - Support for omitting empty fields during an encoding
-  - Encoding from any value and decoding into pointer to any value
-    (struct, slice, map, primitives, pointers, interface{}, etc)
-  - Extensions to support efficient encoding/decoding of any named types
-  - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
-  - Support IsZero() bool to determine if a value is a zero value.
-    Analogous to time.Time.IsZero() bool.
-  - Decoding without a schema (into a interface{}).
-    Includes Options to configure what specific map or slice type to use
-    when decoding an encoded list or map into a nil interface{}
-  - Mapping a non-interface type to an interface, so we can decode appropriately
-    into any interface type with a correctly configured non-interface value.
-  - Encode a struct as an array, and decode struct from an array in the data stream
-  - Option to encode struct keys as numbers (instead of strings)
-    (to support structured streams with fields encoded as numeric codes)
-  - Comprehensive support for anonymous fields
-  - Fast (no-reflection) encoding/decoding of common maps and slices
-  - Code-generation for faster performance.
-  - Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
-  - Support indefinite-length formats to enable true streaming 
-    (for formats which support it e.g. json, cbor)
-  - Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes.
-    This mostly applies to maps, where iteration order is non-deterministic.
-  - NIL in data stream decoded as zero value
-  - Never silently skip data when decoding.
-    User decides whether to return an error or silently skip data when keys or indexes
-    in the data stream do not map to fields in the struct.
-  - Encode/Decode from/to chan types (for iterative streaming support)
-  - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
-  - Provides a RPC Server and Client Codec for net/rpc communication protocol.
-  - Handle unique idiosyncrasies of codecs e.g. 
-    - For messagepack, configure how ambiguities in handling raw bytes are resolved 
-    - For messagepack, provide rpc server/client codec to support
-      msgpack-rpc protocol defined at:
-      https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
-
-## Extension Support
-
-Users can register a function to handle the encoding or decoding of
-their custom types.
-
-There are no restrictions on what the custom type can be. Some examples:
-
-    type BisSet   []int
-    type BitSet64 uint64
-    type UUID     string
-    type MyStructWithUnexportedFields struct { a int; b bool; c []int; }
-    type GifImage struct { ... }
-
-As an illustration, MyStructWithUnexportedFields would normally be
-encoded as an empty map because it has no exported fields, while UUID
-would be encoded as a string. However, with extension support, you can
-encode any of these however you like.
-
-## Custom Encoding and Decoding
-
-This package maintains symmetry in the encoding and decoding halfs.
-We determine how to encode or decode by walking this decision tree
-
-  - is type a codec.Selfer?
-  - is there an extension registered for the type?
-  - is format binary, and is type a encoding.BinaryMarshaler and BinaryUnmarshaler?
-  - is format specifically json, and is type a encoding/json.Marshaler and Unmarshaler?
-  - is format text-based, and type an encoding.TextMarshaler?
-  - else we use a pair of functions based on the "kind" of the type e.g. map, slice, int64, etc
-
-This symmetry is important to reduce chances of issues happening because the
-encoding and decoding sides are out of sync e.g. decoded via very specific
-encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
-
-Consequently, if a type only defines one-half of the symmetry
-(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
-then that type doesn't satisfy the check and we will continue walking down the
-decision tree.
-
-## RPC
-
-RPC Client and Server Codecs are implemented, so the codecs can be used
-with the standard net/rpc package.
-
-## Usage
-
-Typical usage model:
-
-    // create and configure Handle
-    var (
-      bh codec.BincHandle
-      mh codec.MsgpackHandle
-      ch codec.CborHandle
-    )
-
-    mh.MapType = reflect.TypeOf(map[string]interface{}(nil))
-
-    // configure extensions
-    // e.g. for msgpack, define functions and enable Time support for tag 1
-    // mh.SetExt(reflect.TypeOf(time.Time{}), 1, myExt)
-
-    // create and use decoder/encoder
-    var (
-      r io.Reader
-      w io.Writer
-      b []byte
-      h = &bh // or mh to use msgpack
-    )
-
-    dec = codec.NewDecoder(r, h)
-    dec = codec.NewDecoderBytes(b, h)
-    err = dec.Decode(&v)
-
-    enc = codec.NewEncoder(w, h)
-    enc = codec.NewEncoderBytes(&b, h)
-    err = enc.Encode(v)
-
-    //RPC Server
-    go func() {
-        for {
-            conn, err := listener.Accept()
-            rpcCodec := codec.GoRpc.ServerCodec(conn, h)
-            //OR rpcCodec := codec.MsgpackSpecRpc.ServerCodec(conn, h)
-            rpc.ServeCodec(rpcCodec)
-        }
-    }()
-
-    //RPC Communication (client side)
-    conn, err = net.Dial("tcp", "localhost:5555")
-    rpcCodec := codec.GoRpc.ClientCodec(conn, h)
-    //OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
-    client := rpc.NewClientWithCodec(rpcCodec)
-
-## Running Tests
-
-To run tests, use the following:
-
-    go test
-
-To run the full suite of tests, use the following:
-
-    go test -tags alltests -run Suite
-
-You can run the tag 'safe' to run tests or build in safe mode. e.g.
-
-    go test -tags safe -run Json
-    go test -tags "alltests safe" -run Suite
-
-## Running Benchmarks
-
-Please see http://github.com/ugorji/go-codec-bench .
-
-## Caveats
-
-Struct fields matching the following are ignored during encoding and decoding
-
-  - struct tag value set to -
-  - func, complex numbers, unsafe pointers
-  - unexported and not embedded
-  - unexported and embedded and not struct kind
-  - unexported and embedded pointers (from go1.10)
-
-Every other field in a struct will be encoded/decoded.
-
-Embedded fields are encoded as if they exist in the top-level struct,
-with some caveats. See Encode documentation.
diff --git a/vendor/github.com/ugorji/go/codec/binc.go b/vendor/github.com/ugorji/go/codec/binc.go
deleted file mode 100644
index a3c96fe..0000000
--- a/vendor/github.com/ugorji/go/codec/binc.go
+++ /dev/null
@@ -1,1168 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"math"
-	"reflect"
-	"time"
-)
-
-const bincDoPrune = true // No longer needed. Needed before as C lib did not support pruning.
-
-// vd as low 4 bits (there are 16 slots)
-const (
-	bincVdSpecial byte = iota
-	bincVdPosInt
-	bincVdNegInt
-	bincVdFloat
-
-	bincVdString
-	bincVdByteArray
-	bincVdArray
-	bincVdMap
-
-	bincVdTimestamp
-	bincVdSmallInt
-	bincVdUnicodeOther
-	bincVdSymbol
-
-	bincVdDecimal
-	_               // open slot
-	_               // open slot
-	bincVdCustomExt = 0x0f
-)
-
-const (
-	bincSpNil byte = iota
-	bincSpFalse
-	bincSpTrue
-	bincSpNan
-	bincSpPosInf
-	bincSpNegInf
-	bincSpZeroFloat
-	bincSpZero
-	bincSpNegOne
-)
-
-const (
-	bincFlBin16 byte = iota
-	bincFlBin32
-	_ // bincFlBin32e
-	bincFlBin64
-	_ // bincFlBin64e
-	// others not currently supported
-)
-
-func bincdesc(vd, vs byte) string {
-	switch vd {
-	case bincVdSpecial:
-		switch vs {
-		case bincSpNil:
-			return "nil"
-		case bincSpFalse:
-			return "false"
-		case bincSpTrue:
-			return "true"
-		case bincSpNan, bincSpPosInf, bincSpNegInf, bincSpZeroFloat:
-			return "float"
-		case bincSpZero:
-			return "uint"
-		case bincSpNegOne:
-			return "int"
-		default:
-			return "unknown"
-		}
-	case bincVdSmallInt, bincVdPosInt:
-		return "uint"
-	case bincVdNegInt:
-		return "int"
-	case bincVdFloat:
-		return "float"
-	case bincVdSymbol:
-		return "string"
-	case bincVdString:
-		return "string"
-	case bincVdByteArray:
-		return "bytes"
-	case bincVdTimestamp:
-		return "time"
-	case bincVdCustomExt:
-		return "ext"
-	case bincVdArray:
-		return "array"
-	case bincVdMap:
-		return "map"
-	default:
-		return "unknown"
-	}
-}
-
-type bincEncDriver struct {
-	e *Encoder
-	h *BincHandle
-	w encWriter
-	m map[string]uint16 // symbols
-	b [16]byte          // scratch, used for encoding numbers - bigendian style
-	s uint16            // symbols sequencer
-	// c containerState
-	encDriverTrackContainerWriter
-	noBuiltInTypes
-	// encNoSeparator
-}
-
-func (e *bincEncDriver) EncodeNil() {
-	e.w.writen1(bincVdSpecial<<4 | bincSpNil)
-}
-
-func (e *bincEncDriver) EncodeTime(t time.Time) {
-	if t.IsZero() {
-		e.EncodeNil()
-	} else {
-		bs := bincEncodeTime(t)
-		e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
-		e.w.writeb(bs)
-	}
-}
-
-func (e *bincEncDriver) EncodeBool(b bool) {
-	if b {
-		e.w.writen1(bincVdSpecial<<4 | bincSpTrue)
-	} else {
-		e.w.writen1(bincVdSpecial<<4 | bincSpFalse)
-	}
-}
-
-func (e *bincEncDriver) EncodeFloat32(f float32) {
-	if f == 0 {
-		e.w.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
-		return
-	}
-	e.w.writen1(bincVdFloat<<4 | bincFlBin32)
-	bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f))
-}
-
-func (e *bincEncDriver) EncodeFloat64(f float64) {
-	if f == 0 {
-		e.w.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
-		return
-	}
-	bigen.PutUint64(e.b[:8], math.Float64bits(f))
-	if bincDoPrune {
-		i := 7
-		for ; i >= 0 && (e.b[i] == 0); i-- {
-		}
-		i++
-		if i <= 6 {
-			e.w.writen1(bincVdFloat<<4 | 0x8 | bincFlBin64)
-			e.w.writen1(byte(i))
-			e.w.writeb(e.b[:i])
-			return
-		}
-	}
-	e.w.writen1(bincVdFloat<<4 | bincFlBin64)
-	e.w.writeb(e.b[:8])
-}
-
-func (e *bincEncDriver) encIntegerPrune(bd byte, pos bool, v uint64, lim uint8) {
-	if lim == 4 {
-		bigen.PutUint32(e.b[:lim], uint32(v))
-	} else {
-		bigen.PutUint64(e.b[:lim], v)
-	}
-	if bincDoPrune {
-		i := pruneSignExt(e.b[:lim], pos)
-		e.w.writen1(bd | lim - 1 - byte(i))
-		e.w.writeb(e.b[i:lim])
-	} else {
-		e.w.writen1(bd | lim - 1)
-		e.w.writeb(e.b[:lim])
-	}
-}
-
-func (e *bincEncDriver) EncodeInt(v int64) {
-	const nbd byte = bincVdNegInt << 4
-	if v >= 0 {
-		e.encUint(bincVdPosInt<<4, true, uint64(v))
-	} else if v == -1 {
-		e.w.writen1(bincVdSpecial<<4 | bincSpNegOne)
-	} else {
-		e.encUint(bincVdNegInt<<4, false, uint64(-v))
-	}
-}
-
-func (e *bincEncDriver) EncodeUint(v uint64) {
-	e.encUint(bincVdPosInt<<4, true, v)
-}
-
-func (e *bincEncDriver) encUint(bd byte, pos bool, v uint64) {
-	if v == 0 {
-		e.w.writen1(bincVdSpecial<<4 | bincSpZero)
-	} else if pos && v >= 1 && v <= 16 {
-		e.w.writen1(bincVdSmallInt<<4 | byte(v-1))
-	} else if v <= math.MaxUint8 {
-		e.w.writen2(bd|0x0, byte(v))
-	} else if v <= math.MaxUint16 {
-		e.w.writen1(bd | 0x01)
-		bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v))
-	} else if v <= math.MaxUint32 {
-		e.encIntegerPrune(bd, pos, v, 4)
-	} else {
-		e.encIntegerPrune(bd, pos, v, 8)
-	}
-}
-
-func (e *bincEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, _ *Encoder) {
-	bs := ext.WriteExt(rv)
-	if bs == nil {
-		e.EncodeNil()
-		return
-	}
-	e.encodeExtPreamble(uint8(xtag), len(bs))
-	e.w.writeb(bs)
-}
-
-func (e *bincEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) {
-	e.encodeExtPreamble(uint8(re.Tag), len(re.Data))
-	e.w.writeb(re.Data)
-}
-
-func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) {
-	e.encLen(bincVdCustomExt<<4, uint64(length))
-	e.w.writen1(xtag)
-}
-
-func (e *bincEncDriver) WriteArrayStart(length int) {
-	e.encLen(bincVdArray<<4, uint64(length))
-	e.c = containerArrayStart
-}
-
-func (e *bincEncDriver) WriteMapStart(length int) {
-	e.encLen(bincVdMap<<4, uint64(length))
-	e.c = containerMapStart
-}
-
-func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
-	if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
-		e.EncodeSymbol(v)
-		return
-	}
-	l := uint64(len(v))
-	e.encBytesLen(c, l)
-	if l > 0 {
-		e.w.writestr(v)
-	}
-}
-
-func (e *bincEncDriver) EncodeSymbol(v string) {
-	// if WriteSymbolsNoRefs {
-	// 	e.encodeString(cUTF8, v)
-	// 	return
-	// }
-
-	//symbols only offer benefit when string length > 1.
-	//This is because strings with length 1 take only 2 bytes to store
-	//(bd with embedded length, and single byte for string val).
-
-	l := len(v)
-	if l == 0 {
-		e.encBytesLen(cUTF8, 0)
-		return
-	} else if l == 1 {
-		e.encBytesLen(cUTF8, 1)
-		e.w.writen1(v[0])
-		return
-	}
-	if e.m == nil {
-		e.m = make(map[string]uint16, 16)
-	}
-	ui, ok := e.m[v]
-	if ok {
-		if ui <= math.MaxUint8 {
-			e.w.writen2(bincVdSymbol<<4, byte(ui))
-		} else {
-			e.w.writen1(bincVdSymbol<<4 | 0x8)
-			bigenHelper{e.b[:2], e.w}.writeUint16(ui)
-		}
-	} else {
-		e.s++
-		ui = e.s
-		//ui = uint16(atomic.AddUint32(&e.s, 1))
-		e.m[v] = ui
-		var lenprec uint8
-		if l <= math.MaxUint8 {
-			// lenprec = 0
-		} else if l <= math.MaxUint16 {
-			lenprec = 1
-		} else if int64(l) <= math.MaxUint32 {
-			lenprec = 2
-		} else {
-			lenprec = 3
-		}
-		if ui <= math.MaxUint8 {
-			e.w.writen2(bincVdSymbol<<4|0x0|0x4|lenprec, byte(ui))
-		} else {
-			e.w.writen1(bincVdSymbol<<4 | 0x8 | 0x4 | lenprec)
-			bigenHelper{e.b[:2], e.w}.writeUint16(ui)
-		}
-		if lenprec == 0 {
-			e.w.writen1(byte(l))
-		} else if lenprec == 1 {
-			bigenHelper{e.b[:2], e.w}.writeUint16(uint16(l))
-		} else if lenprec == 2 {
-			bigenHelper{e.b[:4], e.w}.writeUint32(uint32(l))
-		} else {
-			bigenHelper{e.b[:8], e.w}.writeUint64(uint64(l))
-		}
-		e.w.writestr(v)
-	}
-}
-
-func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
-	if v == nil {
-		e.EncodeNil()
-		return
-	}
-	l := uint64(len(v))
-	e.encBytesLen(c, l)
-	if l > 0 {
-		e.w.writeb(v)
-	}
-}
-
-func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
-	//TODO: support bincUnicodeOther (for now, just use string or bytearray)
-	if c == cRAW {
-		e.encLen(bincVdByteArray<<4, length)
-	} else {
-		e.encLen(bincVdString<<4, length)
-	}
-}
-
-func (e *bincEncDriver) encLen(bd byte, l uint64) {
-	if l < 12 {
-		e.w.writen1(bd | uint8(l+4))
-	} else {
-		e.encLenNumber(bd, l)
-	}
-}
-
-func (e *bincEncDriver) encLenNumber(bd byte, v uint64) {
-	if v <= math.MaxUint8 {
-		e.w.writen2(bd, byte(v))
-	} else if v <= math.MaxUint16 {
-		e.w.writen1(bd | 0x01)
-		bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v))
-	} else if v <= math.MaxUint32 {
-		e.w.writen1(bd | 0x02)
-		bigenHelper{e.b[:4], e.w}.writeUint32(uint32(v))
-	} else {
-		e.w.writen1(bd | 0x03)
-		bigenHelper{e.b[:8], e.w}.writeUint64(uint64(v))
-	}
-}
-
-//------------------------------------
-
-type bincDecSymbol struct {
-	s string
-	b []byte
-	i uint16
-}
-
-type bincDecDriver struct {
-	decDriverNoopContainerReader
-	noBuiltInTypes
-
-	d      *Decoder
-	h      *BincHandle
-	r      decReader
-	br     bool // bytes reader
-	bdRead bool
-	bd     byte
-	vd     byte
-	vs     byte
-	_      [3]byte // padding
-	// linear searching on this slice is ok,
-	// because we typically expect < 32 symbols in each stream.
-	s []bincDecSymbol
-
-	// noStreamingCodec
-	// decNoSeparator
-
-	b [8 * 8]byte // scratch
-}
-
-func (d *bincDecDriver) readNextBd() {
-	d.bd = d.r.readn1()
-	d.vd = d.bd >> 4
-	d.vs = d.bd & 0x0f
-	d.bdRead = true
-}
-
-func (d *bincDecDriver) uncacheRead() {
-	if d.bdRead {
-		d.r.unreadn1()
-		d.bdRead = false
-	}
-}
-
-func (d *bincDecDriver) ContainerType() (vt valueType) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.vd == bincVdSpecial && d.vs == bincSpNil {
-		return valueTypeNil
-	} else if d.vd == bincVdByteArray {
-		return valueTypeBytes
-	} else if d.vd == bincVdString {
-		return valueTypeString
-	} else if d.vd == bincVdArray {
-		return valueTypeArray
-	} else if d.vd == bincVdMap {
-		return valueTypeMap
-	}
-	// else {
-	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
-	// }
-	return valueTypeUnset
-}
-
-func (d *bincDecDriver) TryDecodeAsNil() bool {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == bincVdSpecial<<4|bincSpNil {
-		d.bdRead = false
-		return true
-	}
-	return false
-}
-
-func (d *bincDecDriver) DecodeTime() (t time.Time) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == bincVdSpecial<<4|bincSpNil {
-		d.bdRead = false
-		return
-	}
-	if d.vd != bincVdTimestamp {
-		d.d.errorf("cannot decode time - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	t, err := bincDecodeTime(d.r.readx(int(d.vs)))
-	if err != nil {
-		panic(err)
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
-	if vs&0x8 == 0 {
-		d.r.readb(d.b[0:defaultLen])
-	} else {
-		l := d.r.readn1()
-		if l > 8 {
-			d.d.errorf("cannot read float - at most 8 bytes used to represent float - received %v bytes", l)
-			return
-		}
-		for i := l; i < 8; i++ {
-			d.b[i] = 0
-		}
-		d.r.readb(d.b[0:l])
-	}
-}
-
-func (d *bincDecDriver) decFloat() (f float64) {
-	//if true { f = math.Float64frombits(bigen.Uint64(d.r.readx(8))); break; }
-	if x := d.vs & 0x7; x == bincFlBin32 {
-		d.decFloatPre(d.vs, 4)
-		f = float64(math.Float32frombits(bigen.Uint32(d.b[0:4])))
-	} else if x == bincFlBin64 {
-		d.decFloatPre(d.vs, 8)
-		f = math.Float64frombits(bigen.Uint64(d.b[0:8]))
-	} else {
-		d.d.errorf("read float - only float32 and float64 are supported - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	return
-}
-
-func (d *bincDecDriver) decUint() (v uint64) {
-	// need to inline the code (interface conversion and type assertion expensive)
-	switch d.vs {
-	case 0:
-		v = uint64(d.r.readn1())
-	case 1:
-		d.r.readb(d.b[6:8])
-		v = uint64(bigen.Uint16(d.b[6:8]))
-	case 2:
-		d.b[4] = 0
-		d.r.readb(d.b[5:8])
-		v = uint64(bigen.Uint32(d.b[4:8]))
-	case 3:
-		d.r.readb(d.b[4:8])
-		v = uint64(bigen.Uint32(d.b[4:8]))
-	case 4, 5, 6:
-		lim := int(7 - d.vs)
-		d.r.readb(d.b[lim:8])
-		for i := 0; i < lim; i++ {
-			d.b[i] = 0
-		}
-		v = uint64(bigen.Uint64(d.b[:8]))
-	case 7:
-		d.r.readb(d.b[:8])
-		v = uint64(bigen.Uint64(d.b[:8]))
-	default:
-		d.d.errorf("unsigned integers with greater than 64 bits of precision not supported")
-		return
-	}
-	return
-}
-
-func (d *bincDecDriver) decCheckInteger() (ui uint64, neg bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	vd, vs := d.vd, d.vs
-	if vd == bincVdPosInt {
-		ui = d.decUint()
-	} else if vd == bincVdNegInt {
-		ui = d.decUint()
-		neg = true
-	} else if vd == bincVdSmallInt {
-		ui = uint64(d.vs) + 1
-	} else if vd == bincVdSpecial {
-		if vs == bincSpZero {
-			//i = 0
-		} else if vs == bincSpNegOne {
-			neg = true
-			ui = 1
-		} else {
-			d.d.errorf("integer decode fails - invalid special value from descriptor %x-%x/%s",
-				d.vd, d.vs, bincdesc(d.vd, d.vs))
-			return
-		}
-	} else {
-		d.d.errorf("integer can only be decoded from int/uint. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
-		return
-	}
-	return
-}
-
-func (d *bincDecDriver) DecodeInt64() (i int64) {
-	ui, neg := d.decCheckInteger()
-	i = chkOvf.SignedIntV(ui)
-	if neg {
-		i = -i
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) DecodeUint64() (ui uint64) {
-	ui, neg := d.decCheckInteger()
-	if neg {
-		d.d.errorf("assigning negative signed value to unsigned integer type")
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) DecodeFloat64() (f float64) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	vd, vs := d.vd, d.vs
-	if vd == bincVdSpecial {
-		d.bdRead = false
-		if vs == bincSpNan {
-			return math.NaN()
-		} else if vs == bincSpPosInf {
-			return math.Inf(1)
-		} else if vs == bincSpZeroFloat || vs == bincSpZero {
-			return
-		} else if vs == bincSpNegInf {
-			return math.Inf(-1)
-		} else {
-			d.d.errorf("float - invalid special value from descriptor %x-%x/%s",
-				d.vd, d.vs, bincdesc(d.vd, d.vs))
-			return
-		}
-	} else if vd == bincVdFloat {
-		f = d.decFloat()
-	} else {
-		f = float64(d.DecodeInt64())
-	}
-	d.bdRead = false
-	return
-}
-
-// bool can be decoded from bool only (single byte).
-func (d *bincDecDriver) DecodeBool() (b bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if bd := d.bd; bd == (bincVdSpecial | bincSpFalse) {
-		// b = false
-	} else if bd == (bincVdSpecial | bincSpTrue) {
-		b = true
-	} else {
-		d.d.errorf("bool - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) ReadMapStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.vd != bincVdMap {
-		d.d.errorf("map - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	length = d.decLen()
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) ReadArrayStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.vd != bincVdArray {
-		d.d.errorf("array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	length = d.decLen()
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) decLen() int {
-	if d.vs > 3 {
-		return int(d.vs - 4)
-	}
-	return int(d.decLenNumber())
-}
-
-func (d *bincDecDriver) decLenNumber() (v uint64) {
-	if x := d.vs; x == 0 {
-		v = uint64(d.r.readn1())
-	} else if x == 1 {
-		d.r.readb(d.b[6:8])
-		v = uint64(bigen.Uint16(d.b[6:8]))
-	} else if x == 2 {
-		d.r.readb(d.b[4:8])
-		v = uint64(bigen.Uint32(d.b[4:8]))
-	} else {
-		d.r.readb(d.b[:8])
-		v = bigen.Uint64(d.b[:8])
-	}
-	return
-}
-
-func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (
-	bs2 []byte, s string) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == bincVdSpecial<<4|bincSpNil {
-		d.bdRead = false
-		return
-	}
-	var slen = -1
-	// var ok bool
-	switch d.vd {
-	case bincVdString, bincVdByteArray:
-		slen = d.decLen()
-		if zerocopy {
-			if d.br {
-				bs2 = d.r.readx(slen)
-			} else if len(bs) == 0 {
-				bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, d.b[:])
-			} else {
-				bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, bs)
-			}
-		} else {
-			bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, bs)
-		}
-		if withString {
-			s = string(bs2)
-		}
-	case bincVdSymbol:
-		// zerocopy doesn't apply for symbols,
-		// as the values must be stored in a table for later use.
-		//
-		//from vs: extract numSymbolBytes, containsStringVal, strLenPrecision,
-		//extract symbol
-		//if containsStringVal, read it and put in map
-		//else look in map for string value
-		var symbol uint16
-		vs := d.vs
-		if vs&0x8 == 0 {
-			symbol = uint16(d.r.readn1())
-		} else {
-			symbol = uint16(bigen.Uint16(d.r.readx(2)))
-		}
-		if d.s == nil {
-			d.s = make([]bincDecSymbol, 0, 16)
-		}
-
-		if vs&0x4 == 0 {
-			for i := range d.s {
-				j := &d.s[i]
-				if j.i == symbol {
-					bs2 = j.b
-					if withString {
-						if j.s == "" && bs2 != nil {
-							j.s = string(bs2)
-						}
-						s = j.s
-					}
-					break
-				}
-			}
-		} else {
-			switch vs & 0x3 {
-			case 0:
-				slen = int(d.r.readn1())
-			case 1:
-				slen = int(bigen.Uint16(d.r.readx(2)))
-			case 2:
-				slen = int(bigen.Uint32(d.r.readx(4)))
-			case 3:
-				slen = int(bigen.Uint64(d.r.readx(8)))
-			}
-			// since using symbols, do not store any part of
-			// the parameter bs in the map, as it might be a shared buffer.
-			// bs2 = decByteSlice(d.r, slen, bs)
-			bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, nil)
-			if withString {
-				s = string(bs2)
-			}
-			d.s = append(d.s, bincDecSymbol{i: symbol, s: s, b: bs2})
-		}
-	default:
-		d.d.errorf("string/bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) DecodeString() (s string) {
-	// DecodeBytes does not accommodate symbols, whose impl stores string version in map.
-	// Use decStringAndBytes directly.
-	// return string(d.DecodeBytes(d.b[:], true, true))
-	_, s = d.decStringAndBytes(d.b[:], true, true)
-	return
-}
-
-func (d *bincDecDriver) DecodeStringAsBytes() (s []byte) {
-	s, _ = d.decStringAndBytes(d.b[:], false, true)
-	return
-}
-
-func (d *bincDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == bincVdSpecial<<4|bincSpNil {
-		d.bdRead = false
-		return nil
-	}
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	if d.vd == bincVdArray {
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	}
-	var clen int
-	if d.vd == bincVdString || d.vd == bincVdByteArray {
-		clen = d.decLen()
-	} else {
-		d.d.errorf("bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	d.bdRead = false
-	if zerocopy {
-		if d.br {
-			return d.r.readx(clen)
-		} else if len(bs) == 0 {
-			bs = d.b[:]
-		}
-	}
-	return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
-}
-
-func (d *bincDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
-	if xtag > 0xff {
-		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
-		return
-	}
-	realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
-	realxtag = uint64(realxtag1)
-	if ext == nil {
-		re := rv.(*RawExt)
-		re.Tag = realxtag
-		re.Data = detachZeroCopyBytes(d.br, re.Data, xbs)
-	} else {
-		ext.ReadExt(rv, xbs)
-	}
-	return
-}
-
-func (d *bincDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.vd == bincVdCustomExt {
-		l := d.decLen()
-		xtag = d.r.readn1()
-		if verifyTag && xtag != tag {
-			d.d.errorf("wrong extension tag - got %b, expecting: %v", xtag, tag)
-			return
-		}
-		xbs = d.r.readx(l)
-	} else if d.vd == bincVdByteArray {
-		xbs = d.DecodeBytes(nil, true)
-	} else {
-		d.d.errorf("ext - expecting extensions or byte array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *bincDecDriver) DecodeNaked() {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-
-	n := d.d.n
-	var decodeFurther bool
-
-	switch d.vd {
-	case bincVdSpecial:
-		switch d.vs {
-		case bincSpNil:
-			n.v = valueTypeNil
-		case bincSpFalse:
-			n.v = valueTypeBool
-			n.b = false
-		case bincSpTrue:
-			n.v = valueTypeBool
-			n.b = true
-		case bincSpNan:
-			n.v = valueTypeFloat
-			n.f = math.NaN()
-		case bincSpPosInf:
-			n.v = valueTypeFloat
-			n.f = math.Inf(1)
-		case bincSpNegInf:
-			n.v = valueTypeFloat
-			n.f = math.Inf(-1)
-		case bincSpZeroFloat:
-			n.v = valueTypeFloat
-			n.f = float64(0)
-		case bincSpZero:
-			n.v = valueTypeUint
-			n.u = uint64(0) // int8(0)
-		case bincSpNegOne:
-			n.v = valueTypeInt
-			n.i = int64(-1) // int8(-1)
-		default:
-			d.d.errorf("cannot infer value - unrecognized special value from descriptor %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs))
-		}
-	case bincVdSmallInt:
-		n.v = valueTypeUint
-		n.u = uint64(int8(d.vs)) + 1 // int8(d.vs) + 1
-	case bincVdPosInt:
-		n.v = valueTypeUint
-		n.u = d.decUint()
-	case bincVdNegInt:
-		n.v = valueTypeInt
-		n.i = -(int64(d.decUint()))
-	case bincVdFloat:
-		n.v = valueTypeFloat
-		n.f = d.decFloat()
-	case bincVdSymbol:
-		n.v = valueTypeSymbol
-		n.s = d.DecodeString()
-	case bincVdString:
-		n.v = valueTypeString
-		n.s = d.DecodeString()
-	case bincVdByteArray:
-		n.v = valueTypeBytes
-		n.l = d.DecodeBytes(nil, false)
-	case bincVdTimestamp:
-		n.v = valueTypeTime
-		tt, err := bincDecodeTime(d.r.readx(int(d.vs)))
-		if err != nil {
-			panic(err)
-		}
-		n.t = tt
-	case bincVdCustomExt:
-		n.v = valueTypeExt
-		l := d.decLen()
-		n.u = uint64(d.r.readn1())
-		n.l = d.r.readx(l)
-	case bincVdArray:
-		n.v = valueTypeArray
-		decodeFurther = true
-	case bincVdMap:
-		n.v = valueTypeMap
-		decodeFurther = true
-	default:
-		d.d.errorf("cannot infer value - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
-	}
-
-	if !decodeFurther {
-		d.bdRead = false
-	}
-	if n.v == valueTypeUint && d.h.SignedInteger {
-		n.v = valueTypeInt
-		n.i = int64(n.u)
-	}
-	return
-}
-
-//------------------------------------
-
-//BincHandle is a Handle for the Binc Schema-Free Encoding Format
-//defined at https://github.com/ugorji/binc .
-//
-//BincHandle currently supports all Binc features with the following EXCEPTIONS:
-//  - only integers up to 64 bits of precision are supported.
-//    big integers are unsupported.
-//  - Only IEEE 754 binary32 and binary64 floats are supported (ie Go float32 and float64 types).
-//    extended precision and decimal IEEE 754 floats are unsupported.
-//  - Only UTF-8 strings supported.
-//    Unicode_Other Binc types (UTF16, UTF32) are currently unsupported.
-//
-//Note that these EXCEPTIONS are temporary and full support is possible and may happen soon.
-type BincHandle struct {
-	BasicHandle
-	binaryEncodingType
-	noElemSeparators
-
-	// AsSymbols defines what should be encoded as symbols.
-	//
-	// Encoding as symbols can reduce the encoded size significantly.
-	//
-	// However, during decoding, each string to be encoded as a symbol must
-	// be checked to see if it has been seen before. Consequently, encoding time
-	// will increase if using symbols, because string comparisons has a clear cost.
-	//
-	// Values:
-	// - 0: default: library uses best judgement
-	// - 1: use symbols
-	// - 2: do not use symbols
-	AsSymbols uint8
-
-	// AsSymbols: may later on introduce more options ...
-	// - m: map keys
-	// - s: struct fields
-	// - n: none
-	// - a: all: same as m, s, ...
-
-	// _ [1]uint64 // padding
-}
-
-// Name returns the name of the handle: binc
-func (h *BincHandle) Name() string { return "binc" }
-
-// SetBytesExt sets an extension
-func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
-}
-
-func (h *BincHandle) newEncDriver(e *Encoder) encDriver {
-	return &bincEncDriver{e: e, h: h, w: e.w}
-}
-
-func (h *BincHandle) newDecDriver(d *Decoder) decDriver {
-	return &bincDecDriver{d: d, h: h, r: d.r, br: d.bytes}
-}
-
-func (e *bincEncDriver) reset() {
-	e.w = e.e.w
-	e.s = 0
-	e.c = 0
-	e.m = nil
-}
-
-func (d *bincDecDriver) reset() {
-	d.r, d.br = d.d.r, d.d.bytes
-	d.s = nil
-	d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0
-}
-
-// var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
-
-// EncodeTime encodes a time.Time as a []byte, including
-// information on the instant in time and UTC offset.
-//
-// Format Description
-//
-//   A timestamp is composed of 3 components:
-//
-//   - secs: signed integer representing seconds since unix epoch
-//   - nsces: unsigned integer representing fractional seconds as a
-//     nanosecond offset within secs, in the range 0 <= nsecs < 1e9
-//   - tz: signed integer representing timezone offset in minutes east of UTC,
-//     and a dst (daylight savings time) flag
-//
-//   When encoding a timestamp, the first byte is the descriptor, which
-//   defines which components are encoded and how many bytes are used to
-//   encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
-//   is not encoded in the byte array explicitly*.
-//
-//       Descriptor 8 bits are of the form `A B C DDD EE`:
-//           A:   Is secs component encoded? 1 = true
-//           B:   Is nsecs component encoded? 1 = true
-//           C:   Is tz component encoded? 1 = true
-//           DDD: Number of extra bytes for secs (range 0-7).
-//                If A = 1, secs encoded in DDD+1 bytes.
-//                    If A = 0, secs is not encoded, and is assumed to be 0.
-//                    If A = 1, then we need at least 1 byte to encode secs.
-//                    DDD says the number of extra bytes beyond that 1.
-//                    E.g. if DDD=0, then secs is represented in 1 byte.
-//                         if DDD=2, then secs is represented in 3 bytes.
-//           EE:  Number of extra bytes for nsecs (range 0-3).
-//                If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
-//
-//   Following the descriptor bytes, subsequent bytes are:
-//
-//       secs component encoded in `DDD + 1` bytes (if A == 1)
-//       nsecs component encoded in `EE + 1` bytes (if B == 1)
-//       tz component encoded in 2 bytes (if C == 1)
-//
-//   secs and nsecs components are integers encoded in a BigEndian
-//   2-complement encoding format.
-//
-//   tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
-//   Least significant bit 0 are described below:
-//
-//       Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
-//       Bit 15 = have\_dst: set to 1 if we set the dst flag.
-//       Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
-//       Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
-//
-func bincEncodeTime(t time.Time) []byte {
-	//t := rv.Interface().(time.Time)
-	tsecs, tnsecs := t.Unix(), t.Nanosecond()
-	var (
-		bd   byte
-		btmp [8]byte
-		bs   [16]byte
-		i    int = 1
-	)
-	l := t.Location()
-	if l == time.UTC {
-		l = nil
-	}
-	if tsecs != 0 {
-		bd = bd | 0x80
-		bigen.PutUint64(btmp[:], uint64(tsecs))
-		f := pruneSignExt(btmp[:], tsecs >= 0)
-		bd = bd | (byte(7-f) << 2)
-		copy(bs[i:], btmp[f:])
-		i = i + (8 - f)
-	}
-	if tnsecs != 0 {
-		bd = bd | 0x40
-		bigen.PutUint32(btmp[:4], uint32(tnsecs))
-		f := pruneSignExt(btmp[:4], true)
-		bd = bd | byte(3-f)
-		copy(bs[i:], btmp[f:4])
-		i = i + (4 - f)
-	}
-	if l != nil {
-		bd = bd | 0x20
-		// Note that Go Libs do not give access to dst flag.
-		_, zoneOffset := t.Zone()
-		//zoneName, zoneOffset := t.Zone()
-		zoneOffset /= 60
-		z := uint16(zoneOffset)
-		bigen.PutUint16(btmp[:2], z)
-		// clear dst flags
-		bs[i] = btmp[0] & 0x3f
-		bs[i+1] = btmp[1]
-		i = i + 2
-	}
-	bs[0] = bd
-	return bs[0:i]
-}
-
-// bincDecodeTime decodes a []byte into a time.Time.
-func bincDecodeTime(bs []byte) (tt time.Time, err error) {
-	bd := bs[0]
-	var (
-		tsec  int64
-		tnsec uint32
-		tz    uint16
-		i     byte = 1
-		i2    byte
-		n     byte
-	)
-	if bd&(1<<7) != 0 {
-		var btmp [8]byte
-		n = ((bd >> 2) & 0x7) + 1
-		i2 = i + n
-		copy(btmp[8-n:], bs[i:i2])
-		//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
-		if bs[i]&(1<<7) != 0 {
-			copy(btmp[0:8-n], bsAll0xff)
-			//for j,k := byte(0), 8-n; j < k; j++ {	btmp[j] = 0xff }
-		}
-		i = i2
-		tsec = int64(bigen.Uint64(btmp[:]))
-	}
-	if bd&(1<<6) != 0 {
-		var btmp [4]byte
-		n = (bd & 0x3) + 1
-		i2 = i + n
-		copy(btmp[4-n:], bs[i:i2])
-		i = i2
-		tnsec = bigen.Uint32(btmp[:])
-	}
-	if bd&(1<<5) == 0 {
-		tt = time.Unix(tsec, int64(tnsec)).UTC()
-		return
-	}
-	// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
-	// However, we need name here, so it can be shown when time is printed.
-	// Zone name is in form: UTC-08:00.
-	// Note that Go Libs do not give access to dst flag, so we ignore dst bits
-
-	i2 = i + 2
-	tz = bigen.Uint16(bs[i:i2])
-	// i = i2
-	// sign extend sign bit into top 2 MSB (which were dst bits):
-	if tz&(1<<13) == 0 { // positive
-		tz = tz & 0x3fff //clear 2 MSBs: dst bits
-	} else { // negative
-		tz = tz | 0xc000 //set 2 MSBs: dst bits
-	}
-	tzint := int16(tz)
-	if tzint == 0 {
-		tt = time.Unix(tsec, int64(tnsec)).UTC()
-	} else {
-		// For Go Time, do not use a descriptive timezone.
-		// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
-		// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
-		// var zoneName = timeLocUTCName(tzint)
-		tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
-	}
-	return
-}
-
-var _ decDriver = (*bincDecDriver)(nil)
-var _ encDriver = (*bincEncDriver)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/cbor.go b/vendor/github.com/ugorji/go/codec/cbor.go
deleted file mode 100644
index 7633c04..0000000
--- a/vendor/github.com/ugorji/go/codec/cbor.go
+++ /dev/null
@@ -1,756 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"math"
-	"reflect"
-	"time"
-)
-
-const (
-	cborMajorUint byte = iota
-	cborMajorNegInt
-	cborMajorBytes
-	cborMajorText
-	cborMajorArray
-	cborMajorMap
-	cborMajorTag
-	cborMajorOther
-)
-
-const (
-	cborBdFalse byte = 0xf4 + iota
-	cborBdTrue
-	cborBdNil
-	cborBdUndefined
-	cborBdExt
-	cborBdFloat16
-	cborBdFloat32
-	cborBdFloat64
-)
-
-const (
-	cborBdIndefiniteBytes  byte = 0x5f
-	cborBdIndefiniteString      = 0x7f
-	cborBdIndefiniteArray       = 0x9f
-	cborBdIndefiniteMap         = 0xbf
-	cborBdBreak                 = 0xff
-)
-
-// These define some in-stream descriptors for
-// manual encoding e.g. when doing explicit indefinite-length
-const (
-	CborStreamBytes  byte = 0x5f
-	CborStreamString      = 0x7f
-	CborStreamArray       = 0x9f
-	CborStreamMap         = 0xbf
-	CborStreamBreak       = 0xff
-)
-
-const (
-	cborBaseUint   byte = 0x00
-	cborBaseNegInt      = 0x20
-	cborBaseBytes       = 0x40
-	cborBaseString      = 0x60
-	cborBaseArray       = 0x80
-	cborBaseMap         = 0xa0
-	cborBaseTag         = 0xc0
-	cborBaseSimple      = 0xe0
-)
-
-func cbordesc(bd byte) string {
-	switch bd {
-	case cborBdNil:
-		return "nil"
-	case cborBdFalse:
-		return "false"
-	case cborBdTrue:
-		return "true"
-	case cborBdFloat16, cborBdFloat32, cborBdFloat64:
-		return "float"
-	case cborBdIndefiniteBytes:
-		return "bytes*"
-	case cborBdIndefiniteString:
-		return "string*"
-	case cborBdIndefiniteArray:
-		return "array*"
-	case cborBdIndefiniteMap:
-		return "map*"
-	default:
-		switch {
-		case bd >= cborBaseUint && bd < cborBaseNegInt:
-			return "(u)int"
-		case bd >= cborBaseNegInt && bd < cborBaseBytes:
-			return "int"
-		case bd >= cborBaseBytes && bd < cborBaseString:
-			return "bytes"
-		case bd >= cborBaseString && bd < cborBaseArray:
-			return "string"
-		case bd >= cborBaseArray && bd < cborBaseMap:
-			return "array"
-		case bd >= cborBaseMap && bd < cborBaseTag:
-			return "map"
-		case bd >= cborBaseTag && bd < cborBaseSimple:
-			return "ext"
-		default:
-			return "unknown"
-		}
-	}
-}
-
-// -------------------
-
-type cborEncDriver struct {
-	noBuiltInTypes
-	encDriverNoopContainerWriter
-	// encNoSeparator
-	e *Encoder
-	w encWriter
-	h *CborHandle
-	x [8]byte
-	_ [3]uint64 // padding
-}
-
-func (e *cborEncDriver) EncodeNil() {
-	e.w.writen1(cborBdNil)
-}
-
-func (e *cborEncDriver) EncodeBool(b bool) {
-	if b {
-		e.w.writen1(cborBdTrue)
-	} else {
-		e.w.writen1(cborBdFalse)
-	}
-}
-
-func (e *cborEncDriver) EncodeFloat32(f float32) {
-	e.w.writen1(cborBdFloat32)
-	bigenHelper{e.x[:4], e.w}.writeUint32(math.Float32bits(f))
-}
-
-func (e *cborEncDriver) EncodeFloat64(f float64) {
-	e.w.writen1(cborBdFloat64)
-	bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
-}
-
-func (e *cborEncDriver) encUint(v uint64, bd byte) {
-	if v <= 0x17 {
-		e.w.writen1(byte(v) + bd)
-	} else if v <= math.MaxUint8 {
-		e.w.writen2(bd+0x18, uint8(v))
-	} else if v <= math.MaxUint16 {
-		e.w.writen1(bd + 0x19)
-		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(v))
-	} else if v <= math.MaxUint32 {
-		e.w.writen1(bd + 0x1a)
-		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(v))
-	} else { // if v <= math.MaxUint64 {
-		e.w.writen1(bd + 0x1b)
-		bigenHelper{e.x[:8], e.w}.writeUint64(v)
-	}
-}
-
-func (e *cborEncDriver) EncodeInt(v int64) {
-	if v < 0 {
-		e.encUint(uint64(-1-v), cborBaseNegInt)
-	} else {
-		e.encUint(uint64(v), cborBaseUint)
-	}
-}
-
-func (e *cborEncDriver) EncodeUint(v uint64) {
-	e.encUint(v, cborBaseUint)
-}
-
-func (e *cborEncDriver) encLen(bd byte, length int) {
-	e.encUint(uint64(length), bd)
-}
-
-func (e *cborEncDriver) EncodeTime(t time.Time) {
-	if t.IsZero() {
-		e.EncodeNil()
-	} else if e.h.TimeRFC3339 {
-		e.encUint(0, cborBaseTag)
-		e.EncodeString(cUTF8, t.Format(time.RFC3339Nano))
-	} else {
-		e.encUint(1, cborBaseTag)
-		t = t.UTC().Round(time.Microsecond)
-		sec, nsec := t.Unix(), uint64(t.Nanosecond())
-		if nsec == 0 {
-			e.EncodeInt(sec)
-		} else {
-			e.EncodeFloat64(float64(sec) + float64(nsec)/1e9)
-		}
-	}
-}
-
-func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
-	e.encUint(uint64(xtag), cborBaseTag)
-	if v := ext.ConvertExt(rv); v == nil {
-		e.EncodeNil()
-	} else {
-		en.encode(v)
-	}
-}
-
-func (e *cborEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
-	e.encUint(uint64(re.Tag), cborBaseTag)
-	if false && re.Data != nil {
-		en.encode(re.Data)
-	} else if re.Value != nil {
-		en.encode(re.Value)
-	} else {
-		e.EncodeNil()
-	}
-}
-
-func (e *cborEncDriver) WriteArrayStart(length int) {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdIndefiniteArray)
-	} else {
-		e.encLen(cborBaseArray, length)
-	}
-}
-
-func (e *cborEncDriver) WriteMapStart(length int) {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdIndefiniteMap)
-	} else {
-		e.encLen(cborBaseMap, length)
-	}
-}
-
-func (e *cborEncDriver) WriteMapEnd() {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdBreak)
-	}
-}
-
-func (e *cborEncDriver) WriteArrayEnd() {
-	if e.h.IndefiniteLength {
-		e.w.writen1(cborBdBreak)
-	}
-}
-
-func (e *cborEncDriver) EncodeString(c charEncoding, v string) {
-	e.encStringBytesS(cborBaseString, v)
-}
-
-func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
-	if v == nil {
-		e.EncodeNil()
-	} else if c == cRAW {
-		e.encStringBytesS(cborBaseBytes, stringView(v))
-	} else {
-		e.encStringBytesS(cborBaseString, stringView(v))
-	}
-}
-
-func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
-	if e.h.IndefiniteLength {
-		if bb == cborBaseBytes {
-			e.w.writen1(cborBdIndefiniteBytes)
-		} else {
-			e.w.writen1(cborBdIndefiniteString)
-		}
-		blen := len(v) / 4
-		if blen == 0 {
-			blen = 64
-		} else if blen > 1024 {
-			blen = 1024
-		}
-		for i := 0; i < len(v); {
-			var v2 string
-			i2 := i + blen
-			if i2 < len(v) {
-				v2 = v[i:i2]
-			} else {
-				v2 = v[i:]
-			}
-			e.encLen(bb, len(v2))
-			e.w.writestr(v2)
-			i = i2
-		}
-		e.w.writen1(cborBdBreak)
-	} else {
-		e.encLen(bb, len(v))
-		e.w.writestr(v)
-	}
-}
-
-// ----------------------
-
-type cborDecDriver struct {
-	d *Decoder
-	h *CborHandle
-	r decReader
-	// b      [scratchByteArrayLen]byte
-	br     bool // bytes reader
-	bdRead bool
-	bd     byte
-	noBuiltInTypes
-	// decNoSeparator
-	decDriverNoopContainerReader
-	_ [3]uint64 // padding
-}
-
-func (d *cborDecDriver) readNextBd() {
-	d.bd = d.r.readn1()
-	d.bdRead = true
-}
-
-func (d *cborDecDriver) uncacheRead() {
-	if d.bdRead {
-		d.r.unreadn1()
-		d.bdRead = false
-	}
-}
-
-func (d *cborDecDriver) ContainerType() (vt valueType) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == cborBdNil {
-		return valueTypeNil
-	} else if d.bd == cborBdIndefiniteBytes || (d.bd >= cborBaseBytes && d.bd < cborBaseString) {
-		return valueTypeBytes
-	} else if d.bd == cborBdIndefiniteString || (d.bd >= cborBaseString && d.bd < cborBaseArray) {
-		return valueTypeString
-	} else if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
-		return valueTypeArray
-	} else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) {
-		return valueTypeMap
-	}
-	// else {
-	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
-	// }
-	return valueTypeUnset
-}
-
-func (d *cborDecDriver) TryDecodeAsNil() bool {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	// treat Nil and Undefined as nil values
-	if d.bd == cborBdNil || d.bd == cborBdUndefined {
-		d.bdRead = false
-		return true
-	}
-	return false
-}
-
-func (d *cborDecDriver) CheckBreak() bool {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == cborBdBreak {
-		d.bdRead = false
-		return true
-	}
-	return false
-}
-
-func (d *cborDecDriver) decUint() (ui uint64) {
-	v := d.bd & 0x1f
-	if v <= 0x17 {
-		ui = uint64(v)
-	} else {
-		if v == 0x18 {
-			ui = uint64(d.r.readn1())
-		} else if v == 0x19 {
-			ui = uint64(bigen.Uint16(d.r.readx(2)))
-		} else if v == 0x1a {
-			ui = uint64(bigen.Uint32(d.r.readx(4)))
-		} else if v == 0x1b {
-			ui = uint64(bigen.Uint64(d.r.readx(8)))
-		} else {
-			d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd))
-			return
-		}
-	}
-	return
-}
-
-func (d *cborDecDriver) decCheckInteger() (neg bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	major := d.bd >> 5
-	if major == cborMajorUint {
-	} else if major == cborMajorNegInt {
-		neg = true
-	} else {
-		d.d.errorf("not an integer - invalid major %v from descriptor %x/%s", major, d.bd, cbordesc(d.bd))
-		return
-	}
-	return
-}
-
-func (d *cborDecDriver) DecodeInt64() (i int64) {
-	neg := d.decCheckInteger()
-	ui := d.decUint()
-	// check if this number can be converted to an int without overflow
-	if neg {
-		i = -(chkOvf.SignedIntV(ui + 1))
-	} else {
-		i = chkOvf.SignedIntV(ui)
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *cborDecDriver) DecodeUint64() (ui uint64) {
-	if d.decCheckInteger() {
-		d.d.errorf("assigning negative signed value to unsigned type")
-		return
-	}
-	ui = d.decUint()
-	d.bdRead = false
-	return
-}
-
-func (d *cborDecDriver) DecodeFloat64() (f float64) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if bd := d.bd; bd == cborBdFloat16 {
-		f = float64(math.Float32frombits(halfFloatToFloatBits(bigen.Uint16(d.r.readx(2)))))
-	} else if bd == cborBdFloat32 {
-		f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
-	} else if bd == cborBdFloat64 {
-		f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
-	} else if bd >= cborBaseUint && bd < cborBaseBytes {
-		f = float64(d.DecodeInt64())
-	} else {
-		d.d.errorf("float only valid from float16/32/64 - invalid descriptor %x/%s", bd, cbordesc(bd))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-// bool can be decoded from bool only (single byte).
-func (d *cborDecDriver) DecodeBool() (b bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if bd := d.bd; bd == cborBdTrue {
-		b = true
-	} else if bd == cborBdFalse {
-	} else {
-		d.d.errorf("not bool - %s %x/%s", msgBadDesc, d.bd, cbordesc(d.bd))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *cborDecDriver) ReadMapStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	d.bdRead = false
-	if d.bd == cborBdIndefiniteMap {
-		return -1
-	}
-	return d.decLen()
-}
-
-func (d *cborDecDriver) ReadArrayStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	d.bdRead = false
-	if d.bd == cborBdIndefiniteArray {
-		return -1
-	}
-	return d.decLen()
-}
-
-func (d *cborDecDriver) decLen() int {
-	return int(d.decUint())
-}
-
-func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
-	d.bdRead = false
-	for {
-		if d.CheckBreak() {
-			break
-		}
-		if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorText {
-			d.d.errorf("expect bytes/string major type in indefinite string/bytes;"+
-				" got major %v from descriptor %x/%x", major, d.bd, cbordesc(d.bd))
-			return nil
-		}
-		n := d.decLen()
-		oldLen := len(bs)
-		newLen := oldLen + n
-		if newLen > cap(bs) {
-			bs2 := make([]byte, newLen, 2*cap(bs)+n)
-			copy(bs2, bs)
-			bs = bs2
-		} else {
-			bs = bs[:newLen]
-		}
-		d.r.readb(bs[oldLen:newLen])
-		// bs = append(bs, d.r.readn()...)
-		d.bdRead = false
-	}
-	d.bdRead = false
-	return bs
-}
-
-func (d *cborDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == cborBdNil || d.bd == cborBdUndefined {
-		d.bdRead = false
-		return nil
-	}
-	if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
-		d.bdRead = false
-		if bs == nil {
-			if zerocopy {
-				return d.decAppendIndefiniteBytes(d.d.b[:0])
-			}
-			return d.decAppendIndefiniteBytes(zeroByteSlice)
-		}
-		return d.decAppendIndefiniteBytes(bs[:0])
-	}
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	}
-	clen := d.decLen()
-	d.bdRead = false
-	if zerocopy {
-		if d.br {
-			return d.r.readx(clen)
-		} else if len(bs) == 0 {
-			bs = d.d.b[:]
-		}
-	}
-	return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
-}
-
-func (d *cborDecDriver) DecodeString() (s string) {
-	return string(d.DecodeBytes(d.d.b[:], true))
-}
-
-func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
-	return d.DecodeBytes(d.d.b[:], true)
-}
-
-func (d *cborDecDriver) DecodeTime() (t time.Time) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == cborBdNil || d.bd == cborBdUndefined {
-		d.bdRead = false
-		return
-	}
-	xtag := d.decUint()
-	d.bdRead = false
-	return d.decodeTime(xtag)
-}
-
-func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	switch xtag {
-	case 0:
-		var err error
-		if t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes())); err != nil {
-			d.d.errorv(err)
-		}
-	case 1:
-		// decode an int64 or a float, and infer time.Time from there.
-		// for floats, round to microseconds, as that is what is guaranteed to fit well.
-		switch {
-		case d.bd == cborBdFloat16, d.bd == cborBdFloat32:
-			f1, f2 := math.Modf(d.DecodeFloat64())
-			t = time.Unix(int64(f1), int64(f2*1e9))
-		case d.bd == cborBdFloat64:
-			f1, f2 := math.Modf(d.DecodeFloat64())
-			t = time.Unix(int64(f1), int64(f2*1e9))
-		case d.bd >= cborBaseUint && d.bd < cborBaseNegInt,
-			d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
-			t = time.Unix(d.DecodeInt64(), 0)
-		default:
-			d.d.errorf("time.Time can only be decoded from a number (or RFC3339 string)")
-		}
-	default:
-		d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag)
-	}
-	t = t.UTC().Round(time.Microsecond)
-	return
-}
-
-func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	u := d.decUint()
-	d.bdRead = false
-	realxtag = u
-	if ext == nil {
-		re := rv.(*RawExt)
-		re.Tag = realxtag
-		d.d.decode(&re.Value)
-	} else if xtag != realxtag {
-		d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", realxtag, xtag)
-		return
-	} else {
-		var v interface{}
-		d.d.decode(&v)
-		ext.UpdateExt(rv, v)
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *cborDecDriver) DecodeNaked() {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-
-	n := d.d.n
-	var decodeFurther bool
-
-	switch d.bd {
-	case cborBdNil:
-		n.v = valueTypeNil
-	case cborBdFalse:
-		n.v = valueTypeBool
-		n.b = false
-	case cborBdTrue:
-		n.v = valueTypeBool
-		n.b = true
-	case cborBdFloat16, cborBdFloat32, cborBdFloat64:
-		n.v = valueTypeFloat
-		n.f = d.DecodeFloat64()
-	case cborBdIndefiniteBytes:
-		n.v = valueTypeBytes
-		n.l = d.DecodeBytes(nil, false)
-	case cborBdIndefiniteString:
-		n.v = valueTypeString
-		n.s = d.DecodeString()
-	case cborBdIndefiniteArray:
-		n.v = valueTypeArray
-		decodeFurther = true
-	case cborBdIndefiniteMap:
-		n.v = valueTypeMap
-		decodeFurther = true
-	default:
-		switch {
-		case d.bd >= cborBaseUint && d.bd < cborBaseNegInt:
-			if d.h.SignedInteger {
-				n.v = valueTypeInt
-				n.i = d.DecodeInt64()
-			} else {
-				n.v = valueTypeUint
-				n.u = d.DecodeUint64()
-			}
-		case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
-			n.v = valueTypeInt
-			n.i = d.DecodeInt64()
-		case d.bd >= cborBaseBytes && d.bd < cborBaseString:
-			n.v = valueTypeBytes
-			n.l = d.DecodeBytes(nil, false)
-		case d.bd >= cborBaseString && d.bd < cborBaseArray:
-			n.v = valueTypeString
-			n.s = d.DecodeString()
-		case d.bd >= cborBaseArray && d.bd < cborBaseMap:
-			n.v = valueTypeArray
-			decodeFurther = true
-		case d.bd >= cborBaseMap && d.bd < cborBaseTag:
-			n.v = valueTypeMap
-			decodeFurther = true
-		case d.bd >= cborBaseTag && d.bd < cborBaseSimple:
-			n.v = valueTypeExt
-			n.u = d.decUint()
-			n.l = nil
-			if n.u == 0 || n.u == 1 {
-				d.bdRead = false
-				n.v = valueTypeTime
-				n.t = d.decodeTime(n.u)
-			}
-			// d.bdRead = false
-			// d.d.decode(&re.Value) // handled by decode itself.
-			// decodeFurther = true
-		default:
-			d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd)
-			return
-		}
-	}
-
-	if !decodeFurther {
-		d.bdRead = false
-	}
-	return
-}
-
-// -------------------------
-
-// CborHandle is a Handle for the CBOR encoding format,
-// defined at http://tools.ietf.org/html/rfc7049 and documented further at http://cbor.io .
-//
-// CBOR is comprehensively supported, including support for:
-//   - indefinite-length arrays/maps/bytes/strings
-//   - (extension) tags in range 0..0xffff (0 .. 65535)
-//   - half, single and double-precision floats
-//   - all numbers (1, 2, 4 and 8-byte signed and unsigned integers)
-//   - nil, true, false, ...
-//   - arrays and maps, bytes and text strings
-//
-// None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
-// Users can implement them as needed (using SetExt), including spec-documented ones:
-//   - timestamp, BigNum, BigFloat, Decimals,
-//   - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
-type CborHandle struct {
-	binaryEncodingType
-	noElemSeparators
-	BasicHandle
-
-	// IndefiniteLength=true, means that we encode using indefinitelength
-	IndefiniteLength bool
-
-	// TimeRFC3339 says to encode time.Time using RFC3339 format.
-	// If unset, we encode time.Time using seconds past epoch.
-	TimeRFC3339 bool
-
-	// _ [1]uint64 // padding
-}
-
-// Name returns the name of the handle: cbor
-func (h *CborHandle) Name() string { return "cbor" }
-
-// SetInterfaceExt sets an extension
-func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
-}
-
-func (h *CborHandle) newEncDriver(e *Encoder) encDriver {
-	return &cborEncDriver{e: e, w: e.w, h: h}
-}
-
-func (h *CborHandle) newDecDriver(d *Decoder) decDriver {
-	return &cborDecDriver{d: d, h: h, r: d.r, br: d.bytes}
-}
-
-func (e *cborEncDriver) reset() {
-	e.w = e.e.w
-}
-
-func (d *cborDecDriver) reset() {
-	d.r, d.br = d.d.r, d.d.bytes
-	d.bd, d.bdRead = 0, false
-}
-
-var _ decDriver = (*cborDecDriver)(nil)
-var _ encDriver = (*cborEncDriver)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/decode.go b/vendor/github.com/ugorji/go/codec/decode.go
deleted file mode 100644
index 1c0817a..0000000
--- a/vendor/github.com/ugorji/go/codec/decode.go
+++ /dev/null
@@ -1,2552 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"encoding"
-	"errors"
-	"fmt"
-	"io"
-	"reflect"
-	"strconv"
-	"sync"
-	"time"
-)
-
-// Some tagging information for error messages.
-const (
-	msgBadDesc            = "unrecognized descriptor byte"
-	msgDecCannotExpandArr = "cannot expand go array from %v to stream length: %v"
-)
-
-const decDefSliceCap = 8
-const decDefChanCap = 64 // should be large, as cap cannot be expanded
-const decScratchByteArrayLen = cacheLineSize - 8
-
-var (
-	errstrOnlyMapOrArrayCanDecodeIntoStruct = "only encoded map or array can be decoded into a struct"
-	errstrCannotDecodeIntoNil               = "cannot decode into nil"
-
-	errmsgExpandSliceOverflow     = "expand slice: slice overflow"
-	errmsgExpandSliceCannotChange = "expand slice: cannot change"
-
-	errDecoderNotInitialized = errors.New("Decoder not initialized")
-
-	errDecUnreadByteNothingToRead   = errors.New("cannot unread - nothing has been read")
-	errDecUnreadByteLastByteNotRead = errors.New("cannot unread - last byte has not been read")
-	errDecUnreadByteUnknown         = errors.New("cannot unread - reason unknown")
-)
-
-// decReader abstracts the reading source, allowing implementations that can
-// read from an io.Reader or directly off a byte slice with zero-copying.
-type decReader interface {
-	unreadn1()
-
-	// readx will use the implementation scratch buffer if possible i.e. n < len(scratchbuf), OR
-	// just return a view of the []byte being decoded from.
-	// Ensure you call detachZeroCopyBytes later if this needs to be sent outside codec control.
-	readx(n int) []byte
-	readb([]byte)
-	readn1() uint8
-	numread() int // number of bytes read
-	track()
-	stopTrack() []byte
-
-	// skip will skip any byte that matches, and return the first non-matching byte
-	skip(accept *bitset256) (token byte)
-	// readTo will read any byte that matches, stopping once no-longer matching.
-	readTo(in []byte, accept *bitset256) (out []byte)
-	// readUntil will read, only stopping once it matches the 'stop' byte.
-	readUntil(in []byte, stop byte) (out []byte)
-}
-
-type decDriver interface {
-	// this will check if the next token is a break.
-	CheckBreak() bool
-	// Note: TryDecodeAsNil should be careful not to share any temporary []byte with
-	// the rest of the decDriver. This is because sometimes, we optimize by holding onto
-	// a transient []byte, and ensuring the only other call we make to the decDriver
-	// during that time is maybe a TryDecodeAsNil() call.
-	TryDecodeAsNil() bool
-	// vt is one of: Bytes, String, Nil, Slice or Map. Return unSet if not known.
-	ContainerType() (vt valueType)
-	// IsBuiltinType(rt uintptr) bool
-
-	// DecodeNaked will decode primitives (number, bool, string, []byte) and RawExt.
-	// For maps and arrays, it will not do the decoding in-band, but will signal
-	// the decoder, so that is done later, by setting the decNaked.valueType field.
-	//
-	// Note: Numbers are decoded as int64, uint64, float64 only (no smaller sized number types).
-	// for extensions, DecodeNaked must read the tag and the []byte if it exists.
-	// if the []byte is not read, then kInterfaceNaked will treat it as a Handle
-	// that stores the subsequent value in-band, and complete reading the RawExt.
-	//
-	// extensions should also use readx to decode them, for efficiency.
-	// kInterface will extract the detached byte slice if it has to pass it outside its realm.
-	DecodeNaked()
-
-	// Deprecated: use DecodeInt64 and DecodeUint64 instead
-	// DecodeInt(bitsize uint8) (i int64)
-	// DecodeUint(bitsize uint8) (ui uint64)
-
-	DecodeInt64() (i int64)
-	DecodeUint64() (ui uint64)
-
-	DecodeFloat64() (f float64)
-	DecodeBool() (b bool)
-	// DecodeString can also decode symbols.
-	// It looks redundant as DecodeBytes is available.
-	// However, some codecs (e.g. binc) support symbols and can
-	// return a pre-stored string value, meaning that it can bypass
-	// the cost of []byte->string conversion.
-	DecodeString() (s string)
-	DecodeStringAsBytes() (v []byte)
-
-	// DecodeBytes may be called directly, without going through reflection.
-	// Consequently, it must be designed to handle possible nil.
-	DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
-	// DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte)
-
-	// decodeExt will decode into a *RawExt or into an extension.
-	DecodeExt(v interface{}, xtag uint64, ext Ext) (realxtag uint64)
-	// decodeExt(verifyTag bool, tag byte) (xtag byte, xbs []byte)
-
-	DecodeTime() (t time.Time)
-
-	ReadArrayStart() int
-	ReadArrayElem()
-	ReadArrayEnd()
-	ReadMapStart() int
-	ReadMapElemKey()
-	ReadMapElemValue()
-	ReadMapEnd()
-
-	reset()
-	uncacheRead()
-}
-
-type decDriverNoopContainerReader struct{}
-
-func (x decDriverNoopContainerReader) ReadArrayStart() (v int) { return }
-func (x decDriverNoopContainerReader) ReadArrayElem()          {}
-func (x decDriverNoopContainerReader) ReadArrayEnd()           {}
-func (x decDriverNoopContainerReader) ReadMapStart() (v int)   { return }
-func (x decDriverNoopContainerReader) ReadMapElemKey()         {}
-func (x decDriverNoopContainerReader) ReadMapElemValue()       {}
-func (x decDriverNoopContainerReader) ReadMapEnd()             {}
-func (x decDriverNoopContainerReader) CheckBreak() (v bool)    { return }
-
-// func (x decNoSeparator) uncacheRead() {}
-
-// DecodeOptions captures configuration options during decode.
-type DecodeOptions struct {
-	// MapType specifies type to use during schema-less decoding of a map in the stream.
-	// If nil (unset), we default to map[string]interface{} iff json handle and MapStringAsKey=true,
-	// else map[interface{}]interface{}.
-	MapType reflect.Type
-
-	// SliceType specifies type to use during schema-less decoding of an array in the stream.
-	// If nil (unset), we default to []interface{} for all formats.
-	SliceType reflect.Type
-
-	// MaxInitLen defines the maxinum initial length that we "make" a collection
-	// (string, slice, map, chan). If 0 or negative, we default to a sensible value
-	// based on the size of an element in the collection.
-	//
-	// For example, when decoding, a stream may say that it has 2^64 elements.
-	// We should not auto-matically provision a slice of that size, to prevent Out-Of-Memory crash.
-	// Instead, we provision up to MaxInitLen, fill that up, and start appending after that.
-	MaxInitLen int
-
-	// ReaderBufferSize is the size of the buffer used when reading.
-	//
-	// if > 0, we use a smart buffer internally for performance purposes.
-	ReaderBufferSize int
-
-	// If ErrorIfNoField, return an error when decoding a map
-	// from a codec stream into a struct, and no matching struct field is found.
-	ErrorIfNoField bool
-
-	// If ErrorIfNoArrayExpand, return an error when decoding a slice/array that cannot be expanded.
-	// For example, the stream contains an array of 8 items, but you are decoding into a [4]T array,
-	// or you are decoding into a slice of length 4 which is non-addressable (and so cannot be set).
-	ErrorIfNoArrayExpand bool
-
-	// If SignedInteger, use the int64 during schema-less decoding of unsigned values (not uint64).
-	SignedInteger bool
-
-	// MapValueReset controls how we decode into a map value.
-	//
-	// By default, we MAY retrieve the mapping for a key, and then decode into that.
-	// However, especially with big maps, that retrieval may be expensive and unnecessary
-	// if the stream already contains all that is necessary to recreate the value.
-	//
-	// If true, we will never retrieve the previous mapping,
-	// but rather decode into a new value and set that in the map.
-	//
-	// If false, we will retrieve the previous mapping if necessary e.g.
-	// the previous mapping is a pointer, or is a struct or array with pre-set state,
-	// or is an interface.
-	MapValueReset bool
-
-	// SliceElementReset: on decoding a slice, reset the element to a zero value first.
-	//
-	// concern: if the slice already contained some garbage, we will decode into that garbage.
-	SliceElementReset bool
-
-	// InterfaceReset controls how we decode into an interface.
-	//
-	// By default, when we see a field that is an interface{...},
-	// or a map with interface{...} value, we will attempt decoding into the
-	// "contained" value.
-	//
-	// However, this prevents us from reading a string into an interface{}
-	// that formerly contained a number.
-	//
-	// If true, we will decode into a new "blank" value, and set that in the interface.
-	// If false, we will decode into whatever is contained in the interface.
-	InterfaceReset bool
-
-	// InternString controls interning of strings during decoding.
-	//
-	// Some handles, e.g. json, typically will read map keys as strings.
-	// If the set of keys are finite, it may help reduce allocation to
-	// look them up from a map (than to allocate them afresh).
-	//
-	// Note: Handles will be smart when using the intern functionality.
-	// Every string should not be interned.
-	// An excellent use-case for interning is struct field names,
-	// or map keys where key type is string.
-	InternString bool
-
-	// PreferArrayOverSlice controls whether to decode to an array or a slice.
-	//
-	// This only impacts decoding into a nil interface{}.
-	// Consequently, it has no effect on codecgen.
-	//
-	// *Note*: This only applies if using go1.5 and above,
-	// as it requires reflect.ArrayOf support which was absent before go1.5.
-	PreferArrayOverSlice bool
-
-	// DeleteOnNilMapValue controls how to decode a nil value in the stream.
-	//
-	// If true, we will delete the mapping of the key.
-	// Else, just set the mapping to the zero value of the type.
-	DeleteOnNilMapValue bool
-}
-
-// ------------------------------------
-
-type bufioDecReader struct {
-	buf []byte
-	r   io.Reader
-
-	c   int // cursor
-	n   int // num read
-	err error
-
-	tr  []byte
-	trb bool
-	b   [4]byte
-}
-
-func (z *bufioDecReader) reset(r io.Reader) {
-	z.r, z.c, z.n, z.err, z.trb = r, 0, 0, nil, false
-	if z.tr != nil {
-		z.tr = z.tr[:0]
-	}
-}
-
-func (z *bufioDecReader) Read(p []byte) (n int, err error) {
-	if z.err != nil {
-		return 0, z.err
-	}
-	p0 := p
-	n = copy(p, z.buf[z.c:])
-	z.c += n
-	if z.c == len(z.buf) {
-		z.c = 0
-	}
-	z.n += n
-	if len(p) == n {
-		if z.c == 0 {
-			z.buf = z.buf[:1]
-			z.buf[0] = p[len(p)-1]
-			z.c = 1
-		}
-		if z.trb {
-			z.tr = append(z.tr, p0[:n]...)
-		}
-		return
-	}
-	p = p[n:]
-	var n2 int
-	// if we are here, then z.buf is all read
-	if len(p) > len(z.buf) {
-		n2, err = decReadFull(z.r, p)
-		n += n2
-		z.n += n2
-		z.err = err
-		// don't return EOF if some bytes were read. keep for next time.
-		if n > 0 && err == io.EOF {
-			err = nil
-		}
-		// always keep last byte in z.buf
-		z.buf = z.buf[:1]
-		z.buf[0] = p[len(p)-1]
-		z.c = 1
-		if z.trb {
-			z.tr = append(z.tr, p0[:n]...)
-		}
-		return
-	}
-	// z.c is now 0, and len(p) <= len(z.buf)
-	for len(p) > 0 && z.err == nil {
-		// println("len(p) loop starting ... ")
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n2, err = z.r.Read(z.buf)
-		if n2 > 0 {
-			if err == io.EOF {
-				err = nil
-			}
-			z.buf = z.buf[:n2]
-			n2 = copy(p, z.buf)
-			z.c = n2
-			n += n2
-			z.n += n2
-			p = p[n2:]
-		}
-		z.err = err
-		// println("... len(p) loop done")
-	}
-	if z.c == 0 {
-		z.buf = z.buf[:1]
-		z.buf[0] = p[len(p)-1]
-		z.c = 1
-	}
-	if z.trb {
-		z.tr = append(z.tr, p0[:n]...)
-	}
-	return
-}
-
-func (z *bufioDecReader) ReadByte() (b byte, err error) {
-	z.b[0] = 0
-	_, err = z.Read(z.b[:1])
-	b = z.b[0]
-	return
-}
-
-func (z *bufioDecReader) UnreadByte() (err error) {
-	if z.err != nil {
-		return z.err
-	}
-	if z.c > 0 {
-		z.c--
-		z.n--
-		if z.trb {
-			z.tr = z.tr[:len(z.tr)-1]
-		}
-		return
-	}
-	return errDecUnreadByteNothingToRead
-}
-
-func (z *bufioDecReader) numread() int {
-	return z.n
-}
-
-func (z *bufioDecReader) readx(n int) (bs []byte) {
-	if n <= 0 || z.err != nil {
-		return
-	}
-	if z.c+n <= len(z.buf) {
-		bs = z.buf[z.c : z.c+n]
-		z.n += n
-		z.c += n
-		if z.trb {
-			z.tr = append(z.tr, bs...)
-		}
-		return
-	}
-	bs = make([]byte, n)
-	_, err := z.Read(bs)
-	if err != nil {
-		panic(err)
-	}
-	return
-}
-
-func (z *bufioDecReader) readb(bs []byte) {
-	_, err := z.Read(bs)
-	if err != nil {
-		panic(err)
-	}
-}
-
-// func (z *bufioDecReader) readn1eof() (b uint8, eof bool) {
-// 	b, err := z.ReadByte()
-// 	if err != nil {
-// 		if err == io.EOF {
-// 			eof = true
-// 		} else {
-// 			panic(err)
-// 		}
-// 	}
-// 	return
-// }
-
-func (z *bufioDecReader) readn1() (b uint8) {
-	b, err := z.ReadByte()
-	if err != nil {
-		panic(err)
-	}
-	return
-}
-
-func (z *bufioDecReader) search(in []byte, accept *bitset256, stop, flag uint8) (token byte, out []byte) {
-	// flag: 1 (skip), 2 (readTo), 4 (readUntil)
-	if flag == 4 {
-		for i := z.c; i < len(z.buf); i++ {
-			if z.buf[i] == stop {
-				token = z.buf[i]
-				z.n = z.n + (i - z.c) - 1
-				i++
-				out = z.buf[z.c:i]
-				if z.trb {
-					z.tr = append(z.tr, z.buf[z.c:i]...)
-				}
-				z.c = i
-				return
-			}
-		}
-	} else {
-		for i := z.c; i < len(z.buf); i++ {
-			if !accept.isset(z.buf[i]) {
-				token = z.buf[i]
-				z.n = z.n + (i - z.c) - 1
-				if flag == 1 {
-					i++
-				} else {
-					out = z.buf[z.c:i]
-				}
-				if z.trb {
-					z.tr = append(z.tr, z.buf[z.c:i]...)
-				}
-				z.c = i
-				return
-			}
-		}
-	}
-	z.n += len(z.buf) - z.c
-	if flag != 1 {
-		out = append(in, z.buf[z.c:]...)
-	}
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:]...)
-	}
-	var n2 int
-	if z.err != nil {
-		return
-	}
-	for {
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n2, z.err = z.r.Read(z.buf)
-		if n2 > 0 && z.err != nil {
-			z.err = nil
-		}
-		z.buf = z.buf[:n2]
-		if flag == 4 {
-			for i := 0; i < n2; i++ {
-				if z.buf[i] == stop {
-					token = z.buf[i]
-					z.n += i - 1
-					i++
-					out = append(out, z.buf[z.c:i]...)
-					if z.trb {
-						z.tr = append(z.tr, z.buf[z.c:i]...)
-					}
-					z.c = i
-					return
-				}
-			}
-		} else {
-			for i := 0; i < n2; i++ {
-				if !accept.isset(z.buf[i]) {
-					token = z.buf[i]
-					z.n += i - 1
-					if flag == 1 {
-						i++
-					}
-					if flag != 1 {
-						out = append(out, z.buf[z.c:i]...)
-					}
-					if z.trb {
-						z.tr = append(z.tr, z.buf[z.c:i]...)
-					}
-					z.c = i
-					return
-				}
-			}
-		}
-		if flag != 1 {
-			out = append(out, z.buf[:n2]...)
-		}
-		z.n += n2
-		if z.err != nil {
-			return
-		}
-		if z.trb {
-			z.tr = append(z.tr, z.buf[:n2]...)
-		}
-	}
-}
-
-func (z *bufioDecReader) skip(accept *bitset256) (token byte) {
-	token, _ = z.search(nil, accept, 0, 1)
-	return
-}
-
-func (z *bufioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
-	_, out = z.search(in, accept, 0, 2)
-	return
-}
-
-func (z *bufioDecReader) readUntil(in []byte, stop byte) (out []byte) {
-	_, out = z.search(in, nil, stop, 4)
-	return
-}
-
-func (z *bufioDecReader) unreadn1() {
-	err := z.UnreadByte()
-	if err != nil {
-		panic(err)
-	}
-}
-
-func (z *bufioDecReader) track() {
-	if z.tr != nil {
-		z.tr = z.tr[:0]
-	}
-	z.trb = true
-}
-
-func (z *bufioDecReader) stopTrack() (bs []byte) {
-	z.trb = false
-	return z.tr
-}
-
-// ioDecReader is a decReader that reads off an io.Reader.
-//
-// It also has a fallback implementation of ByteScanner if needed.
-type ioDecReader struct {
-	r io.Reader // the reader passed in
-
-	rr io.Reader
-	br io.ByteScanner
-
-	l   byte // last byte
-	ls  byte // last byte status. 0: init-canDoNothing, 1: canRead, 2: canUnread
-	trb bool // tracking bytes turned on
-	_   bool
-	b   [4]byte // tiny buffer for reading single bytes
-
-	x  [scratchByteArrayLen]byte // for: get struct field name, swallow valueTypeBytes, etc
-	n  int                       // num read
-	tr []byte                    // tracking bytes read
-}
-
-func (z *ioDecReader) reset(r io.Reader) {
-	z.r = r
-	z.rr = r
-	z.l, z.ls, z.n, z.trb = 0, 0, 0, false
-	if z.tr != nil {
-		z.tr = z.tr[:0]
-	}
-	var ok bool
-	if z.br, ok = r.(io.ByteScanner); !ok {
-		z.br = z
-		z.rr = z
-	}
-}
-
-func (z *ioDecReader) Read(p []byte) (n int, err error) {
-	if len(p) == 0 {
-		return
-	}
-	var firstByte bool
-	if z.ls == 1 {
-		z.ls = 2
-		p[0] = z.l
-		if len(p) == 1 {
-			n = 1
-			return
-		}
-		firstByte = true
-		p = p[1:]
-	}
-	n, err = z.r.Read(p)
-	if n > 0 {
-		if err == io.EOF && n == len(p) {
-			err = nil // read was successful, so postpone EOF (till next time)
-		}
-		z.l = p[n-1]
-		z.ls = 2
-	}
-	if firstByte {
-		n++
-	}
-	return
-}
-
-func (z *ioDecReader) ReadByte() (c byte, err error) {
-	n, err := z.Read(z.b[:1])
-	if n == 1 {
-		c = z.b[0]
-		if err == io.EOF {
-			err = nil // read was successful, so postpone EOF (till next time)
-		}
-	}
-	return
-}
-
-func (z *ioDecReader) UnreadByte() (err error) {
-	switch z.ls {
-	case 2:
-		z.ls = 1
-	case 0:
-		err = errDecUnreadByteNothingToRead
-	case 1:
-		err = errDecUnreadByteLastByteNotRead
-	default:
-		err = errDecUnreadByteUnknown
-	}
-	return
-}
-
-func (z *ioDecReader) numread() int {
-	return z.n
-}
-
-func (z *ioDecReader) readx(n int) (bs []byte) {
-	if n <= 0 {
-		return
-	}
-	if n < len(z.x) {
-		bs = z.x[:n]
-	} else {
-		bs = make([]byte, n)
-	}
-	if _, err := decReadFull(z.rr, bs); err != nil {
-		panic(err)
-	}
-	z.n += len(bs)
-	if z.trb {
-		z.tr = append(z.tr, bs...)
-	}
-	return
-}
-
-func (z *ioDecReader) readb(bs []byte) {
-	// if len(bs) == 0 {
-	// 	return
-	// }
-	if _, err := decReadFull(z.rr, bs); err != nil {
-		panic(err)
-	}
-	z.n += len(bs)
-	if z.trb {
-		z.tr = append(z.tr, bs...)
-	}
-}
-
-func (z *ioDecReader) readn1eof() (b uint8, eof bool) {
-	b, err := z.br.ReadByte()
-	if err == nil {
-		z.n++
-		if z.trb {
-			z.tr = append(z.tr, b)
-		}
-	} else if err == io.EOF {
-		eof = true
-	} else {
-		panic(err)
-	}
-	return
-}
-
-func (z *ioDecReader) readn1() (b uint8) {
-	var err error
-	if b, err = z.br.ReadByte(); err == nil {
-		z.n++
-		if z.trb {
-			z.tr = append(z.tr, b)
-		}
-		return
-	}
-	panic(err)
-}
-
-func (z *ioDecReader) skip(accept *bitset256) (token byte) {
-	for {
-		var eof bool
-		token, eof = z.readn1eof()
-		if eof {
-			return
-		}
-		if accept.isset(token) {
-			continue
-		}
-		return
-	}
-}
-
-func (z *ioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
-	out = in
-	for {
-		token, eof := z.readn1eof()
-		if eof {
-			return
-		}
-		if accept.isset(token) {
-			out = append(out, token)
-		} else {
-			z.unreadn1()
-			return
-		}
-	}
-}
-
-func (z *ioDecReader) readUntil(in []byte, stop byte) (out []byte) {
-	out = in
-	for {
-		token, eof := z.readn1eof()
-		if eof {
-			panic(io.EOF)
-		}
-		out = append(out, token)
-		if token == stop {
-			return
-		}
-	}
-}
-
-func (z *ioDecReader) unreadn1() {
-	err := z.br.UnreadByte()
-	if err != nil {
-		panic(err)
-	}
-	z.n--
-	if z.trb {
-		if l := len(z.tr) - 1; l >= 0 {
-			z.tr = z.tr[:l]
-		}
-	}
-}
-
-func (z *ioDecReader) track() {
-	if z.tr != nil {
-		z.tr = z.tr[:0]
-	}
-	z.trb = true
-}
-
-func (z *ioDecReader) stopTrack() (bs []byte) {
-	z.trb = false
-	return z.tr
-}
-
-// ------------------------------------
-
-var errBytesDecReaderCannotUnread = errors.New("cannot unread last byte read")
-
-// bytesDecReader is a decReader that reads off a byte slice with zero copying
-type bytesDecReader struct {
-	b []byte // data
-	c int    // cursor
-	a int    // available
-	t int    // track start
-}
-
-func (z *bytesDecReader) reset(in []byte) {
-	z.b = in
-	z.a = len(in)
-	z.c = 0
-	z.t = 0
-}
-
-func (z *bytesDecReader) numread() int {
-	return z.c
-}
-
-func (z *bytesDecReader) unreadn1() {
-	if z.c == 0 || len(z.b) == 0 {
-		panic(errBytesDecReaderCannotUnread)
-	}
-	z.c--
-	z.a++
-	return
-}
-
-func (z *bytesDecReader) readx(n int) (bs []byte) {
-	// slicing from a non-constant start position is more expensive,
-	// as more computation is required to decipher the pointer start position.
-	// However, we do it only once, and it's better than reslicing both z.b and return value.
-
-	if n <= 0 {
-	} else if z.a == 0 {
-		panic(io.EOF)
-	} else if n > z.a {
-		panic(io.ErrUnexpectedEOF)
-	} else {
-		c0 := z.c
-		z.c = c0 + n
-		z.a = z.a - n
-		bs = z.b[c0:z.c]
-	}
-	return
-}
-
-func (z *bytesDecReader) readb(bs []byte) {
-	copy(bs, z.readx(len(bs)))
-}
-
-func (z *bytesDecReader) readn1() (v uint8) {
-	if z.a == 0 {
-		panic(io.EOF)
-	}
-	v = z.b[z.c]
-	z.c++
-	z.a--
-	return
-}
-
-// func (z *bytesDecReader) readn1eof() (v uint8, eof bool) {
-// 	if z.a == 0 {
-// 		eof = true
-// 		return
-// 	}
-// 	v = z.b[z.c]
-// 	z.c++
-// 	z.a--
-// 	return
-// }
-
-func (z *bytesDecReader) skip(accept *bitset256) (token byte) {
-	if z.a == 0 {
-		return
-	}
-	blen := len(z.b)
-	for i := z.c; i < blen; i++ {
-		if !accept.isset(z.b[i]) {
-			token = z.b[i]
-			i++
-			z.a -= (i - z.c)
-			z.c = i
-			return
-		}
-	}
-	z.a, z.c = 0, blen
-	return
-}
-
-func (z *bytesDecReader) readTo(_ []byte, accept *bitset256) (out []byte) {
-	if z.a == 0 {
-		return
-	}
-	blen := len(z.b)
-	for i := z.c; i < blen; i++ {
-		if !accept.isset(z.b[i]) {
-			out = z.b[z.c:i]
-			z.a -= (i - z.c)
-			z.c = i
-			return
-		}
-	}
-	out = z.b[z.c:]
-	z.a, z.c = 0, blen
-	return
-}
-
-func (z *bytesDecReader) readUntil(_ []byte, stop byte) (out []byte) {
-	if z.a == 0 {
-		panic(io.EOF)
-	}
-	blen := len(z.b)
-	for i := z.c; i < blen; i++ {
-		if z.b[i] == stop {
-			i++
-			out = z.b[z.c:i]
-			z.a -= (i - z.c)
-			z.c = i
-			return
-		}
-	}
-	z.a, z.c = 0, blen
-	panic(io.EOF)
-}
-
-func (z *bytesDecReader) track() {
-	z.t = z.c
-}
-
-func (z *bytesDecReader) stopTrack() (bs []byte) {
-	return z.b[z.t:z.c]
-}
-
-// ----------------------------------------
-
-// func (d *Decoder) builtin(f *codecFnInfo, rv reflect.Value) {
-// 	d.d.DecodeBuiltin(f.ti.rtid, rv2i(rv))
-// }
-
-func (d *Decoder) rawExt(f *codecFnInfo, rv reflect.Value) {
-	d.d.DecodeExt(rv2i(rv), 0, nil)
-}
-
-func (d *Decoder) ext(f *codecFnInfo, rv reflect.Value) {
-	d.d.DecodeExt(rv2i(rv), f.xfTag, f.xfFn)
-}
-
-func (d *Decoder) selferUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	rv2i(rv).(Selfer).CodecDecodeSelf(d)
-}
-
-func (d *Decoder) binaryUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	bm := rv2i(rv).(encoding.BinaryUnmarshaler)
-	xbs := d.d.DecodeBytes(nil, true)
-	if fnerr := bm.UnmarshalBinary(xbs); fnerr != nil {
-		panic(fnerr)
-	}
-}
-
-func (d *Decoder) textUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	tm := rv2i(rv).(encoding.TextUnmarshaler)
-	fnerr := tm.UnmarshalText(d.d.DecodeStringAsBytes())
-	if fnerr != nil {
-		panic(fnerr)
-	}
-}
-
-func (d *Decoder) jsonUnmarshal(f *codecFnInfo, rv reflect.Value) {
-	tm := rv2i(rv).(jsonUnmarshaler)
-	// bs := d.d.DecodeBytes(d.b[:], true, true)
-	// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
-	fnerr := tm.UnmarshalJSON(d.nextValueBytes())
-	if fnerr != nil {
-		panic(fnerr)
-	}
-}
-
-func (d *Decoder) kErr(f *codecFnInfo, rv reflect.Value) {
-	d.errorf("no decoding function defined for kind %v", rv.Kind())
-}
-
-// var kIntfCtr uint64
-
-func (d *Decoder) kInterfaceNaked(f *codecFnInfo) (rvn reflect.Value) {
-	// nil interface:
-	// use some hieristics to decode it appropriately
-	// based on the detected next value in the stream.
-	n := d.naked()
-	d.d.DecodeNaked()
-	if n.v == valueTypeNil {
-		return
-	}
-	// We cannot decode non-nil stream value into nil interface with methods (e.g. io.Reader).
-	if f.ti.numMeth > 0 {
-		d.errorf("cannot decode non-nil codec value into nil %v (%v methods)", f.ti.rt, f.ti.numMeth)
-		return
-	}
-	// var useRvn bool
-	switch n.v {
-	case valueTypeMap:
-		// if json, default to a map type with string keys
-		mtid := d.mtid
-		if mtid == 0 {
-			if d.jsms {
-				mtid = mapStrIntfTypId
-			} else {
-				mtid = mapIntfIntfTypId
-			}
-		}
-		if mtid == mapIntfIntfTypId {
-			n.initContainers()
-			if n.lm < arrayCacheLen {
-				n.ma[n.lm] = nil
-				rvn = n.rma[n.lm]
-				n.lm++
-				d.decode(&n.ma[n.lm-1])
-				n.lm--
-			} else {
-				var v2 map[interface{}]interface{}
-				d.decode(&v2)
-				rvn = reflect.ValueOf(&v2).Elem()
-			}
-		} else if mtid == mapStrIntfTypId { // for json performance
-			n.initContainers()
-			if n.ln < arrayCacheLen {
-				n.na[n.ln] = nil
-				rvn = n.rna[n.ln]
-				n.ln++
-				d.decode(&n.na[n.ln-1])
-				n.ln--
-			} else {
-				var v2 map[string]interface{}
-				d.decode(&v2)
-				rvn = reflect.ValueOf(&v2).Elem()
-			}
-		} else {
-			if d.mtr {
-				rvn = reflect.New(d.h.MapType)
-				d.decode(rv2i(rvn))
-				rvn = rvn.Elem()
-			} else {
-				rvn = reflect.New(d.h.MapType).Elem()
-				d.decodeValue(rvn, nil, true)
-			}
-		}
-	case valueTypeArray:
-		if d.stid == 0 || d.stid == intfSliceTypId {
-			n.initContainers()
-			if n.ls < arrayCacheLen {
-				n.sa[n.ls] = nil
-				rvn = n.rsa[n.ls]
-				n.ls++
-				d.decode(&n.sa[n.ls-1])
-				n.ls--
-			} else {
-				var v2 []interface{}
-				d.decode(&v2)
-				rvn = reflect.ValueOf(&v2).Elem()
-			}
-			if reflectArrayOfSupported && d.stid == 0 && d.h.PreferArrayOverSlice {
-				rvn2 := reflect.New(reflectArrayOf(rvn.Len(), intfTyp)).Elem()
-				reflect.Copy(rvn2, rvn)
-				rvn = rvn2
-			}
-		} else {
-			if d.str {
-				rvn = reflect.New(d.h.SliceType)
-				d.decode(rv2i(rvn))
-				rvn = rvn.Elem()
-			} else {
-				rvn = reflect.New(d.h.SliceType).Elem()
-				d.decodeValue(rvn, nil, true)
-			}
-		}
-	case valueTypeExt:
-		var v interface{}
-		tag, bytes := n.u, n.l // calling decode below might taint the values
-		if bytes == nil {
-			n.initContainers()
-			if n.li < arrayCacheLen {
-				n.ia[n.li] = nil
-				n.li++
-				d.decode(&n.ia[n.li-1])
-				// v = *(&n.ia[l])
-				n.li--
-				v = n.ia[n.li]
-				n.ia[n.li] = nil
-			} else {
-				d.decode(&v)
-			}
-		}
-		bfn := d.h.getExtForTag(tag)
-		if bfn == nil {
-			var re RawExt
-			re.Tag = tag
-			re.Data = detachZeroCopyBytes(d.bytes, nil, bytes)
-			re.Value = v
-			rvn = reflect.ValueOf(&re).Elem()
-		} else {
-			rvnA := reflect.New(bfn.rt)
-			if bytes != nil {
-				bfn.ext.ReadExt(rv2i(rvnA), bytes)
-			} else {
-				bfn.ext.UpdateExt(rv2i(rvnA), v)
-			}
-			rvn = rvnA.Elem()
-		}
-	case valueTypeNil:
-		// no-op
-	case valueTypeInt:
-		rvn = n.ri
-	case valueTypeUint:
-		rvn = n.ru
-	case valueTypeFloat:
-		rvn = n.rf
-	case valueTypeBool:
-		rvn = n.rb
-	case valueTypeString, valueTypeSymbol:
-		rvn = n.rs
-	case valueTypeBytes:
-		rvn = n.rl
-	case valueTypeTime:
-		rvn = n.rt
-	default:
-		panicv.errorf("kInterfaceNaked: unexpected valueType: %d", n.v)
-	}
-	return
-}
-
-func (d *Decoder) kInterface(f *codecFnInfo, rv reflect.Value) {
-	// Note:
-	// A consequence of how kInterface works, is that
-	// if an interface already contains something, we try
-	// to decode into what was there before.
-	// We do not replace with a generic value (as got from decodeNaked).
-
-	// every interface passed here MUST be settable.
-	var rvn reflect.Value
-	if rv.IsNil() || d.h.InterfaceReset {
-		// check if mapping to a type: if so, initialize it and move on
-		rvn = d.h.intf2impl(f.ti.rtid)
-		if rvn.IsValid() {
-			rv.Set(rvn)
-		} else {
-			rvn = d.kInterfaceNaked(f)
-			if rvn.IsValid() {
-				rv.Set(rvn)
-			} else if d.h.InterfaceReset {
-				// reset to zero value based on current type in there.
-				rv.Set(reflect.Zero(rv.Elem().Type()))
-			}
-			return
-		}
-	} else {
-		// now we have a non-nil interface value, meaning it contains a type
-		rvn = rv.Elem()
-	}
-	if d.d.TryDecodeAsNil() {
-		rv.Set(reflect.Zero(rvn.Type()))
-		return
-	}
-
-	// Note: interface{} is settable, but underlying type may not be.
-	// Consequently, we MAY have to create a decodable value out of the underlying value,
-	// decode into it, and reset the interface itself.
-	// fmt.Printf(">>>> kInterface: rvn type: %v, rv type: %v\n", rvn.Type(), rv.Type())
-
-	rvn2, canDecode := isDecodeable(rvn)
-	if canDecode {
-		d.decodeValue(rvn2, nil, true)
-		return
-	}
-
-	rvn2 = reflect.New(rvn.Type()).Elem()
-	rvn2.Set(rvn)
-	d.decodeValue(rvn2, nil, true)
-	rv.Set(rvn2)
-}
-
-func decStructFieldKey(dd decDriver, keyType valueType, b *[decScratchByteArrayLen]byte) (rvkencname []byte) {
-	// use if-else-if, not switch (which compiles to binary-search)
-	// since keyType is typically valueTypeString, branch prediction is pretty good.
-
-	if keyType == valueTypeString {
-		rvkencname = dd.DecodeStringAsBytes()
-	} else if keyType == valueTypeInt {
-		rvkencname = strconv.AppendInt(b[:0], dd.DecodeInt64(), 10)
-	} else if keyType == valueTypeUint {
-		rvkencname = strconv.AppendUint(b[:0], dd.DecodeUint64(), 10)
-	} else if keyType == valueTypeFloat {
-		rvkencname = strconv.AppendFloat(b[:0], dd.DecodeFloat64(), 'f', -1, 64)
-	} else {
-		rvkencname = dd.DecodeStringAsBytes()
-	}
-	return rvkencname
-}
-
-func (d *Decoder) kStruct(f *codecFnInfo, rv reflect.Value) {
-	fti := f.ti
-	dd := d.d
-	elemsep := d.esep
-	sfn := structFieldNode{v: rv, update: true}
-	ctyp := dd.ContainerType()
-	if ctyp == valueTypeMap {
-		containerLen := dd.ReadMapStart()
-		if containerLen == 0 {
-			dd.ReadMapEnd()
-			return
-		}
-		tisfi := fti.sfiSort
-		hasLen := containerLen >= 0
-
-		var rvkencname []byte
-		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-			if elemsep {
-				dd.ReadMapElemKey()
-			}
-			rvkencname = decStructFieldKey(dd, fti.keyType, &d.b)
-			if elemsep {
-				dd.ReadMapElemValue()
-			}
-			if k := fti.indexForEncName(rvkencname); k > -1 {
-				si := tisfi[k]
-				if dd.TryDecodeAsNil() {
-					si.setToZeroValue(rv)
-				} else {
-					d.decodeValue(sfn.field(si), nil, true)
-				}
-			} else {
-				d.structFieldNotFound(-1, stringView(rvkencname))
-			}
-			// keepAlive4StringView(rvkencnameB) // not needed, as reference is outside loop
-		}
-		dd.ReadMapEnd()
-	} else if ctyp == valueTypeArray {
-		containerLen := dd.ReadArrayStart()
-		if containerLen == 0 {
-			dd.ReadArrayEnd()
-			return
-		}
-		// Not much gain from doing it two ways for array.
-		// Arrays are not used as much for structs.
-		hasLen := containerLen >= 0
-		for j, si := range fti.sfiSrc {
-			if (hasLen && j == containerLen) || (!hasLen && dd.CheckBreak()) {
-				break
-			}
-			if elemsep {
-				dd.ReadArrayElem()
-			}
-			if dd.TryDecodeAsNil() {
-				si.setToZeroValue(rv)
-			} else {
-				d.decodeValue(sfn.field(si), nil, true)
-			}
-		}
-		if containerLen > len(fti.sfiSrc) {
-			// read remaining values and throw away
-			for j := len(fti.sfiSrc); j < containerLen; j++ {
-				if elemsep {
-					dd.ReadArrayElem()
-				}
-				d.structFieldNotFound(j, "")
-			}
-		}
-		dd.ReadArrayEnd()
-	} else {
-		d.errorstr(errstrOnlyMapOrArrayCanDecodeIntoStruct)
-		return
-	}
-}
-
-func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
-	// A slice can be set from a map or array in stream.
-	// This way, the order can be kept (as order is lost with map).
-	ti := f.ti
-	if f.seq == seqTypeChan && ti.chandir&uint8(reflect.SendDir) == 0 {
-		d.errorf("receive-only channel cannot be decoded")
-	}
-	dd := d.d
-	rtelem0 := ti.elem
-	ctyp := dd.ContainerType()
-	if ctyp == valueTypeBytes || ctyp == valueTypeString {
-		// you can only decode bytes or string in the stream into a slice or array of bytes
-		if !(ti.rtid == uint8SliceTypId || rtelem0.Kind() == reflect.Uint8) {
-			d.errorf("bytes/string in stream must decode into slice/array of bytes, not %v", ti.rt)
-		}
-		if f.seq == seqTypeChan {
-			bs2 := dd.DecodeBytes(nil, true)
-			irv := rv2i(rv)
-			ch, ok := irv.(chan<- byte)
-			if !ok {
-				ch = irv.(chan byte)
-			}
-			for _, b := range bs2 {
-				ch <- b
-			}
-		} else {
-			rvbs := rv.Bytes()
-			bs2 := dd.DecodeBytes(rvbs, false)
-			// if rvbs == nil && bs2 != nil || rvbs != nil && bs2 == nil || len(bs2) != len(rvbs) {
-			if !(len(bs2) > 0 && len(bs2) == len(rvbs) && &bs2[0] == &rvbs[0]) {
-				if rv.CanSet() {
-					rv.SetBytes(bs2)
-				} else if len(rvbs) > 0 && len(bs2) > 0 {
-					copy(rvbs, bs2)
-				}
-			}
-		}
-		return
-	}
-
-	// array := f.seq == seqTypeChan
-
-	slh, containerLenS := d.decSliceHelperStart() // only expects valueType(Array|Map)
-
-	// an array can never return a nil slice. so no need to check f.array here.
-	if containerLenS == 0 {
-		if rv.CanSet() {
-			if f.seq == seqTypeSlice {
-				if rv.IsNil() {
-					rv.Set(reflect.MakeSlice(ti.rt, 0, 0))
-				} else {
-					rv.SetLen(0)
-				}
-			} else if f.seq == seqTypeChan {
-				if rv.IsNil() {
-					rv.Set(reflect.MakeChan(ti.rt, 0))
-				}
-			}
-		}
-		slh.End()
-		return
-	}
-
-	rtelem0Size := int(rtelem0.Size())
-	rtElem0Kind := rtelem0.Kind()
-	rtelem0Mut := !isImmutableKind(rtElem0Kind)
-	rtelem := rtelem0
-	rtelemkind := rtelem.Kind()
-	for rtelemkind == reflect.Ptr {
-		rtelem = rtelem.Elem()
-		rtelemkind = rtelem.Kind()
-	}
-
-	var fn *codecFn
-
-	var rvCanset = rv.CanSet()
-	var rvChanged bool
-	var rv0 = rv
-	var rv9 reflect.Value
-
-	rvlen := rv.Len()
-	rvcap := rv.Cap()
-	hasLen := containerLenS > 0
-	if hasLen && f.seq == seqTypeSlice {
-		if containerLenS > rvcap {
-			oldRvlenGtZero := rvlen > 0
-			rvlen = decInferLen(containerLenS, d.h.MaxInitLen, int(rtelem0.Size()))
-			if rvlen <= rvcap {
-				if rvCanset {
-					rv.SetLen(rvlen)
-				}
-			} else if rvCanset {
-				rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
-				rvcap = rvlen
-				rvChanged = true
-			} else {
-				d.errorf("cannot decode into non-settable slice")
-			}
-			if rvChanged && oldRvlenGtZero && !isImmutableKind(rtelem0.Kind()) {
-				reflect.Copy(rv, rv0) // only copy up to length NOT cap i.e. rv0.Slice(0, rvcap)
-			}
-		} else if containerLenS != rvlen {
-			rvlen = containerLenS
-			if rvCanset {
-				rv.SetLen(rvlen)
-			}
-			// else {
-			// rv = rv.Slice(0, rvlen)
-			// rvChanged = true
-			// d.errorf("cannot decode into non-settable slice")
-			// }
-		}
-	}
-
-	// consider creating new element once, and just decoding into it.
-	var rtelem0Zero reflect.Value
-	var rtelem0ZeroValid bool
-	var decodeAsNil bool
-	var j int
-	d.cfer()
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && (f.seq == seqTypeSlice || f.seq == seqTypeChan) && rv.IsNil() {
-			if hasLen {
-				rvlen = decInferLen(containerLenS, d.h.MaxInitLen, rtelem0Size)
-			} else if f.seq == seqTypeSlice {
-				rvlen = decDefSliceCap
-			} else {
-				rvlen = decDefChanCap
-			}
-			if rvCanset {
-				if f.seq == seqTypeSlice {
-					rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
-					rvChanged = true
-				} else { // chan
-					// xdebugf(">>>>>> haslen = %v, make chan of type '%v' with length: %v", hasLen, ti.rt, rvlen)
-					rv = reflect.MakeChan(ti.rt, rvlen)
-					rvChanged = true
-				}
-			} else {
-				d.errorf("cannot decode into non-settable slice")
-			}
-		}
-		slh.ElemContainerState(j)
-		decodeAsNil = dd.TryDecodeAsNil()
-		if f.seq == seqTypeChan {
-			if decodeAsNil {
-				rv.Send(reflect.Zero(rtelem0))
-				continue
-			}
-			if rtelem0Mut || !rv9.IsValid() { // || (rtElem0Kind == reflect.Ptr && rv9.IsNil()) {
-				rv9 = reflect.New(rtelem0).Elem()
-			}
-			if fn == nil {
-				fn = d.cf.get(rtelem, true, true)
-			}
-			d.decodeValue(rv9, fn, true)
-			// xdebugf(">>>> rv9 sent on %v during decode: %v, with len=%v, cap=%v", rv.Type(), rv9, rv.Len(), rv.Cap())
-			rv.Send(rv9)
-		} else {
-			// if indefinite, etc, then expand the slice if necessary
-			var decodeIntoBlank bool
-			if j >= rvlen {
-				if f.seq == seqTypeArray {
-					d.arrayCannotExpand(rvlen, j+1)
-					decodeIntoBlank = true
-				} else { // if f.seq == seqTypeSlice
-					// rv = reflect.Append(rv, reflect.Zero(rtelem0)) // append logic + varargs
-					var rvcap2 int
-					var rvErrmsg2 string
-					rv9, rvcap2, rvChanged, rvErrmsg2 =
-						expandSliceRV(rv, ti.rt, rvCanset, rtelem0Size, 1, rvlen, rvcap)
-					if rvErrmsg2 != "" {
-						d.errorf(rvErrmsg2)
-					}
-					rvlen++
-					if rvChanged {
-						rv = rv9
-						rvcap = rvcap2
-					}
-				}
-			}
-			if decodeIntoBlank {
-				if !decodeAsNil {
-					d.swallow()
-				}
-			} else {
-				rv9 = rv.Index(j)
-				if d.h.SliceElementReset || decodeAsNil {
-					if !rtelem0ZeroValid {
-						rtelem0ZeroValid = true
-						rtelem0Zero = reflect.Zero(rtelem0)
-					}
-					rv9.Set(rtelem0Zero)
-				}
-				if decodeAsNil {
-					continue
-				}
-
-				if fn == nil {
-					fn = d.cf.get(rtelem, true, true)
-				}
-				d.decodeValue(rv9, fn, true)
-			}
-		}
-	}
-	if f.seq == seqTypeSlice {
-		if j < rvlen {
-			if rv.CanSet() {
-				rv.SetLen(j)
-			} else if rvCanset {
-				rv = rv.Slice(0, j)
-				rvChanged = true
-			} // else { d.errorf("kSlice: cannot change non-settable slice") }
-			rvlen = j
-		} else if j == 0 && rv.IsNil() {
-			if rvCanset {
-				rv = reflect.MakeSlice(ti.rt, 0, 0)
-				rvChanged = true
-			} // else { d.errorf("kSlice: cannot change non-settable slice") }
-		}
-	}
-	slh.End()
-
-	if rvChanged { // infers rvCanset=true, so it can be reset
-		rv0.Set(rv)
-	}
-}
-
-// func (d *Decoder) kArray(f *codecFnInfo, rv reflect.Value) {
-// 	// d.decodeValueFn(rv.Slice(0, rv.Len()))
-// 	f.kSlice(rv.Slice(0, rv.Len()))
-// }
-
-func (d *Decoder) kMap(f *codecFnInfo, rv reflect.Value) {
-	dd := d.d
-	containerLen := dd.ReadMapStart()
-	elemsep := d.esep
-	ti := f.ti
-	if rv.IsNil() {
-		rv.Set(makeMapReflect(ti.rt, containerLen))
-	}
-
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return
-	}
-
-	ktype, vtype := ti.key, ti.elem
-	ktypeId := rt2id(ktype)
-	vtypeKind := vtype.Kind()
-
-	var keyFn, valFn *codecFn
-	var ktypeLo, vtypeLo reflect.Type
-
-	for ktypeLo = ktype; ktypeLo.Kind() == reflect.Ptr; ktypeLo = ktypeLo.Elem() {
-	}
-
-	for vtypeLo = vtype; vtypeLo.Kind() == reflect.Ptr; vtypeLo = vtypeLo.Elem() {
-	}
-
-	var mapGet, mapSet bool
-	rvvImmut := isImmutableKind(vtypeKind)
-	if !d.h.MapValueReset {
-		// if pointer, mapGet = true
-		// if interface, mapGet = true if !DecodeNakedAlways (else false)
-		// if builtin, mapGet = false
-		// else mapGet = true
-		if vtypeKind == reflect.Ptr {
-			mapGet = true
-		} else if vtypeKind == reflect.Interface {
-			if !d.h.InterfaceReset {
-				mapGet = true
-			}
-		} else if !rvvImmut {
-			mapGet = true
-		}
-	}
-
-	var rvk, rvkp, rvv, rvz reflect.Value
-	rvkMut := !isImmutableKind(ktype.Kind()) // if ktype is immutable, then re-use the same rvk.
-	ktypeIsString := ktypeId == stringTypId
-	ktypeIsIntf := ktypeId == intfTypId
-	hasLen := containerLen > 0
-	var kstrbs []byte
-	d.cfer()
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if rvkMut || !rvkp.IsValid() {
-			rvkp = reflect.New(ktype)
-			rvk = rvkp.Elem()
-		}
-		if elemsep {
-			dd.ReadMapElemKey()
-		}
-		if false && dd.TryDecodeAsNil() { // nil cannot be a map key, so disregard this block
-			// Previously, if a nil key, we just ignored the mapped value and continued.
-			// However, that makes the result of encoding and then decoding map[intf]intf{nil:nil}
-			// to be an empty map.
-			// Instead, we treat a nil key as the zero value of the type.
-			rvk.Set(reflect.Zero(ktype))
-		} else if ktypeIsString {
-			kstrbs = dd.DecodeStringAsBytes()
-			rvk.SetString(stringView(kstrbs))
-			// NOTE: if doing an insert, you MUST use a real string (not stringview)
-		} else {
-			if keyFn == nil {
-				keyFn = d.cf.get(ktypeLo, true, true)
-			}
-			d.decodeValue(rvk, keyFn, true)
-		}
-		// special case if a byte array.
-		if ktypeIsIntf {
-			if rvk2 := rvk.Elem(); rvk2.IsValid() {
-				if rvk2.Type() == uint8SliceTyp {
-					rvk = reflect.ValueOf(d.string(rvk2.Bytes()))
-				} else {
-					rvk = rvk2
-				}
-			}
-		}
-
-		if elemsep {
-			dd.ReadMapElemValue()
-		}
-
-		// Brittle, but OK per TryDecodeAsNil() contract.
-		// i.e. TryDecodeAsNil never shares slices with other decDriver procedures
-		if dd.TryDecodeAsNil() {
-			if ktypeIsString {
-				rvk.SetString(d.string(kstrbs))
-			}
-			if d.h.DeleteOnNilMapValue {
-				rv.SetMapIndex(rvk, reflect.Value{})
-			} else {
-				rv.SetMapIndex(rvk, reflect.Zero(vtype))
-			}
-			continue
-		}
-
-		mapSet = true // set to false if u do a get, and its a non-nil pointer
-		if mapGet {
-			// mapGet true only in case where kind=Ptr|Interface or kind is otherwise mutable.
-			rvv = rv.MapIndex(rvk)
-			if !rvv.IsValid() {
-				rvv = reflect.New(vtype).Elem()
-			} else if vtypeKind == reflect.Ptr {
-				if rvv.IsNil() {
-					rvv = reflect.New(vtype).Elem()
-				} else {
-					mapSet = false
-				}
-			} else if vtypeKind == reflect.Interface {
-				// not addressable, and thus not settable.
-				// e MUST create a settable/addressable variant
-				rvv2 := reflect.New(rvv.Type()).Elem()
-				if !rvv.IsNil() {
-					rvv2.Set(rvv)
-				}
-				rvv = rvv2
-			}
-			// else it is ~mutable, and we can just decode into it directly
-		} else if rvvImmut {
-			if !rvz.IsValid() {
-				rvz = reflect.New(vtype).Elem()
-			}
-			rvv = rvz
-		} else {
-			rvv = reflect.New(vtype).Elem()
-		}
-
-		// We MUST be done with the stringview of the key, before decoding the value
-		// so that we don't bastardize the reused byte array.
-		if mapSet && ktypeIsString {
-			rvk.SetString(d.string(kstrbs))
-		}
-		if valFn == nil {
-			valFn = d.cf.get(vtypeLo, true, true)
-		}
-		d.decodeValue(rvv, valFn, true)
-		// d.decodeValueFn(rvv, valFn)
-		if mapSet {
-			rv.SetMapIndex(rvk, rvv)
-		}
-		// if ktypeIsString {
-		// 	// keepAlive4StringView(kstrbs) // not needed, as reference is outside loop
-		// }
-	}
-
-	dd.ReadMapEnd()
-}
-
-// decNaked is used to keep track of the primitives decoded.
-// Without it, we would have to decode each primitive and wrap it
-// in an interface{}, causing an allocation.
-// In this model, the primitives are decoded in a "pseudo-atomic" fashion,
-// so we can rest assured that no other decoding happens while these
-// primitives are being decoded.
-//
-// maps and arrays are not handled by this mechanism.
-// However, RawExt is, and we accommodate for extensions that decode
-// RawExt from DecodeNaked, but need to decode the value subsequently.
-// kInterfaceNaked and swallow, which call DecodeNaked, handle this caveat.
-//
-// However, decNaked also keeps some arrays of default maps and slices
-// used in DecodeNaked. This way, we can get a pointer to it
-// without causing a new heap allocation.
-//
-// kInterfaceNaked will ensure that there is no allocation for the common
-// uses.
-
-type decNakedContainers struct {
-	// array/stacks for reducing allocation
-	// keep arrays at the bottom? Chance is that they are not used much.
-	ia [arrayCacheLen]interface{}
-	ma [arrayCacheLen]map[interface{}]interface{}
-	na [arrayCacheLen]map[string]interface{}
-	sa [arrayCacheLen][]interface{}
-
-	// ria [arrayCacheLen]reflect.Value // not needed, as we decode directly into &ia[n]
-	rma, rna, rsa [arrayCacheLen]reflect.Value // reflect.Value mapping to above
-}
-
-func (n *decNakedContainers) init() {
-	for i := 0; i < arrayCacheLen; i++ {
-		// n.ria[i] = reflect.ValueOf(&(n.ia[i])).Elem()
-		n.rma[i] = reflect.ValueOf(&(n.ma[i])).Elem()
-		n.rna[i] = reflect.ValueOf(&(n.na[i])).Elem()
-		n.rsa[i] = reflect.ValueOf(&(n.sa[i])).Elem()
-	}
-}
-
-type decNaked struct {
-	// r RawExt // used for RawExt, uint, []byte.
-
-	// primitives below
-	u uint64
-	i int64
-	f float64
-	l []byte
-	s string
-
-	// ---- cpu cache line boundary?
-	t time.Time
-	b bool
-
-	// state
-	v              valueType
-	li, lm, ln, ls int8
-	inited         bool
-
-	*decNakedContainers
-
-	ru, ri, rf, rl, rs, rb, rt reflect.Value // mapping to the primitives above
-
-	// _ [6]uint64 // padding // no padding - rt goes into next cache line
-}
-
-func (n *decNaked) init() {
-	if n.inited {
-		return
-	}
-	n.ru = reflect.ValueOf(&n.u).Elem()
-	n.ri = reflect.ValueOf(&n.i).Elem()
-	n.rf = reflect.ValueOf(&n.f).Elem()
-	n.rl = reflect.ValueOf(&n.l).Elem()
-	n.rs = reflect.ValueOf(&n.s).Elem()
-	n.rt = reflect.ValueOf(&n.t).Elem()
-	n.rb = reflect.ValueOf(&n.b).Elem()
-
-	n.inited = true
-	// n.rr[] = reflect.ValueOf(&n.)
-}
-
-func (n *decNaked) initContainers() {
-	if n.decNakedContainers == nil {
-		n.decNakedContainers = new(decNakedContainers)
-		n.decNakedContainers.init()
-	}
-}
-
-func (n *decNaked) reset() {
-	if n == nil {
-		return
-	}
-	n.li, n.lm, n.ln, n.ls = 0, 0, 0, 0
-}
-
-type rtid2rv struct {
-	rtid uintptr
-	rv   reflect.Value
-}
-
-// --------------
-
-type decReaderSwitch struct {
-	rb bytesDecReader
-	// ---- cpu cache line boundary?
-	ri       *ioDecReader
-	mtr, str bool // whether maptype or slicetype are known types
-
-	be    bool // is binary encoding
-	bytes bool // is bytes reader
-	js    bool // is json handle
-	jsms  bool // is json handle, and MapKeyAsString
-	esep  bool // has elem separators
-}
-
-// TODO: Uncomment after mid-stack inlining enabled in go 1.11
-//
-// func (z *decReaderSwitch) unreadn1() {
-// 	if z.bytes {
-// 		z.rb.unreadn1()
-// 	} else {
-// 		z.ri.unreadn1()
-// 	}
-// }
-// func (z *decReaderSwitch) readx(n int) []byte {
-// 	if z.bytes {
-// 		return z.rb.readx(n)
-// 	}
-// 	return z.ri.readx(n)
-// }
-// func (z *decReaderSwitch) readb(s []byte) {
-// 	if z.bytes {
-// 		z.rb.readb(s)
-// 	} else {
-// 		z.ri.readb(s)
-// 	}
-// }
-// func (z *decReaderSwitch) readn1() uint8 {
-// 	if z.bytes {
-// 		return z.rb.readn1()
-// 	}
-// 	return z.ri.readn1()
-// }
-// func (z *decReaderSwitch) numread() int {
-// 	if z.bytes {
-// 		return z.rb.numread()
-// 	}
-// 	return z.ri.numread()
-// }
-// func (z *decReaderSwitch) track() {
-// 	if z.bytes {
-// 		z.rb.track()
-// 	} else {
-// 		z.ri.track()
-// 	}
-// }
-// func (z *decReaderSwitch) stopTrack() []byte {
-// 	if z.bytes {
-// 		return z.rb.stopTrack()
-// 	}
-// 	return z.ri.stopTrack()
-// }
-// func (z *decReaderSwitch) skip(accept *bitset256) (token byte) {
-// 	if z.bytes {
-// 		return z.rb.skip(accept)
-// 	}
-// 	return z.ri.skip(accept)
-// }
-// func (z *decReaderSwitch) readTo(in []byte, accept *bitset256) (out []byte) {
-// 	if z.bytes {
-// 		return z.rb.readTo(in, accept)
-// 	}
-// 	return z.ri.readTo(in, accept)
-// }
-// func (z *decReaderSwitch) readUntil(in []byte, stop byte) (out []byte) {
-// 	if z.bytes {
-// 		return z.rb.readUntil(in, stop)
-// 	}
-// 	return z.ri.readUntil(in, stop)
-// }
-
-// A Decoder reads and decodes an object from an input stream in the codec format.
-type Decoder struct {
-	panicHdl
-	// hopefully, reduce derefencing cost by laying the decReader inside the Decoder.
-	// Try to put things that go together to fit within a cache line (8 words).
-
-	d decDriver
-	// NOTE: Decoder shouldn't call it's read methods,
-	// as the handler MAY need to do some coordination.
-	r  decReader
-	h  *BasicHandle
-	bi *bufioDecReader
-	// cache the mapTypeId and sliceTypeId for faster comparisons
-	mtid uintptr
-	stid uintptr
-
-	// ---- cpu cache line boundary?
-	decReaderSwitch
-
-	// ---- cpu cache line boundary?
-	codecFnPooler
-	// cr containerStateRecv
-	n   *decNaked
-	nsp *sync.Pool
-	err error
-
-	// ---- cpu cache line boundary?
-	b  [decScratchByteArrayLen]byte // scratch buffer, used by Decoder and xxxEncDrivers
-	is map[string]string            // used for interning strings
-
-	// padding - false sharing help // modify 232 if Decoder struct changes.
-	// _ [cacheLineSize - 232%cacheLineSize]byte
-}
-
-// NewDecoder returns a Decoder for decoding a stream of bytes from an io.Reader.
-//
-// For efficiency, Users are encouraged to pass in a memory buffered reader
-// (eg bufio.Reader, bytes.Buffer).
-func NewDecoder(r io.Reader, h Handle) *Decoder {
-	d := newDecoder(h)
-	d.Reset(r)
-	return d
-}
-
-// NewDecoderBytes returns a Decoder which efficiently decodes directly
-// from a byte slice with zero copying.
-func NewDecoderBytes(in []byte, h Handle) *Decoder {
-	d := newDecoder(h)
-	d.ResetBytes(in)
-	return d
-}
-
-var defaultDecNaked decNaked
-
-func newDecoder(h Handle) *Decoder {
-	d := &Decoder{h: h.getBasicHandle(), err: errDecoderNotInitialized}
-	d.hh = h
-	d.be = h.isBinary()
-	// NOTE: do not initialize d.n here. It is lazily initialized in d.naked()
-	var jh *JsonHandle
-	jh, d.js = h.(*JsonHandle)
-	if d.js {
-		d.jsms = jh.MapKeyAsString
-	}
-	d.esep = d.hh.hasElemSeparators()
-	if d.h.InternString {
-		d.is = make(map[string]string, 32)
-	}
-	d.d = h.newDecDriver(d)
-	// d.cr, _ = d.d.(containerStateRecv)
-	return d
-}
-
-func (d *Decoder) resetCommon() {
-	d.n.reset()
-	d.d.reset()
-	d.err = nil
-	// reset all things which were cached from the Handle, but could change
-	d.mtid, d.stid = 0, 0
-	d.mtr, d.str = false, false
-	if d.h.MapType != nil {
-		d.mtid = rt2id(d.h.MapType)
-		d.mtr = fastpathAV.index(d.mtid) != -1
-	}
-	if d.h.SliceType != nil {
-		d.stid = rt2id(d.h.SliceType)
-		d.str = fastpathAV.index(d.stid) != -1
-	}
-}
-
-// Reset the Decoder with a new Reader to decode from,
-// clearing all state from last run(s).
-func (d *Decoder) Reset(r io.Reader) {
-	if r == nil {
-		return
-	}
-	if d.bi == nil {
-		d.bi = new(bufioDecReader)
-	}
-	d.bytes = false
-	if d.h.ReaderBufferSize > 0 {
-		d.bi.buf = make([]byte, 0, d.h.ReaderBufferSize)
-		d.bi.reset(r)
-		d.r = d.bi
-	} else {
-		// d.ri.x = &d.b
-		// d.s = d.sa[:0]
-		if d.ri == nil {
-			d.ri = new(ioDecReader)
-		}
-		d.ri.reset(r)
-		d.r = d.ri
-	}
-	d.resetCommon()
-}
-
-// ResetBytes resets the Decoder with a new []byte to decode from,
-// clearing all state from last run(s).
-func (d *Decoder) ResetBytes(in []byte) {
-	if in == nil {
-		return
-	}
-	d.bytes = true
-	d.rb.reset(in)
-	d.r = &d.rb
-	d.resetCommon()
-}
-
-// naked must be called before each call to .DecodeNaked,
-// as they will use it.
-func (d *Decoder) naked() *decNaked {
-	if d.n == nil {
-		// consider one of:
-		//   - get from sync.Pool  (if GC is frequent, there's no value here)
-		//   - new alloc           (safest. only init'ed if it a naked decode will be done)
-		//   - field in Decoder    (makes the Decoder struct very big)
-		// To support using a decoder where a DecodeNaked is not needed,
-		// we prefer #1 or #2.
-		// d.n = new(decNaked) // &d.nv // new(decNaked) // grab from a sync.Pool
-		// d.n.init()
-		var v interface{}
-		d.nsp, v = pool.decNaked()
-		d.n = v.(*decNaked)
-	}
-	return d.n
-}
-
-// Decode decodes the stream from reader and stores the result in the
-// value pointed to by v. v cannot be a nil pointer. v can also be
-// a reflect.Value of a pointer.
-//
-// Note that a pointer to a nil interface is not a nil pointer.
-// If you do not know what type of stream it is, pass in a pointer to a nil interface.
-// We will decode and store a value in that nil interface.
-//
-// Sample usages:
-//   // Decoding into a non-nil typed value
-//   var f float32
-//   err = codec.NewDecoder(r, handle).Decode(&f)
-//
-//   // Decoding into nil interface
-//   var v interface{}
-//   dec := codec.NewDecoder(r, handle)
-//   err = dec.Decode(&v)
-//
-// When decoding into a nil interface{}, we will decode into an appropriate value based
-// on the contents of the stream:
-//   - Numbers are decoded as float64, int64 or uint64.
-//   - Other values are decoded appropriately depending on the type:
-//     bool, string, []byte, time.Time, etc
-//   - Extensions are decoded as RawExt (if no ext function registered for the tag)
-// Configurations exist on the Handle to override defaults
-// (e.g. for MapType, SliceType and how to decode raw bytes).
-//
-// When decoding into a non-nil interface{} value, the mode of encoding is based on the
-// type of the value. When a value is seen:
-//   - If an extension is registered for it, call that extension function
-//   - If it implements BinaryUnmarshaler, call its UnmarshalBinary(data []byte) error
-//   - Else decode it based on its reflect.Kind
-//
-// There are some special rules when decoding into containers (slice/array/map/struct).
-// Decode will typically use the stream contents to UPDATE the container.
-//   - A map can be decoded from a stream map, by updating matching keys.
-//   - A slice can be decoded from a stream array,
-//     by updating the first n elements, where n is length of the stream.
-//   - A slice can be decoded from a stream map, by decoding as if
-//     it contains a sequence of key-value pairs.
-//   - A struct can be decoded from a stream map, by updating matching fields.
-//   - A struct can be decoded from a stream array,
-//     by updating fields as they occur in the struct (by index).
-//
-// When decoding a stream map or array with length of 0 into a nil map or slice,
-// we reset the destination map or slice to a zero-length value.
-//
-// However, when decoding a stream nil, we reset the destination container
-// to its "zero" value (e.g. nil for slice/map, etc).
-//
-// Note: we allow nil values in the stream anywhere except for map keys.
-// A nil value in the encoded stream where a map key is expected is treated as an error.
-func (d *Decoder) Decode(v interface{}) (err error) {
-	defer d.deferred(&err)
-	d.MustDecode(v)
-	return
-}
-
-// MustDecode is like Decode, but panics if unable to Decode.
-// This provides insight to the code location that triggered the error.
-func (d *Decoder) MustDecode(v interface{}) {
-	// TODO: Top-level: ensure that v is a pointer and not nil.
-	if d.err != nil {
-		panic(d.err)
-	}
-	if d.d.TryDecodeAsNil() {
-		setZero(v)
-	} else {
-		d.decode(v)
-	}
-	d.alwaysAtEnd()
-	// xprintf(">>>>>>>> >>>>>>>> num decFns: %v\n", d.cf.sn)
-}
-
-func (d *Decoder) deferred(err1 *error) {
-	d.alwaysAtEnd()
-	if recoverPanicToErr {
-		if x := recover(); x != nil {
-			panicValToErr(d, x, err1)
-			panicValToErr(d, x, &d.err)
-		}
-	}
-}
-
-func (d *Decoder) alwaysAtEnd() {
-	if d.n != nil {
-		// if n != nil, then nsp != nil (they are always set together)
-		d.nsp.Put(d.n)
-		d.n, d.nsp = nil, nil
-	}
-	d.codecFnPooler.alwaysAtEnd()
-}
-
-// // this is not a smart swallow, as it allocates objects and does unnecessary work.
-// func (d *Decoder) swallowViaHammer() {
-// 	var blank interface{}
-// 	d.decodeValueNoFn(reflect.ValueOf(&blank).Elem())
-// }
-
-func (d *Decoder) swallow() {
-	// smarter decode that just swallows the content
-	dd := d.d
-	if dd.TryDecodeAsNil() {
-		return
-	}
-	elemsep := d.esep
-	switch dd.ContainerType() {
-	case valueTypeMap:
-		containerLen := dd.ReadMapStart()
-		hasLen := containerLen >= 0
-		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-			// if clenGtEqualZero {if j >= containerLen {break} } else if dd.CheckBreak() {break}
-			if elemsep {
-				dd.ReadMapElemKey()
-			}
-			d.swallow()
-			if elemsep {
-				dd.ReadMapElemValue()
-			}
-			d.swallow()
-		}
-		dd.ReadMapEnd()
-	case valueTypeArray:
-		containerLen := dd.ReadArrayStart()
-		hasLen := containerLen >= 0
-		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-			if elemsep {
-				dd.ReadArrayElem()
-			}
-			d.swallow()
-		}
-		dd.ReadArrayEnd()
-	case valueTypeBytes:
-		dd.DecodeBytes(d.b[:], true)
-	case valueTypeString:
-		dd.DecodeStringAsBytes()
-	default:
-		// these are all primitives, which we can get from decodeNaked
-		// if RawExt using Value, complete the processing.
-		n := d.naked()
-		dd.DecodeNaked()
-		if n.v == valueTypeExt && n.l == nil {
-			n.initContainers()
-			if n.li < arrayCacheLen {
-				n.ia[n.li] = nil
-				n.li++
-				d.decode(&n.ia[n.li-1])
-				n.ia[n.li-1] = nil
-				n.li--
-			} else {
-				var v2 interface{}
-				d.decode(&v2)
-			}
-		}
-	}
-}
-
-func setZero(iv interface{}) {
-	if iv == nil || definitelyNil(iv) {
-		return
-	}
-	var canDecode bool
-	switch v := iv.(type) {
-	case *string:
-		*v = ""
-	case *bool:
-		*v = false
-	case *int:
-		*v = 0
-	case *int8:
-		*v = 0
-	case *int16:
-		*v = 0
-	case *int32:
-		*v = 0
-	case *int64:
-		*v = 0
-	case *uint:
-		*v = 0
-	case *uint8:
-		*v = 0
-	case *uint16:
-		*v = 0
-	case *uint32:
-		*v = 0
-	case *uint64:
-		*v = 0
-	case *float32:
-		*v = 0
-	case *float64:
-		*v = 0
-	case *[]uint8:
-		*v = nil
-	case *Raw:
-		*v = nil
-	case *time.Time:
-		*v = time.Time{}
-	case reflect.Value:
-		if v, canDecode = isDecodeable(v); canDecode && v.CanSet() {
-			v.Set(reflect.Zero(v.Type()))
-		} // TODO: else drain if chan, clear if map, set all to nil if slice???
-	default:
-		if !fastpathDecodeSetZeroTypeSwitch(iv) {
-			v := reflect.ValueOf(iv)
-			if v, canDecode = isDecodeable(v); canDecode && v.CanSet() {
-				v.Set(reflect.Zero(v.Type()))
-			} // TODO: else drain if chan, clear if map, set all to nil if slice???
-		}
-	}
-}
-
-func (d *Decoder) decode(iv interface{}) {
-	// check nil and interfaces explicitly,
-	// so that type switches just have a run of constant non-interface types.
-	if iv == nil {
-		d.errorstr(errstrCannotDecodeIntoNil)
-		return
-	}
-	if v, ok := iv.(Selfer); ok {
-		v.CodecDecodeSelf(d)
-		return
-	}
-
-	switch v := iv.(type) {
-	// case nil:
-	// case Selfer:
-
-	case reflect.Value:
-		v = d.ensureDecodeable(v)
-		d.decodeValue(v, nil, true)
-
-	case *string:
-		*v = d.d.DecodeString()
-	case *bool:
-		*v = d.d.DecodeBool()
-	case *int:
-		*v = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
-	case *int8:
-		*v = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
-	case *int16:
-		*v = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
-	case *int32:
-		*v = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
-	case *int64:
-		*v = d.d.DecodeInt64()
-	case *uint:
-		*v = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
-	case *uint8:
-		*v = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
-	case *uint16:
-		*v = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
-	case *uint32:
-		*v = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
-	case *uint64:
-		*v = d.d.DecodeUint64()
-	case *float32:
-		f64 := d.d.DecodeFloat64()
-		if chkOvf.Float32(f64) {
-			d.errorf("float32 overflow: %v", f64)
-		}
-		*v = float32(f64)
-	case *float64:
-		*v = d.d.DecodeFloat64()
-	case *[]uint8:
-		*v = d.d.DecodeBytes(*v, false)
-	case []uint8:
-		b := d.d.DecodeBytes(v, false)
-		if !(len(b) > 0 && len(b) == len(v) && &b[0] == &v[0]) {
-			copy(v, b)
-		}
-	case *time.Time:
-		*v = d.d.DecodeTime()
-	case *Raw:
-		*v = d.rawBytes()
-
-	case *interface{}:
-		d.decodeValue(reflect.ValueOf(iv).Elem(), nil, true)
-		// d.decodeValueNotNil(reflect.ValueOf(iv).Elem())
-
-	default:
-		if !fastpathDecodeTypeSwitch(iv, d) {
-			v := reflect.ValueOf(iv)
-			v = d.ensureDecodeable(v)
-			d.decodeValue(v, nil, false)
-			// d.decodeValueFallback(v)
-		}
-	}
-}
-
-func (d *Decoder) decodeValue(rv reflect.Value, fn *codecFn, chkAll bool) {
-	// If stream is not containing a nil value, then we can deref to the base
-	// non-pointer value, and decode into that.
-	var rvp reflect.Value
-	var rvpValid bool
-	if rv.Kind() == reflect.Ptr {
-		rvpValid = true
-		for {
-			if rv.IsNil() {
-				rv.Set(reflect.New(rv.Type().Elem()))
-			}
-			rvp = rv
-			rv = rv.Elem()
-			if rv.Kind() != reflect.Ptr {
-				break
-			}
-		}
-	}
-
-	if fn == nil {
-		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
-		fn = d.cfer().get(rv.Type(), chkAll, true) // chkAll, chkAll)
-	}
-	if fn.i.addrD {
-		if rvpValid {
-			fn.fd(d, &fn.i, rvp)
-		} else if rv.CanAddr() {
-			fn.fd(d, &fn.i, rv.Addr())
-		} else if !fn.i.addrF {
-			fn.fd(d, &fn.i, rv)
-		} else {
-			d.errorf("cannot decode into a non-pointer value")
-		}
-	} else {
-		fn.fd(d, &fn.i, rv)
-	}
-	// return rv
-}
-
-func (d *Decoder) structFieldNotFound(index int, rvkencname string) {
-	// NOTE: rvkencname may be a stringView, so don't pass it to another function.
-	if d.h.ErrorIfNoField {
-		if index >= 0 {
-			d.errorf("no matching struct field found when decoding stream array at index %v", index)
-			return
-		} else if rvkencname != "" {
-			d.errorf("no matching struct field found when decoding stream map with key " + rvkencname)
-			return
-		}
-	}
-	d.swallow()
-}
-
-func (d *Decoder) arrayCannotExpand(sliceLen, streamLen int) {
-	if d.h.ErrorIfNoArrayExpand {
-		d.errorf("cannot expand array len during decode from %v to %v", sliceLen, streamLen)
-	}
-}
-
-func isDecodeable(rv reflect.Value) (rv2 reflect.Value, canDecode bool) {
-	switch rv.Kind() {
-	case reflect.Array:
-		return rv, true
-	case reflect.Ptr:
-		if !rv.IsNil() {
-			return rv.Elem(), true
-		}
-	case reflect.Slice, reflect.Chan, reflect.Map:
-		if !rv.IsNil() {
-			return rv, true
-		}
-	}
-	return
-}
-
-func (d *Decoder) ensureDecodeable(rv reflect.Value) (rv2 reflect.Value) {
-	// decode can take any reflect.Value that is a inherently addressable i.e.
-	//   - array
-	//   - non-nil chan    (we will SEND to it)
-	//   - non-nil slice   (we will set its elements)
-	//   - non-nil map     (we will put into it)
-	//   - non-nil pointer (we can "update" it)
-	rv2, canDecode := isDecodeable(rv)
-	if canDecode {
-		return
-	}
-	if !rv.IsValid() {
-		d.errorstr(errstrCannotDecodeIntoNil)
-		return
-	}
-	if !rv.CanInterface() {
-		d.errorf("cannot decode into a value without an interface: %v", rv)
-		return
-	}
-	rvi := rv2i(rv)
-	rvk := rv.Kind()
-	d.errorf("cannot decode into value of kind: %v, type: %T, %v", rvk, rvi, rvi)
-	return
-}
-
-// Possibly get an interned version of a string
-//
-// This should mostly be used for map keys, where the key type is string.
-// This is because keys of a map/struct are typically reused across many objects.
-func (d *Decoder) string(v []byte) (s string) {
-	if d.is == nil {
-		return string(v) // don't return stringView, as we need a real string here.
-	}
-	s, ok := d.is[string(v)] // no allocation here, per go implementation
-	if !ok {
-		s = string(v) // new allocation here
-		d.is[s] = s
-	}
-	return s
-}
-
-// nextValueBytes returns the next value in the stream as a set of bytes.
-func (d *Decoder) nextValueBytes() (bs []byte) {
-	d.d.uncacheRead()
-	d.r.track()
-	d.swallow()
-	bs = d.r.stopTrack()
-	return
-}
-
-func (d *Decoder) rawBytes() []byte {
-	// ensure that this is not a view into the bytes
-	// i.e. make new copy always.
-	bs := d.nextValueBytes()
-	bs2 := make([]byte, len(bs))
-	copy(bs2, bs)
-	return bs2
-}
-
-func (d *Decoder) wrapErrstr(v interface{}, err *error) {
-	*err = fmt.Errorf("%s decode error [pos %d]: %v", d.hh.Name(), d.r.numread(), v)
-}
-
-// --------------------------------------------------
-
-// decSliceHelper assists when decoding into a slice, from a map or an array in the stream.
-// A slice can be set from a map or array in stream. This supports the MapBySlice interface.
-type decSliceHelper struct {
-	d *Decoder
-	// ct valueType
-	array bool
-}
-
-func (d *Decoder) decSliceHelperStart() (x decSliceHelper, clen int) {
-	dd := d.d
-	ctyp := dd.ContainerType()
-	switch ctyp {
-	case valueTypeArray:
-		x.array = true
-		clen = dd.ReadArrayStart()
-	case valueTypeMap:
-		clen = dd.ReadMapStart() * 2
-	default:
-		d.errorf("only encoded map or array can be decoded into a slice (%d)", ctyp)
-	}
-	// x.ct = ctyp
-	x.d = d
-	return
-}
-
-func (x decSliceHelper) End() {
-	if x.array {
-		x.d.d.ReadArrayEnd()
-	} else {
-		x.d.d.ReadMapEnd()
-	}
-}
-
-func (x decSliceHelper) ElemContainerState(index int) {
-	if x.array {
-		x.d.d.ReadArrayElem()
-	} else if index%2 == 0 {
-		x.d.d.ReadMapElemKey()
-	} else {
-		x.d.d.ReadMapElemValue()
-	}
-}
-
-func decByteSlice(r decReader, clen, maxInitLen int, bs []byte) (bsOut []byte) {
-	if clen == 0 {
-		return zeroByteSlice
-	}
-	if len(bs) == clen {
-		bsOut = bs
-		r.readb(bsOut)
-	} else if cap(bs) >= clen {
-		bsOut = bs[:clen]
-		r.readb(bsOut)
-	} else {
-		// bsOut = make([]byte, clen)
-		len2 := decInferLen(clen, maxInitLen, 1)
-		bsOut = make([]byte, len2)
-		r.readb(bsOut)
-		for len2 < clen {
-			len3 := decInferLen(clen-len2, maxInitLen, 1)
-			bs3 := bsOut
-			bsOut = make([]byte, len2+len3)
-			copy(bsOut, bs3)
-			r.readb(bsOut[len2:])
-			len2 += len3
-		}
-	}
-	return
-}
-
-func detachZeroCopyBytes(isBytesReader bool, dest []byte, in []byte) (out []byte) {
-	if xlen := len(in); xlen > 0 {
-		if isBytesReader || xlen <= scratchByteArrayLen {
-			if cap(dest) >= xlen {
-				out = dest[:xlen]
-			} else {
-				out = make([]byte, xlen)
-			}
-			copy(out, in)
-			return
-		}
-	}
-	return in
-}
-
-// decInferLen will infer a sensible length, given the following:
-//    - clen: length wanted.
-//    - maxlen: max length to be returned.
-//      if <= 0, it is unset, and we infer it based on the unit size
-//    - unit: number of bytes for each element of the collection
-func decInferLen(clen, maxlen, unit int) (rvlen int) {
-	// handle when maxlen is not set i.e. <= 0
-	if clen <= 0 {
-		return
-	}
-	if unit == 0 {
-		return clen
-	}
-	if maxlen <= 0 {
-		// no maxlen defined. Use maximum of 256K memory, with a floor of 4K items.
-		// maxlen = 256 * 1024 / unit
-		// if maxlen < (4 * 1024) {
-		// 	maxlen = 4 * 1024
-		// }
-		if unit < (256 / 4) {
-			maxlen = 256 * 1024 / unit
-		} else {
-			maxlen = 4 * 1024
-		}
-	}
-	if clen > maxlen {
-		rvlen = maxlen
-	} else {
-		rvlen = clen
-	}
-	return
-}
-
-func expandSliceRV(s reflect.Value, st reflect.Type, canChange bool, stElemSize, num, slen, scap int) (
-	s2 reflect.Value, scap2 int, changed bool, err string) {
-	l1 := slen + num // new slice length
-	if l1 < slen {
-		err = errmsgExpandSliceOverflow
-		return
-	}
-	if l1 <= scap {
-		if s.CanSet() {
-			s.SetLen(l1)
-		} else if canChange {
-			s2 = s.Slice(0, l1)
-			scap2 = scap
-			changed = true
-		} else {
-			err = errmsgExpandSliceCannotChange
-			return
-		}
-		return
-	}
-	if !canChange {
-		err = errmsgExpandSliceCannotChange
-		return
-	}
-	scap2 = growCap(scap, stElemSize, num)
-	s2 = reflect.MakeSlice(st, l1, scap2)
-	changed = true
-	reflect.Copy(s2, s)
-	return
-}
-
-func decReadFull(r io.Reader, bs []byte) (n int, err error) {
-	var nn int
-	for n < len(bs) && err == nil {
-		nn, err = r.Read(bs[n:])
-		if nn > 0 {
-			if err == io.EOF {
-				// leave EOF for next time
-				err = nil
-			}
-			n += nn
-		}
-	}
-
-	// do not do this - it serves no purpose
-	// if n != len(bs) && err == io.EOF { err = io.ErrUnexpectedEOF }
-	return
-}
diff --git a/vendor/github.com/ugorji/go/codec/encode.go b/vendor/github.com/ugorji/go/codec/encode.go
deleted file mode 100644
index ef46529..0000000
--- a/vendor/github.com/ugorji/go/codec/encode.go
+++ /dev/null
@@ -1,1375 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"bufio"
-	"encoding"
-	"errors"
-	"fmt"
-	"io"
-	"reflect"
-	"sort"
-	"strconv"
-	"sync"
-	"time"
-)
-
-const defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
-
-var errEncoderNotInitialized = errors.New("Encoder not initialized")
-
-// encWriter abstracts writing to a byte array or to an io.Writer.
-type encWriter interface {
-	writeb([]byte)
-	writestr(string)
-	writen1(byte)
-	writen2(byte, byte)
-	atEndOfEncode()
-}
-
-// encDriver abstracts the actual codec (binc vs msgpack, etc)
-type encDriver interface {
-	EncodeNil()
-	EncodeInt(i int64)
-	EncodeUint(i uint64)
-	EncodeBool(b bool)
-	EncodeFloat32(f float32)
-	EncodeFloat64(f float64)
-	// encodeExtPreamble(xtag byte, length int)
-	EncodeRawExt(re *RawExt, e *Encoder)
-	EncodeExt(v interface{}, xtag uint64, ext Ext, e *Encoder)
-	EncodeString(c charEncoding, v string)
-	// EncodeSymbol(v string)
-	EncodeStringBytes(c charEncoding, v []byte)
-	EncodeTime(time.Time)
-	//encBignum(f *big.Int)
-	//encStringRunes(c charEncoding, v []rune)
-	WriteArrayStart(length int)
-	WriteArrayElem()
-	WriteArrayEnd()
-	WriteMapStart(length int)
-	WriteMapElemKey()
-	WriteMapElemValue()
-	WriteMapEnd()
-
-	reset()
-	atEndOfEncode()
-}
-
-type ioEncStringWriter interface {
-	WriteString(s string) (n int, err error)
-}
-
-type encDriverAsis interface {
-	EncodeAsis(v []byte)
-}
-
-type encDriverNoopContainerWriter struct{}
-
-func (encDriverNoopContainerWriter) WriteArrayStart(length int) {}
-func (encDriverNoopContainerWriter) WriteArrayElem()            {}
-func (encDriverNoopContainerWriter) WriteArrayEnd()             {}
-func (encDriverNoopContainerWriter) WriteMapStart(length int)   {}
-func (encDriverNoopContainerWriter) WriteMapElemKey()           {}
-func (encDriverNoopContainerWriter) WriteMapElemValue()         {}
-func (encDriverNoopContainerWriter) WriteMapEnd()               {}
-func (encDriverNoopContainerWriter) atEndOfEncode()             {}
-
-type encDriverTrackContainerWriter struct {
-	c containerState
-}
-
-func (e *encDriverTrackContainerWriter) WriteArrayStart(length int) { e.c = containerArrayStart }
-func (e *encDriverTrackContainerWriter) WriteArrayElem()            { e.c = containerArrayElem }
-func (e *encDriverTrackContainerWriter) WriteArrayEnd()             { e.c = containerArrayEnd }
-func (e *encDriverTrackContainerWriter) WriteMapStart(length int)   { e.c = containerMapStart }
-func (e *encDriverTrackContainerWriter) WriteMapElemKey()           { e.c = containerMapKey }
-func (e *encDriverTrackContainerWriter) WriteMapElemValue()         { e.c = containerMapValue }
-func (e *encDriverTrackContainerWriter) WriteMapEnd()               { e.c = containerMapEnd }
-func (e *encDriverTrackContainerWriter) atEndOfEncode()             {}
-
-// type ioEncWriterWriter interface {
-// 	WriteByte(c byte) error
-// 	WriteString(s string) (n int, err error)
-// 	Write(p []byte) (n int, err error)
-// }
-
-// EncodeOptions captures configuration options during encode.
-type EncodeOptions struct {
-	// WriterBufferSize is the size of the buffer used when writing.
-	//
-	// if > 0, we use a smart buffer internally for performance purposes.
-	WriterBufferSize int
-
-	// ChanRecvTimeout is the timeout used when selecting from a chan.
-	//
-	// Configuring this controls how we receive from a chan during the encoding process.
-	//   - If ==0, we only consume the elements currently available in the chan.
-	//   - if  <0, we consume until the chan is closed.
-	//   - If  >0, we consume until this timeout.
-	ChanRecvTimeout time.Duration
-
-	// StructToArray specifies to encode a struct as an array, and not as a map
-	StructToArray bool
-
-	// Canonical representation means that encoding a value will always result in the same
-	// sequence of bytes.
-	//
-	// This only affects maps, as the iteration order for maps is random.
-	//
-	// The implementation MAY use the natural sort order for the map keys if possible:
-	//
-	//     - If there is a natural sort order (ie for number, bool, string or []byte keys),
-	//       then the map keys are first sorted in natural order and then written
-	//       with corresponding map values to the strema.
-	//     - If there is no natural sort order, then the map keys will first be
-	//       encoded into []byte, and then sorted,
-	//       before writing the sorted keys and the corresponding map values to the stream.
-	//
-	Canonical bool
-
-	// CheckCircularRef controls whether we check for circular references
-	// and error fast during an encode.
-	//
-	// If enabled, an error is received if a pointer to a struct
-	// references itself either directly or through one of its fields (iteratively).
-	//
-	// This is opt-in, as there may be a performance hit to checking circular references.
-	CheckCircularRef bool
-
-	// RecursiveEmptyCheck controls whether we descend into interfaces, structs and pointers
-	// when checking if a value is empty.
-	//
-	// Note that this may make OmitEmpty more expensive, as it incurs a lot more reflect calls.
-	RecursiveEmptyCheck bool
-
-	// Raw controls whether we encode Raw values.
-	// This is a "dangerous" option and must be explicitly set.
-	// If set, we blindly encode Raw values as-is, without checking
-	// if they are a correct representation of a value in that format.
-	// If unset, we error out.
-	Raw bool
-
-	// // AsSymbols defines what should be encoded as symbols.
-	// //
-	// // Encoding as symbols can reduce the encoded size significantly.
-	// //
-	// // However, during decoding, each string to be encoded as a symbol must
-	// // be checked to see if it has been seen before. Consequently, encoding time
-	// // will increase if using symbols, because string comparisons has a clear cost.
-	// //
-	// // Sample values:
-	// //   AsSymbolNone
-	// //   AsSymbolAll
-	// //   AsSymbolMapStringKeys
-	// //   AsSymbolMapStringKeysFlag | AsSymbolStructFieldNameFlag
-	// AsSymbols AsSymbolFlag
-}
-
-// ---------------------------------------------
-
-// ioEncWriter implements encWriter and can write to an io.Writer implementation
-type ioEncWriter struct {
-	w  io.Writer
-	ww io.Writer
-	bw io.ByteWriter
-	sw ioEncStringWriter
-	fw ioFlusher
-	b  [8]byte
-}
-
-func (z *ioEncWriter) WriteByte(b byte) (err error) {
-	z.b[0] = b
-	_, err = z.w.Write(z.b[:1])
-	return
-}
-
-func (z *ioEncWriter) WriteString(s string) (n int, err error) {
-	return z.w.Write(bytesView(s))
-}
-
-func (z *ioEncWriter) writeb(bs []byte) {
-	if _, err := z.ww.Write(bs); err != nil {
-		panic(err)
-	}
-}
-
-func (z *ioEncWriter) writestr(s string) {
-	if _, err := z.sw.WriteString(s); err != nil {
-		panic(err)
-	}
-}
-
-func (z *ioEncWriter) writen1(b byte) {
-	if err := z.bw.WriteByte(b); err != nil {
-		panic(err)
-	}
-}
-
-func (z *ioEncWriter) writen2(b1, b2 byte) {
-	var err error
-	if err = z.bw.WriteByte(b1); err == nil {
-		if err = z.bw.WriteByte(b2); err == nil {
-			return
-		}
-	}
-	panic(err)
-}
-
-// func (z *ioEncWriter) writen5(b1, b2, b3, b4, b5 byte) {
-// 	z.b[0], z.b[1], z.b[2], z.b[3], z.b[4] = b1, b2, b3, b4, b5
-// 	if _, err := z.ww.Write(z.b[:5]); err != nil {
-// 		panic(err)
-// 	}
-// }
-
-func (z *ioEncWriter) atEndOfEncode() {
-	if z.fw != nil {
-		if err := z.fw.Flush(); err != nil {
-			panic(err)
-		}
-	}
-}
-
-// ---------------------------------------------
-
-// bytesEncAppender implements encWriter and can write to an byte slice.
-type bytesEncAppender struct {
-	b   []byte
-	out *[]byte
-}
-
-func (z *bytesEncAppender) writeb(s []byte) {
-	z.b = append(z.b, s...)
-}
-func (z *bytesEncAppender) writestr(s string) {
-	z.b = append(z.b, s...)
-}
-func (z *bytesEncAppender) writen1(b1 byte) {
-	z.b = append(z.b, b1)
-}
-func (z *bytesEncAppender) writen2(b1, b2 byte) {
-	z.b = append(z.b, b1, b2)
-}
-func (z *bytesEncAppender) atEndOfEncode() {
-	*(z.out) = z.b
-}
-func (z *bytesEncAppender) reset(in []byte, out *[]byte) {
-	z.b = in[:0]
-	z.out = out
-}
-
-// ---------------------------------------------
-
-func (e *Encoder) rawExt(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeRawExt(rv2i(rv).(*RawExt), e)
-}
-
-func (e *Encoder) ext(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeExt(rv2i(rv), f.xfTag, f.xfFn, e)
-}
-
-func (e *Encoder) selferMarshal(f *codecFnInfo, rv reflect.Value) {
-	rv2i(rv).(Selfer).CodecEncodeSelf(e)
-}
-
-func (e *Encoder) binaryMarshal(f *codecFnInfo, rv reflect.Value) {
-	bs, fnerr := rv2i(rv).(encoding.BinaryMarshaler).MarshalBinary()
-	e.marshal(bs, fnerr, false, cRAW)
-}
-
-func (e *Encoder) textMarshal(f *codecFnInfo, rv reflect.Value) {
-	bs, fnerr := rv2i(rv).(encoding.TextMarshaler).MarshalText()
-	e.marshal(bs, fnerr, false, cUTF8)
-}
-
-func (e *Encoder) jsonMarshal(f *codecFnInfo, rv reflect.Value) {
-	bs, fnerr := rv2i(rv).(jsonMarshaler).MarshalJSON()
-	e.marshal(bs, fnerr, true, cUTF8)
-}
-
-func (e *Encoder) raw(f *codecFnInfo, rv reflect.Value) {
-	e.rawBytes(rv2i(rv).(Raw))
-}
-
-func (e *Encoder) kInvalid(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeNil()
-}
-
-func (e *Encoder) kErr(f *codecFnInfo, rv reflect.Value) {
-	e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv)
-}
-
-func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
-	ti := f.ti
-	ee := e.e
-	// array may be non-addressable, so we have to manage with care
-	//   (don't call rv.Bytes, rv.Slice, etc).
-	// E.g. type struct S{B [2]byte};
-	//   Encode(S{}) will bomb on "panic: slice of unaddressable array".
-	if f.seq != seqTypeArray {
-		if rv.IsNil() {
-			ee.EncodeNil()
-			return
-		}
-		// If in this method, then there was no extension function defined.
-		// So it's okay to treat as []byte.
-		if ti.rtid == uint8SliceTypId {
-			ee.EncodeStringBytes(cRAW, rv.Bytes())
-			return
-		}
-	}
-	if f.seq == seqTypeChan && ti.chandir&uint8(reflect.RecvDir) == 0 {
-		e.errorf("send-only channel cannot be encoded")
-	}
-	elemsep := e.esep
-	rtelem := ti.elem
-	rtelemIsByte := uint8TypId == rt2id(rtelem) // NOT rtelem.Kind() == reflect.Uint8
-	var l int
-	// if a slice, array or chan of bytes, treat specially
-	if rtelemIsByte {
-		switch f.seq {
-		case seqTypeSlice:
-			ee.EncodeStringBytes(cRAW, rv.Bytes())
-		case seqTypeArray:
-			l = rv.Len()
-			if rv.CanAddr() {
-				ee.EncodeStringBytes(cRAW, rv.Slice(0, l).Bytes())
-			} else {
-				var bs []byte
-				if l <= cap(e.b) {
-					bs = e.b[:l]
-				} else {
-					bs = make([]byte, l)
-				}
-				reflect.Copy(reflect.ValueOf(bs), rv)
-				ee.EncodeStringBytes(cRAW, bs)
-			}
-		case seqTypeChan:
-			// do not use range, so that the number of elements encoded
-			// does not change, and encoding does not hang waiting on someone to close chan.
-			// for b := range rv2i(rv).(<-chan byte) { bs = append(bs, b) }
-			// ch := rv2i(rv).(<-chan byte) // fix error - that this is a chan byte, not a <-chan byte.
-
-			if rv.IsNil() {
-				ee.EncodeNil()
-				break
-			}
-			bs := e.b[:0]
-			irv := rv2i(rv)
-			ch, ok := irv.(<-chan byte)
-			if !ok {
-				ch = irv.(chan byte)
-			}
-
-		L1:
-			switch timeout := e.h.ChanRecvTimeout; {
-			case timeout == 0: // only consume available
-				for {
-					select {
-					case b := <-ch:
-						bs = append(bs, b)
-					default:
-						break L1
-					}
-				}
-			case timeout > 0: // consume until timeout
-				tt := time.NewTimer(timeout)
-				for {
-					select {
-					case b := <-ch:
-						bs = append(bs, b)
-					case <-tt.C:
-						// close(tt.C)
-						break L1
-					}
-				}
-			default: // consume until close
-				for b := range ch {
-					bs = append(bs, b)
-				}
-			}
-
-			ee.EncodeStringBytes(cRAW, bs)
-		}
-		return
-	}
-
-	// if chan, consume chan into a slice, and work off that slice.
-	var rvcs reflect.Value
-	if f.seq == seqTypeChan {
-		rvcs = reflect.Zero(reflect.SliceOf(rtelem))
-		timeout := e.h.ChanRecvTimeout
-		if timeout < 0 { // consume until close
-			for {
-				recv, recvOk := rv.Recv()
-				if !recvOk {
-					break
-				}
-				rvcs = reflect.Append(rvcs, recv)
-			}
-		} else {
-			cases := make([]reflect.SelectCase, 2)
-			cases[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: rv}
-			if timeout == 0 {
-				cases[1] = reflect.SelectCase{Dir: reflect.SelectDefault}
-			} else {
-				tt := time.NewTimer(timeout)
-				cases[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(tt.C)}
-			}
-			for {
-				chosen, recv, recvOk := reflect.Select(cases)
-				if chosen == 1 || !recvOk {
-					break
-				}
-				rvcs = reflect.Append(rvcs, recv)
-			}
-		}
-		rv = rvcs // TODO: ensure this doesn't mess up anywhere that rv of kind chan is expected
-	}
-
-	l = rv.Len()
-	if ti.mbs {
-		if l%2 == 1 {
-			e.errorf("mapBySlice requires even slice length, but got %v", l)
-			return
-		}
-		ee.WriteMapStart(l / 2)
-	} else {
-		ee.WriteArrayStart(l)
-	}
-
-	if l > 0 {
-		var fn *codecFn
-		for rtelem.Kind() == reflect.Ptr {
-			rtelem = rtelem.Elem()
-		}
-		// if kind is reflect.Interface, do not pre-determine the
-		// encoding type, because preEncodeValue may break it down to
-		// a concrete type and kInterface will bomb.
-		if rtelem.Kind() != reflect.Interface {
-			fn = e.cfer().get(rtelem, true, true)
-		}
-		for j := 0; j < l; j++ {
-			if elemsep {
-				if ti.mbs {
-					if j%2 == 0 {
-						ee.WriteMapElemKey()
-					} else {
-						ee.WriteMapElemValue()
-					}
-				} else {
-					ee.WriteArrayElem()
-				}
-			}
-			e.encodeValue(rv.Index(j), fn, true)
-		}
-	}
-
-	if ti.mbs {
-		ee.WriteMapEnd()
-	} else {
-		ee.WriteArrayEnd()
-	}
-}
-
-func (e *Encoder) kStructNoOmitempty(f *codecFnInfo, rv reflect.Value) {
-	fti := f.ti
-	elemsep := e.esep
-	tisfi := fti.sfiSrc
-	toMap := !(fti.toArray || e.h.StructToArray)
-	if toMap {
-		tisfi = fti.sfiSort
-	}
-	ee := e.e
-
-	sfn := structFieldNode{v: rv, update: false}
-	if toMap {
-		ee.WriteMapStart(len(tisfi))
-		if elemsep {
-			for _, si := range tisfi {
-				ee.WriteMapElemKey()
-				// ee.EncodeString(cUTF8, si.encName)
-				encStructFieldKey(ee, fti.keyType, si.encName)
-				ee.WriteMapElemValue()
-				e.encodeValue(sfn.field(si), nil, true)
-			}
-		} else {
-			for _, si := range tisfi {
-				// ee.EncodeString(cUTF8, si.encName)
-				encStructFieldKey(ee, fti.keyType, si.encName)
-				e.encodeValue(sfn.field(si), nil, true)
-			}
-		}
-		ee.WriteMapEnd()
-	} else {
-		ee.WriteArrayStart(len(tisfi))
-		if elemsep {
-			for _, si := range tisfi {
-				ee.WriteArrayElem()
-				e.encodeValue(sfn.field(si), nil, true)
-			}
-		} else {
-			for _, si := range tisfi {
-				e.encodeValue(sfn.field(si), nil, true)
-			}
-		}
-		ee.WriteArrayEnd()
-	}
-}
-
-func encStructFieldKey(ee encDriver, keyType valueType, s string) {
-	var m must
-
-	// use if-else-if, not switch (which compiles to binary-search)
-	// since keyType is typically valueTypeString, branch prediction is pretty good.
-
-	if keyType == valueTypeString {
-		ee.EncodeString(cUTF8, s)
-	} else if keyType == valueTypeInt {
-		ee.EncodeInt(m.Int(strconv.ParseInt(s, 10, 64)))
-	} else if keyType == valueTypeUint {
-		ee.EncodeUint(m.Uint(strconv.ParseUint(s, 10, 64)))
-	} else if keyType == valueTypeFloat {
-		ee.EncodeFloat64(m.Float(strconv.ParseFloat(s, 64)))
-	} else {
-		ee.EncodeString(cUTF8, s)
-	}
-}
-
-func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
-	fti := f.ti
-	elemsep := e.esep
-	tisfi := fti.sfiSrc
-	toMap := !(fti.toArray || e.h.StructToArray)
-	// if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct)
-	if toMap {
-		tisfi = fti.sfiSort
-	}
-	newlen := len(fti.sfiSort)
-	ee := e.e
-
-	// Use sync.Pool to reduce allocating slices unnecessarily.
-	// The cost of sync.Pool is less than the cost of new allocation.
-	//
-	// Each element of the array pools one of encStructPool(8|16|32|64).
-	// It allows the re-use of slices up to 64 in length.
-	// A performance cost of encoding structs was collecting
-	// which values were empty and should be omitted.
-	// We needed slices of reflect.Value and string to collect them.
-	// This shared pool reduces the amount of unnecessary creation we do.
-	// The cost is that of locking sometimes, but sync.Pool is efficient
-	// enough to reduce thread contention.
-
-	var spool *sync.Pool
-	var poolv interface{}
-	var fkvs []stringRv
-	// fmt.Printf(">>>>>>>>>>>>>> encode.kStruct: newlen: %d\n", newlen)
-	if newlen <= 8 {
-		spool, poolv = pool.stringRv8()
-		fkvs = poolv.(*[8]stringRv)[:newlen]
-	} else if newlen <= 16 {
-		spool, poolv = pool.stringRv16()
-		fkvs = poolv.(*[16]stringRv)[:newlen]
-	} else if newlen <= 32 {
-		spool, poolv = pool.stringRv32()
-		fkvs = poolv.(*[32]stringRv)[:newlen]
-	} else if newlen <= 64 {
-		spool, poolv = pool.stringRv64()
-		fkvs = poolv.(*[64]stringRv)[:newlen]
-	} else if newlen <= 128 {
-		spool, poolv = pool.stringRv128()
-		fkvs = poolv.(*[128]stringRv)[:newlen]
-	} else {
-		fkvs = make([]stringRv, newlen)
-	}
-
-	newlen = 0
-	var kv stringRv
-	recur := e.h.RecursiveEmptyCheck
-	sfn := structFieldNode{v: rv, update: false}
-	for _, si := range tisfi {
-		// kv.r = si.field(rv, false)
-		kv.r = sfn.field(si)
-		if toMap {
-			if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
-				continue
-			}
-			kv.v = si.encName
-		} else {
-			// use the zero value.
-			// if a reference or struct, set to nil (so you do not output too much)
-			if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
-				switch kv.r.Kind() {
-				case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice:
-					kv.r = reflect.Value{} //encode as nil
-				}
-			}
-		}
-		fkvs[newlen] = kv
-		newlen++
-	}
-
-	if toMap {
-		ee.WriteMapStart(newlen)
-		if elemsep {
-			for j := 0; j < newlen; j++ {
-				kv = fkvs[j]
-				ee.WriteMapElemKey()
-				// ee.EncodeString(cUTF8, kv.v)
-				encStructFieldKey(ee, fti.keyType, kv.v)
-				ee.WriteMapElemValue()
-				e.encodeValue(kv.r, nil, true)
-			}
-		} else {
-			for j := 0; j < newlen; j++ {
-				kv = fkvs[j]
-				// ee.EncodeString(cUTF8, kv.v)
-				encStructFieldKey(ee, fti.keyType, kv.v)
-				e.encodeValue(kv.r, nil, true)
-			}
-		}
-		ee.WriteMapEnd()
-	} else {
-		ee.WriteArrayStart(newlen)
-		if elemsep {
-			for j := 0; j < newlen; j++ {
-				ee.WriteArrayElem()
-				e.encodeValue(fkvs[j].r, nil, true)
-			}
-		} else {
-			for j := 0; j < newlen; j++ {
-				e.encodeValue(fkvs[j].r, nil, true)
-			}
-		}
-		ee.WriteArrayEnd()
-	}
-
-	// do not use defer. Instead, use explicit pool return at end of function.
-	// defer has a cost we are trying to avoid.
-	// If there is a panic and these slices are not returned, it is ok.
-	if spool != nil {
-		spool.Put(poolv)
-	}
-}
-
-func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
-	ee := e.e
-	if rv.IsNil() {
-		ee.EncodeNil()
-		return
-	}
-
-	l := rv.Len()
-	ee.WriteMapStart(l)
-	elemsep := e.esep
-	if l == 0 {
-		ee.WriteMapEnd()
-		return
-	}
-	// var asSymbols bool
-	// determine the underlying key and val encFn's for the map.
-	// This eliminates some work which is done for each loop iteration i.e.
-	// rv.Type(), ref.ValueOf(rt).Pointer(), then check map/list for fn.
-	//
-	// However, if kind is reflect.Interface, do not pre-determine the
-	// encoding type, because preEncodeValue may break it down to
-	// a concrete type and kInterface will bomb.
-	var keyFn, valFn *codecFn
-	ti := f.ti
-	rtkey0 := ti.key
-	rtkey := rtkey0
-	rtval0 := ti.elem
-	rtval := rtval0
-	// rtkeyid := rt2id(rtkey0)
-	for rtval.Kind() == reflect.Ptr {
-		rtval = rtval.Elem()
-	}
-	if rtval.Kind() != reflect.Interface {
-		valFn = e.cfer().get(rtval, true, true)
-	}
-	mks := rv.MapKeys()
-
-	if e.h.Canonical {
-		e.kMapCanonical(rtkey, rv, mks, valFn)
-		ee.WriteMapEnd()
-		return
-	}
-
-	var keyTypeIsString = stringTypId == rt2id(rtkey0) // rtkeyid
-	if !keyTypeIsString {
-		for rtkey.Kind() == reflect.Ptr {
-			rtkey = rtkey.Elem()
-		}
-		if rtkey.Kind() != reflect.Interface {
-			// rtkeyid = rt2id(rtkey)
-			keyFn = e.cfer().get(rtkey, true, true)
-		}
-	}
-
-	// for j, lmks := 0, len(mks); j < lmks; j++ {
-	for j := range mks {
-		if elemsep {
-			ee.WriteMapElemKey()
-		}
-		if keyTypeIsString {
-			ee.EncodeString(cUTF8, mks[j].String())
-		} else {
-			e.encodeValue(mks[j], keyFn, true)
-		}
-		if elemsep {
-			ee.WriteMapElemValue()
-		}
-		e.encodeValue(rv.MapIndex(mks[j]), valFn, true)
-
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) kMapCanonical(rtkey reflect.Type, rv reflect.Value, mks []reflect.Value, valFn *codecFn) {
-	ee := e.e
-	elemsep := e.esep
-	// we previously did out-of-band if an extension was registered.
-	// This is not necessary, as the natural kind is sufficient for ordering.
-
-	switch rtkey.Kind() {
-	case reflect.Bool:
-		mksv := make([]boolRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Bool()
-		}
-		sort.Sort(boolRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeBool(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.String:
-		mksv := make([]stringRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.String()
-		}
-		sort.Sort(stringRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeString(cUTF8, mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
-		mksv := make([]uintRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Uint()
-		}
-		sort.Sort(uintRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeUint(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
-		mksv := make([]intRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Int()
-		}
-		sort.Sort(intRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeInt(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Float32:
-		mksv := make([]floatRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Float()
-		}
-		sort.Sort(floatRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeFloat32(float32(mksv[i].v))
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Float64:
-		mksv := make([]floatRv, len(mks))
-		for i, k := range mks {
-			v := &mksv[i]
-			v.r = k
-			v.v = k.Float()
-		}
-		sort.Sort(floatRvSlice(mksv))
-		for i := range mksv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			ee.EncodeFloat64(mksv[i].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-		}
-	case reflect.Struct:
-		if rv.Type() == timeTyp {
-			mksv := make([]timeRv, len(mks))
-			for i, k := range mks {
-				v := &mksv[i]
-				v.r = k
-				v.v = rv2i(k).(time.Time)
-			}
-			sort.Sort(timeRvSlice(mksv))
-			for i := range mksv {
-				if elemsep {
-					ee.WriteMapElemKey()
-				}
-				ee.EncodeTime(mksv[i].v)
-				if elemsep {
-					ee.WriteMapElemValue()
-				}
-				e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
-			}
-			break
-		}
-		fallthrough
-	default:
-		// out-of-band
-		// first encode each key to a []byte first, then sort them, then record
-		var mksv []byte = make([]byte, 0, len(mks)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		mksbv := make([]bytesRv, len(mks))
-		for i, k := range mks {
-			v := &mksbv[i]
-			l := len(mksv)
-			e2.MustEncode(k)
-			v.r = k
-			v.v = mksv[l:]
-		}
-		sort.Sort(bytesRvSlice(mksbv))
-		for j := range mksbv {
-			if elemsep {
-				ee.WriteMapElemKey()
-			}
-			e.asis(mksbv[j].v)
-			if elemsep {
-				ee.WriteMapElemValue()
-			}
-			e.encodeValue(rv.MapIndex(mksbv[j].r), valFn, true)
-		}
-	}
-}
-
-// // --------------------------------------------------
-
-type encWriterSwitch struct {
-	wi *ioEncWriter
-	// wb bytesEncWriter
-	wb   bytesEncAppender
-	wx   bool // if bytes, wx=true
-	esep bool // whether it has elem separators
-	isas bool // whether e.as != nil
-}
-
-// // TODO: Uncomment after mid-stack inlining enabled in go 1.11
-
-// func (z *encWriterSwitch) writeb(s []byte) {
-// 	if z.wx {
-// 		z.wb.writeb(s)
-// 	} else {
-// 		z.wi.writeb(s)
-// 	}
-// }
-// func (z *encWriterSwitch) writestr(s string) {
-// 	if z.wx {
-// 		z.wb.writestr(s)
-// 	} else {
-// 		z.wi.writestr(s)
-// 	}
-// }
-// func (z *encWriterSwitch) writen1(b1 byte) {
-// 	if z.wx {
-// 		z.wb.writen1(b1)
-// 	} else {
-// 		z.wi.writen1(b1)
-// 	}
-// }
-// func (z *encWriterSwitch) writen2(b1, b2 byte) {
-// 	if z.wx {
-// 		z.wb.writen2(b1, b2)
-// 	} else {
-// 		z.wi.writen2(b1, b2)
-// 	}
-// }
-
-// An Encoder writes an object to an output stream in the codec format.
-type Encoder struct {
-	panicHdl
-	// hopefully, reduce derefencing cost by laying the encWriter inside the Encoder
-	e encDriver
-	// NOTE: Encoder shouldn't call it's write methods,
-	// as the handler MAY need to do some coordination.
-	w encWriter
-
-	h  *BasicHandle
-	bw *bufio.Writer
-	as encDriverAsis
-
-	// ---- cpu cache line boundary?
-
-	// ---- cpu cache line boundary?
-	encWriterSwitch
-	err error
-
-	// ---- cpu cache line boundary?
-	codecFnPooler
-	ci set
-	js bool    // here, so that no need to piggy back on *codecFner for this
-	be bool    // here, so that no need to piggy back on *codecFner for this
-	_  [6]byte // padding
-
-	// ---- writable fields during execution --- *try* to keep in sep cache line
-
-	// ---- cpu cache line boundary?
-	// b [scratchByteArrayLen]byte
-	// _ [cacheLineSize - scratchByteArrayLen]byte // padding
-	b [cacheLineSize - 0]byte // used for encoding a chan or (non-addressable) array of bytes
-}
-
-// NewEncoder returns an Encoder for encoding into an io.Writer.
-//
-// For efficiency, Users are encouraged to pass in a memory buffered writer
-// (eg bufio.Writer, bytes.Buffer).
-func NewEncoder(w io.Writer, h Handle) *Encoder {
-	e := newEncoder(h)
-	e.Reset(w)
-	return e
-}
-
-// NewEncoderBytes returns an encoder for encoding directly and efficiently
-// into a byte slice, using zero-copying to temporary slices.
-//
-// It will potentially replace the output byte slice pointed to.
-// After encoding, the out parameter contains the encoded contents.
-func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
-	e := newEncoder(h)
-	e.ResetBytes(out)
-	return e
-}
-
-func newEncoder(h Handle) *Encoder {
-	e := &Encoder{h: h.getBasicHandle(), err: errEncoderNotInitialized}
-	e.hh = h
-	e.esep = h.hasElemSeparators()
-	return e
-}
-
-func (e *Encoder) resetCommon() {
-	if e.e == nil || e.hh.recreateEncDriver(e.e) {
-		e.e = e.hh.newEncDriver(e)
-		e.as, e.isas = e.e.(encDriverAsis)
-		// e.cr, _ = e.e.(containerStateRecv)
-	}
-	e.be = e.hh.isBinary()
-	_, e.js = e.hh.(*JsonHandle)
-	e.e.reset()
-	e.err = nil
-}
-
-// Reset resets the Encoder with a new output stream.
-//
-// This accommodates using the state of the Encoder,
-// where it has "cached" information about sub-engines.
-func (e *Encoder) Reset(w io.Writer) {
-	if w == nil {
-		return
-	}
-	if e.wi == nil {
-		e.wi = new(ioEncWriter)
-	}
-	var ok bool
-	e.wx = false
-	e.wi.w = w
-	if e.h.WriterBufferSize > 0 {
-		e.bw = bufio.NewWriterSize(w, e.h.WriterBufferSize)
-		e.wi.bw = e.bw
-		e.wi.sw = e.bw
-		e.wi.fw = e.bw
-		e.wi.ww = e.bw
-	} else {
-		if e.wi.bw, ok = w.(io.ByteWriter); !ok {
-			e.wi.bw = e.wi
-		}
-		if e.wi.sw, ok = w.(ioEncStringWriter); !ok {
-			e.wi.sw = e.wi
-		}
-		e.wi.fw, _ = w.(ioFlusher)
-		e.wi.ww = w
-	}
-	e.w = e.wi
-	e.resetCommon()
-}
-
-// ResetBytes resets the Encoder with a new destination output []byte.
-func (e *Encoder) ResetBytes(out *[]byte) {
-	if out == nil {
-		return
-	}
-	var in []byte
-	if out != nil {
-		in = *out
-	}
-	if in == nil {
-		in = make([]byte, defEncByteBufSize)
-	}
-	e.wx = true
-	e.wb.reset(in, out)
-	e.w = &e.wb
-	e.resetCommon()
-}
-
-// Encode writes an object into a stream.
-//
-// Encoding can be configured via the struct tag for the fields.
-// The key (in the struct tags) that we look at is configurable.
-//
-// By default, we look up the "codec" key in the struct field's tags,
-// and fall bak to the "json" key if "codec" is absent.
-// That key in struct field's tag value is the key name,
-// followed by an optional comma and options.
-//
-// To set an option on all fields (e.g. omitempty on all fields), you
-// can create a field called _struct, and set flags on it. The options
-// which can be set on _struct are:
-//    - omitempty: so all fields are omitted if empty
-//    - toarray: so struct is encoded as an array
-//    - int: so struct key names are encoded as signed integers (instead of strings)
-//    - uint: so struct key names are encoded as unsigned integers (instead of strings)
-//    - float: so struct key names are encoded as floats (instead of strings)
-// More details on these below.
-//
-// Struct values "usually" encode as maps. Each exported struct field is encoded unless:
-//    - the field's tag is "-", OR
-//    - the field is empty (empty or the zero value) and its tag specifies the "omitempty" option.
-//
-// When encoding as a map, the first string in the tag (before the comma)
-// is the map key string to use when encoding.
-// ...
-// This key is typically encoded as a string.
-// However, there are instances where the encoded stream has mapping keys encoded as numbers.
-// For example, some cbor streams have keys as integer codes in the stream, but they should map
-// to fields in a structured object. Consequently, a struct is the natural representation in code.
-// For these, configure the struct to encode/decode the keys as numbers (instead of string).
-// This is done with the int,uint or float option on the _struct field (see above).
-//
-// However, struct values may encode as arrays. This happens when:
-//    - StructToArray Encode option is set, OR
-//    - the tag on the _struct field sets the "toarray" option
-// Note that omitempty is ignored when encoding struct values as arrays,
-// as an entry must be encoded for each field, to maintain its position.
-//
-// Values with types that implement MapBySlice are encoded as stream maps.
-//
-// The empty values (for omitempty option) are false, 0, any nil pointer
-// or interface value, and any array, slice, map, or string of length zero.
-//
-// Anonymous fields are encoded inline except:
-//    - the struct tag specifies a replacement name (first value)
-//    - the field is of an interface type
-//
-// Examples:
-//
-//      // NOTE: 'json:' can be used as struct tag key, in place 'codec:' below.
-//      type MyStruct struct {
-//          _struct bool    `codec:",omitempty"`   //set omitempty for every field
-//          Field1 string   `codec:"-"`            //skip this field
-//          Field2 int      `codec:"myName"`       //Use key "myName" in encode stream
-//          Field3 int32    `codec:",omitempty"`   //use key "Field3". Omit if empty.
-//          Field4 bool     `codec:"f4,omitempty"` //use key "f4". Omit if empty.
-//          io.Reader                              //use key "Reader".
-//          MyStruct        `codec:"my1"           //use key "my1".
-//          MyStruct                               //inline it
-//          ...
-//      }
-//
-//      type MyStruct struct {
-//          _struct bool    `codec:",toarray"`     //encode struct as an array
-//      }
-//
-//      type MyStruct struct {
-//          _struct bool    `codec:",uint"`        //encode struct with "unsigned integer" keys
-//          Field1 string   `codec:"1"`            //encode Field1 key using: EncodeInt(1)
-//          Field2 string   `codec:"2"`            //encode Field2 key using: EncodeInt(2)
-//      }
-//
-// The mode of encoding is based on the type of the value. When a value is seen:
-//   - If a Selfer, call its CodecEncodeSelf method
-//   - If an extension is registered for it, call that extension function
-//   - If implements encoding.(Binary|Text|JSON)Marshaler, call Marshal(Binary|Text|JSON) method
-//   - Else encode it based on its reflect.Kind
-//
-// Note that struct field names and keys in map[string]XXX will be treated as symbols.
-// Some formats support symbols (e.g. binc) and will properly encode the string
-// only once in the stream, and use a tag to refer to it thereafter.
-func (e *Encoder) Encode(v interface{}) (err error) {
-	defer e.deferred(&err)
-	e.MustEncode(v)
-	return
-}
-
-// MustEncode is like Encode, but panics if unable to Encode.
-// This provides insight to the code location that triggered the error.
-func (e *Encoder) MustEncode(v interface{}) {
-	if e.err != nil {
-		panic(e.err)
-	}
-	e.encode(v)
-	e.e.atEndOfEncode()
-	e.w.atEndOfEncode()
-	e.alwaysAtEnd()
-}
-
-func (e *Encoder) deferred(err1 *error) {
-	e.alwaysAtEnd()
-	if recoverPanicToErr {
-		if x := recover(); x != nil {
-			panicValToErr(e, x, err1)
-			panicValToErr(e, x, &e.err)
-		}
-	}
-}
-
-// func (e *Encoder) alwaysAtEnd() {
-// 	e.codecFnPooler.alwaysAtEnd()
-// }
-
-func (e *Encoder) encode(iv interface{}) {
-	if iv == nil || definitelyNil(iv) {
-		e.e.EncodeNil()
-		return
-	}
-	if v, ok := iv.(Selfer); ok {
-		v.CodecEncodeSelf(e)
-		return
-	}
-
-	// a switch with only concrete types can be optimized.
-	// consequently, we deal with nil and interfaces outside.
-
-	switch v := iv.(type) {
-	case Raw:
-		e.rawBytes(v)
-	case reflect.Value:
-		e.encodeValue(v, nil, true)
-
-	case string:
-		e.e.EncodeString(cUTF8, v)
-	case bool:
-		e.e.EncodeBool(v)
-	case int:
-		e.e.EncodeInt(int64(v))
-	case int8:
-		e.e.EncodeInt(int64(v))
-	case int16:
-		e.e.EncodeInt(int64(v))
-	case int32:
-		e.e.EncodeInt(int64(v))
-	case int64:
-		e.e.EncodeInt(v)
-	case uint:
-		e.e.EncodeUint(uint64(v))
-	case uint8:
-		e.e.EncodeUint(uint64(v))
-	case uint16:
-		e.e.EncodeUint(uint64(v))
-	case uint32:
-		e.e.EncodeUint(uint64(v))
-	case uint64:
-		e.e.EncodeUint(v)
-	case uintptr:
-		e.e.EncodeUint(uint64(v))
-	case float32:
-		e.e.EncodeFloat32(v)
-	case float64:
-		e.e.EncodeFloat64(v)
-	case time.Time:
-		e.e.EncodeTime(v)
-	case []uint8:
-		e.e.EncodeStringBytes(cRAW, v)
-
-	case *Raw:
-		e.rawBytes(*v)
-
-	case *string:
-		e.e.EncodeString(cUTF8, *v)
-	case *bool:
-		e.e.EncodeBool(*v)
-	case *int:
-		e.e.EncodeInt(int64(*v))
-	case *int8:
-		e.e.EncodeInt(int64(*v))
-	case *int16:
-		e.e.EncodeInt(int64(*v))
-	case *int32:
-		e.e.EncodeInt(int64(*v))
-	case *int64:
-		e.e.EncodeInt(*v)
-	case *uint:
-		e.e.EncodeUint(uint64(*v))
-	case *uint8:
-		e.e.EncodeUint(uint64(*v))
-	case *uint16:
-		e.e.EncodeUint(uint64(*v))
-	case *uint32:
-		e.e.EncodeUint(uint64(*v))
-	case *uint64:
-		e.e.EncodeUint(*v)
-	case *uintptr:
-		e.e.EncodeUint(uint64(*v))
-	case *float32:
-		e.e.EncodeFloat32(*v)
-	case *float64:
-		e.e.EncodeFloat64(*v)
-	case *time.Time:
-		e.e.EncodeTime(*v)
-
-	case *[]uint8:
-		e.e.EncodeStringBytes(cRAW, *v)
-
-	default:
-		if !fastpathEncodeTypeSwitch(iv, e) {
-			// checkfastpath=true (not false), as underlying slice/map type may be fast-path
-			e.encodeValue(reflect.ValueOf(iv), nil, true)
-		}
-	}
-}
-
-func (e *Encoder) encodeValue(rv reflect.Value, fn *codecFn, checkFastpath bool) {
-	// if a valid fn is passed, it MUST BE for the dereferenced type of rv
-	var sptr uintptr
-	var rvp reflect.Value
-	var rvpValid bool
-TOP:
-	switch rv.Kind() {
-	case reflect.Ptr:
-		if rv.IsNil() {
-			e.e.EncodeNil()
-			return
-		}
-		rvpValid = true
-		rvp = rv
-		rv = rv.Elem()
-		if e.h.CheckCircularRef && rv.Kind() == reflect.Struct {
-			// TODO: Movable pointers will be an issue here. Future problem.
-			sptr = rv.UnsafeAddr()
-			break TOP
-		}
-		goto TOP
-	case reflect.Interface:
-		if rv.IsNil() {
-			e.e.EncodeNil()
-			return
-		}
-		rv = rv.Elem()
-		goto TOP
-	case reflect.Slice, reflect.Map:
-		if rv.IsNil() {
-			e.e.EncodeNil()
-			return
-		}
-	case reflect.Invalid, reflect.Func:
-		e.e.EncodeNil()
-		return
-	}
-
-	if sptr != 0 && (&e.ci).add(sptr) {
-		e.errorf("circular reference found: # %d", sptr)
-	}
-
-	if fn == nil {
-		rt := rv.Type()
-		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
-		fn = e.cfer().get(rt, checkFastpath, true)
-	}
-	if fn.i.addrE {
-		if rvpValid {
-			fn.fe(e, &fn.i, rvp)
-		} else if rv.CanAddr() {
-			fn.fe(e, &fn.i, rv.Addr())
-		} else {
-			rv2 := reflect.New(rv.Type())
-			rv2.Elem().Set(rv)
-			fn.fe(e, &fn.i, rv2)
-		}
-	} else {
-		fn.fe(e, &fn.i, rv)
-	}
-	if sptr != 0 {
-		(&e.ci).remove(sptr)
-	}
-}
-
-func (e *Encoder) marshal(bs []byte, fnerr error, asis bool, c charEncoding) {
-	if fnerr != nil {
-		panic(fnerr)
-	}
-	if bs == nil {
-		e.e.EncodeNil()
-	} else if asis {
-		e.asis(bs)
-	} else {
-		e.e.EncodeStringBytes(c, bs)
-	}
-}
-
-func (e *Encoder) asis(v []byte) {
-	if e.isas {
-		e.as.EncodeAsis(v)
-	} else {
-		e.w.writeb(v)
-	}
-}
-
-func (e *Encoder) rawBytes(vv Raw) {
-	v := []byte(vv)
-	if !e.h.Raw {
-		e.errorf("Raw values cannot be encoded: %v", v)
-	}
-	e.asis(v)
-}
-
-func (e *Encoder) wrapErrstr(v interface{}, err *error) {
-	*err = fmt.Errorf("%s encode error: %v", e.hh.Name(), v)
-}
diff --git a/vendor/github.com/ugorji/go/codec/fast-path.generated.go b/vendor/github.com/ugorji/go/codec/fast-path.generated.go
deleted file mode 100644
index 87f2562..0000000
--- a/vendor/github.com/ugorji/go/codec/fast-path.generated.go
+++ /dev/null
@@ -1,34522 +0,0 @@
-// +build !notfastpath
-
-// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// Code generated from fast-path.go.tmpl - DO NOT EDIT.
-
-package codec
-
-// Fast path functions try to create a fast path encode or decode implementation
-// for common maps and slices.
-//
-// We define the functions and register then in this single file
-// so as not to pollute the encode.go and decode.go, and create a dependency in there.
-// This file can be omitted without causing a build failure.
-//
-// The advantage of fast paths is:
-//	  - Many calls bypass reflection altogether
-//
-// Currently support
-//	  - slice of all builtin types,
-//	  - map of all builtin types to string or interface value
-//	  - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
-// This should provide adequate "typical" implementations.
-//
-// Note that fast track decode functions must handle values for which an address cannot be obtained.
-// For example:
-//	 m2 := map[string]int{}
-//	 p2 := []interface{}{m2}
-//	 // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
-//
-
-import (
-	"reflect"
-	"sort"
-)
-
-const fastpathEnabled = true
-
-type fastpathT struct{}
-
-var fastpathTV fastpathT
-
-type fastpathE struct {
-	rtid  uintptr
-	rt    reflect.Type
-	encfn func(*Encoder, *codecFnInfo, reflect.Value)
-	decfn func(*Decoder, *codecFnInfo, reflect.Value)
-}
-
-type fastpathA [271]fastpathE
-
-func (x *fastpathA) index(rtid uintptr) int {
-	// use binary search to grab the index (adapted from sort/search.go)
-	h, i, j := 0, 0, 271 // len(x)
-	for i < j {
-		h = i + (j-i)/2
-		if x[h].rtid < rtid {
-			i = h + 1
-		} else {
-			j = h
-		}
-	}
-	if i < 271 && x[i].rtid == rtid {
-		return i
-	}
-	return -1
-}
-
-type fastpathAslice []fastpathE
-
-func (x fastpathAslice) Len() int           { return len(x) }
-func (x fastpathAslice) Less(i, j int) bool { return x[i].rtid < x[j].rtid }
-func (x fastpathAslice) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-
-var fastpathAV fastpathA
-
-// due to possible initialization loop error, make fastpath in an init()
-func init() {
-	i := 0
-	fn := func(v interface{},
-		fe func(*Encoder, *codecFnInfo, reflect.Value),
-		fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
-		xrt := reflect.TypeOf(v)
-		xptr := rt2id(xrt)
-		fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
-		i++
-		return
-	}
-
-	fn([]interface{}(nil), (*Encoder).fastpathEncSliceIntfR, (*Decoder).fastpathDecSliceIntfR)
-	fn([]string(nil), (*Encoder).fastpathEncSliceStringR, (*Decoder).fastpathDecSliceStringR)
-	fn([]float32(nil), (*Encoder).fastpathEncSliceFloat32R, (*Decoder).fastpathDecSliceFloat32R)
-	fn([]float64(nil), (*Encoder).fastpathEncSliceFloat64R, (*Decoder).fastpathDecSliceFloat64R)
-	fn([]uint(nil), (*Encoder).fastpathEncSliceUintR, (*Decoder).fastpathDecSliceUintR)
-	fn([]uint16(nil), (*Encoder).fastpathEncSliceUint16R, (*Decoder).fastpathDecSliceUint16R)
-	fn([]uint32(nil), (*Encoder).fastpathEncSliceUint32R, (*Decoder).fastpathDecSliceUint32R)
-	fn([]uint64(nil), (*Encoder).fastpathEncSliceUint64R, (*Decoder).fastpathDecSliceUint64R)
-	fn([]uintptr(nil), (*Encoder).fastpathEncSliceUintptrR, (*Decoder).fastpathDecSliceUintptrR)
-	fn([]int(nil), (*Encoder).fastpathEncSliceIntR, (*Decoder).fastpathDecSliceIntR)
-	fn([]int8(nil), (*Encoder).fastpathEncSliceInt8R, (*Decoder).fastpathDecSliceInt8R)
-	fn([]int16(nil), (*Encoder).fastpathEncSliceInt16R, (*Decoder).fastpathDecSliceInt16R)
-	fn([]int32(nil), (*Encoder).fastpathEncSliceInt32R, (*Decoder).fastpathDecSliceInt32R)
-	fn([]int64(nil), (*Encoder).fastpathEncSliceInt64R, (*Decoder).fastpathDecSliceInt64R)
-	fn([]bool(nil), (*Encoder).fastpathEncSliceBoolR, (*Decoder).fastpathDecSliceBoolR)
-
-	fn(map[interface{}]interface{}(nil), (*Encoder).fastpathEncMapIntfIntfR, (*Decoder).fastpathDecMapIntfIntfR)
-	fn(map[interface{}]string(nil), (*Encoder).fastpathEncMapIntfStringR, (*Decoder).fastpathDecMapIntfStringR)
-	fn(map[interface{}]uint(nil), (*Encoder).fastpathEncMapIntfUintR, (*Decoder).fastpathDecMapIntfUintR)
-	fn(map[interface{}]uint8(nil), (*Encoder).fastpathEncMapIntfUint8R, (*Decoder).fastpathDecMapIntfUint8R)
-	fn(map[interface{}]uint16(nil), (*Encoder).fastpathEncMapIntfUint16R, (*Decoder).fastpathDecMapIntfUint16R)
-	fn(map[interface{}]uint32(nil), (*Encoder).fastpathEncMapIntfUint32R, (*Decoder).fastpathDecMapIntfUint32R)
-	fn(map[interface{}]uint64(nil), (*Encoder).fastpathEncMapIntfUint64R, (*Decoder).fastpathDecMapIntfUint64R)
-	fn(map[interface{}]uintptr(nil), (*Encoder).fastpathEncMapIntfUintptrR, (*Decoder).fastpathDecMapIntfUintptrR)
-	fn(map[interface{}]int(nil), (*Encoder).fastpathEncMapIntfIntR, (*Decoder).fastpathDecMapIntfIntR)
-	fn(map[interface{}]int8(nil), (*Encoder).fastpathEncMapIntfInt8R, (*Decoder).fastpathDecMapIntfInt8R)
-	fn(map[interface{}]int16(nil), (*Encoder).fastpathEncMapIntfInt16R, (*Decoder).fastpathDecMapIntfInt16R)
-	fn(map[interface{}]int32(nil), (*Encoder).fastpathEncMapIntfInt32R, (*Decoder).fastpathDecMapIntfInt32R)
-	fn(map[interface{}]int64(nil), (*Encoder).fastpathEncMapIntfInt64R, (*Decoder).fastpathDecMapIntfInt64R)
-	fn(map[interface{}]float32(nil), (*Encoder).fastpathEncMapIntfFloat32R, (*Decoder).fastpathDecMapIntfFloat32R)
-	fn(map[interface{}]float64(nil), (*Encoder).fastpathEncMapIntfFloat64R, (*Decoder).fastpathDecMapIntfFloat64R)
-	fn(map[interface{}]bool(nil), (*Encoder).fastpathEncMapIntfBoolR, (*Decoder).fastpathDecMapIntfBoolR)
-	fn(map[string]interface{}(nil), (*Encoder).fastpathEncMapStringIntfR, (*Decoder).fastpathDecMapStringIntfR)
-	fn(map[string]string(nil), (*Encoder).fastpathEncMapStringStringR, (*Decoder).fastpathDecMapStringStringR)
-	fn(map[string]uint(nil), (*Encoder).fastpathEncMapStringUintR, (*Decoder).fastpathDecMapStringUintR)
-	fn(map[string]uint8(nil), (*Encoder).fastpathEncMapStringUint8R, (*Decoder).fastpathDecMapStringUint8R)
-	fn(map[string]uint16(nil), (*Encoder).fastpathEncMapStringUint16R, (*Decoder).fastpathDecMapStringUint16R)
-	fn(map[string]uint32(nil), (*Encoder).fastpathEncMapStringUint32R, (*Decoder).fastpathDecMapStringUint32R)
-	fn(map[string]uint64(nil), (*Encoder).fastpathEncMapStringUint64R, (*Decoder).fastpathDecMapStringUint64R)
-	fn(map[string]uintptr(nil), (*Encoder).fastpathEncMapStringUintptrR, (*Decoder).fastpathDecMapStringUintptrR)
-	fn(map[string]int(nil), (*Encoder).fastpathEncMapStringIntR, (*Decoder).fastpathDecMapStringIntR)
-	fn(map[string]int8(nil), (*Encoder).fastpathEncMapStringInt8R, (*Decoder).fastpathDecMapStringInt8R)
-	fn(map[string]int16(nil), (*Encoder).fastpathEncMapStringInt16R, (*Decoder).fastpathDecMapStringInt16R)
-	fn(map[string]int32(nil), (*Encoder).fastpathEncMapStringInt32R, (*Decoder).fastpathDecMapStringInt32R)
-	fn(map[string]int64(nil), (*Encoder).fastpathEncMapStringInt64R, (*Decoder).fastpathDecMapStringInt64R)
-	fn(map[string]float32(nil), (*Encoder).fastpathEncMapStringFloat32R, (*Decoder).fastpathDecMapStringFloat32R)
-	fn(map[string]float64(nil), (*Encoder).fastpathEncMapStringFloat64R, (*Decoder).fastpathDecMapStringFloat64R)
-	fn(map[string]bool(nil), (*Encoder).fastpathEncMapStringBoolR, (*Decoder).fastpathDecMapStringBoolR)
-	fn(map[float32]interface{}(nil), (*Encoder).fastpathEncMapFloat32IntfR, (*Decoder).fastpathDecMapFloat32IntfR)
-	fn(map[float32]string(nil), (*Encoder).fastpathEncMapFloat32StringR, (*Decoder).fastpathDecMapFloat32StringR)
-	fn(map[float32]uint(nil), (*Encoder).fastpathEncMapFloat32UintR, (*Decoder).fastpathDecMapFloat32UintR)
-	fn(map[float32]uint8(nil), (*Encoder).fastpathEncMapFloat32Uint8R, (*Decoder).fastpathDecMapFloat32Uint8R)
-	fn(map[float32]uint16(nil), (*Encoder).fastpathEncMapFloat32Uint16R, (*Decoder).fastpathDecMapFloat32Uint16R)
-	fn(map[float32]uint32(nil), (*Encoder).fastpathEncMapFloat32Uint32R, (*Decoder).fastpathDecMapFloat32Uint32R)
-	fn(map[float32]uint64(nil), (*Encoder).fastpathEncMapFloat32Uint64R, (*Decoder).fastpathDecMapFloat32Uint64R)
-	fn(map[float32]uintptr(nil), (*Encoder).fastpathEncMapFloat32UintptrR, (*Decoder).fastpathDecMapFloat32UintptrR)
-	fn(map[float32]int(nil), (*Encoder).fastpathEncMapFloat32IntR, (*Decoder).fastpathDecMapFloat32IntR)
-	fn(map[float32]int8(nil), (*Encoder).fastpathEncMapFloat32Int8R, (*Decoder).fastpathDecMapFloat32Int8R)
-	fn(map[float32]int16(nil), (*Encoder).fastpathEncMapFloat32Int16R, (*Decoder).fastpathDecMapFloat32Int16R)
-	fn(map[float32]int32(nil), (*Encoder).fastpathEncMapFloat32Int32R, (*Decoder).fastpathDecMapFloat32Int32R)
-	fn(map[float32]int64(nil), (*Encoder).fastpathEncMapFloat32Int64R, (*Decoder).fastpathDecMapFloat32Int64R)
-	fn(map[float32]float32(nil), (*Encoder).fastpathEncMapFloat32Float32R, (*Decoder).fastpathDecMapFloat32Float32R)
-	fn(map[float32]float64(nil), (*Encoder).fastpathEncMapFloat32Float64R, (*Decoder).fastpathDecMapFloat32Float64R)
-	fn(map[float32]bool(nil), (*Encoder).fastpathEncMapFloat32BoolR, (*Decoder).fastpathDecMapFloat32BoolR)
-	fn(map[float64]interface{}(nil), (*Encoder).fastpathEncMapFloat64IntfR, (*Decoder).fastpathDecMapFloat64IntfR)
-	fn(map[float64]string(nil), (*Encoder).fastpathEncMapFloat64StringR, (*Decoder).fastpathDecMapFloat64StringR)
-	fn(map[float64]uint(nil), (*Encoder).fastpathEncMapFloat64UintR, (*Decoder).fastpathDecMapFloat64UintR)
-	fn(map[float64]uint8(nil), (*Encoder).fastpathEncMapFloat64Uint8R, (*Decoder).fastpathDecMapFloat64Uint8R)
-	fn(map[float64]uint16(nil), (*Encoder).fastpathEncMapFloat64Uint16R, (*Decoder).fastpathDecMapFloat64Uint16R)
-	fn(map[float64]uint32(nil), (*Encoder).fastpathEncMapFloat64Uint32R, (*Decoder).fastpathDecMapFloat64Uint32R)
-	fn(map[float64]uint64(nil), (*Encoder).fastpathEncMapFloat64Uint64R, (*Decoder).fastpathDecMapFloat64Uint64R)
-	fn(map[float64]uintptr(nil), (*Encoder).fastpathEncMapFloat64UintptrR, (*Decoder).fastpathDecMapFloat64UintptrR)
-	fn(map[float64]int(nil), (*Encoder).fastpathEncMapFloat64IntR, (*Decoder).fastpathDecMapFloat64IntR)
-	fn(map[float64]int8(nil), (*Encoder).fastpathEncMapFloat64Int8R, (*Decoder).fastpathDecMapFloat64Int8R)
-	fn(map[float64]int16(nil), (*Encoder).fastpathEncMapFloat64Int16R, (*Decoder).fastpathDecMapFloat64Int16R)
-	fn(map[float64]int32(nil), (*Encoder).fastpathEncMapFloat64Int32R, (*Decoder).fastpathDecMapFloat64Int32R)
-	fn(map[float64]int64(nil), (*Encoder).fastpathEncMapFloat64Int64R, (*Decoder).fastpathDecMapFloat64Int64R)
-	fn(map[float64]float32(nil), (*Encoder).fastpathEncMapFloat64Float32R, (*Decoder).fastpathDecMapFloat64Float32R)
-	fn(map[float64]float64(nil), (*Encoder).fastpathEncMapFloat64Float64R, (*Decoder).fastpathDecMapFloat64Float64R)
-	fn(map[float64]bool(nil), (*Encoder).fastpathEncMapFloat64BoolR, (*Decoder).fastpathDecMapFloat64BoolR)
-	fn(map[uint]interface{}(nil), (*Encoder).fastpathEncMapUintIntfR, (*Decoder).fastpathDecMapUintIntfR)
-	fn(map[uint]string(nil), (*Encoder).fastpathEncMapUintStringR, (*Decoder).fastpathDecMapUintStringR)
-	fn(map[uint]uint(nil), (*Encoder).fastpathEncMapUintUintR, (*Decoder).fastpathDecMapUintUintR)
-	fn(map[uint]uint8(nil), (*Encoder).fastpathEncMapUintUint8R, (*Decoder).fastpathDecMapUintUint8R)
-	fn(map[uint]uint16(nil), (*Encoder).fastpathEncMapUintUint16R, (*Decoder).fastpathDecMapUintUint16R)
-	fn(map[uint]uint32(nil), (*Encoder).fastpathEncMapUintUint32R, (*Decoder).fastpathDecMapUintUint32R)
-	fn(map[uint]uint64(nil), (*Encoder).fastpathEncMapUintUint64R, (*Decoder).fastpathDecMapUintUint64R)
-	fn(map[uint]uintptr(nil), (*Encoder).fastpathEncMapUintUintptrR, (*Decoder).fastpathDecMapUintUintptrR)
-	fn(map[uint]int(nil), (*Encoder).fastpathEncMapUintIntR, (*Decoder).fastpathDecMapUintIntR)
-	fn(map[uint]int8(nil), (*Encoder).fastpathEncMapUintInt8R, (*Decoder).fastpathDecMapUintInt8R)
-	fn(map[uint]int16(nil), (*Encoder).fastpathEncMapUintInt16R, (*Decoder).fastpathDecMapUintInt16R)
-	fn(map[uint]int32(nil), (*Encoder).fastpathEncMapUintInt32R, (*Decoder).fastpathDecMapUintInt32R)
-	fn(map[uint]int64(nil), (*Encoder).fastpathEncMapUintInt64R, (*Decoder).fastpathDecMapUintInt64R)
-	fn(map[uint]float32(nil), (*Encoder).fastpathEncMapUintFloat32R, (*Decoder).fastpathDecMapUintFloat32R)
-	fn(map[uint]float64(nil), (*Encoder).fastpathEncMapUintFloat64R, (*Decoder).fastpathDecMapUintFloat64R)
-	fn(map[uint]bool(nil), (*Encoder).fastpathEncMapUintBoolR, (*Decoder).fastpathDecMapUintBoolR)
-	fn(map[uint8]interface{}(nil), (*Encoder).fastpathEncMapUint8IntfR, (*Decoder).fastpathDecMapUint8IntfR)
-	fn(map[uint8]string(nil), (*Encoder).fastpathEncMapUint8StringR, (*Decoder).fastpathDecMapUint8StringR)
-	fn(map[uint8]uint(nil), (*Encoder).fastpathEncMapUint8UintR, (*Decoder).fastpathDecMapUint8UintR)
-	fn(map[uint8]uint8(nil), (*Encoder).fastpathEncMapUint8Uint8R, (*Decoder).fastpathDecMapUint8Uint8R)
-	fn(map[uint8]uint16(nil), (*Encoder).fastpathEncMapUint8Uint16R, (*Decoder).fastpathDecMapUint8Uint16R)
-	fn(map[uint8]uint32(nil), (*Encoder).fastpathEncMapUint8Uint32R, (*Decoder).fastpathDecMapUint8Uint32R)
-	fn(map[uint8]uint64(nil), (*Encoder).fastpathEncMapUint8Uint64R, (*Decoder).fastpathDecMapUint8Uint64R)
-	fn(map[uint8]uintptr(nil), (*Encoder).fastpathEncMapUint8UintptrR, (*Decoder).fastpathDecMapUint8UintptrR)
-	fn(map[uint8]int(nil), (*Encoder).fastpathEncMapUint8IntR, (*Decoder).fastpathDecMapUint8IntR)
-	fn(map[uint8]int8(nil), (*Encoder).fastpathEncMapUint8Int8R, (*Decoder).fastpathDecMapUint8Int8R)
-	fn(map[uint8]int16(nil), (*Encoder).fastpathEncMapUint8Int16R, (*Decoder).fastpathDecMapUint8Int16R)
-	fn(map[uint8]int32(nil), (*Encoder).fastpathEncMapUint8Int32R, (*Decoder).fastpathDecMapUint8Int32R)
-	fn(map[uint8]int64(nil), (*Encoder).fastpathEncMapUint8Int64R, (*Decoder).fastpathDecMapUint8Int64R)
-	fn(map[uint8]float32(nil), (*Encoder).fastpathEncMapUint8Float32R, (*Decoder).fastpathDecMapUint8Float32R)
-	fn(map[uint8]float64(nil), (*Encoder).fastpathEncMapUint8Float64R, (*Decoder).fastpathDecMapUint8Float64R)
-	fn(map[uint8]bool(nil), (*Encoder).fastpathEncMapUint8BoolR, (*Decoder).fastpathDecMapUint8BoolR)
-	fn(map[uint16]interface{}(nil), (*Encoder).fastpathEncMapUint16IntfR, (*Decoder).fastpathDecMapUint16IntfR)
-	fn(map[uint16]string(nil), (*Encoder).fastpathEncMapUint16StringR, (*Decoder).fastpathDecMapUint16StringR)
-	fn(map[uint16]uint(nil), (*Encoder).fastpathEncMapUint16UintR, (*Decoder).fastpathDecMapUint16UintR)
-	fn(map[uint16]uint8(nil), (*Encoder).fastpathEncMapUint16Uint8R, (*Decoder).fastpathDecMapUint16Uint8R)
-	fn(map[uint16]uint16(nil), (*Encoder).fastpathEncMapUint16Uint16R, (*Decoder).fastpathDecMapUint16Uint16R)
-	fn(map[uint16]uint32(nil), (*Encoder).fastpathEncMapUint16Uint32R, (*Decoder).fastpathDecMapUint16Uint32R)
-	fn(map[uint16]uint64(nil), (*Encoder).fastpathEncMapUint16Uint64R, (*Decoder).fastpathDecMapUint16Uint64R)
-	fn(map[uint16]uintptr(nil), (*Encoder).fastpathEncMapUint16UintptrR, (*Decoder).fastpathDecMapUint16UintptrR)
-	fn(map[uint16]int(nil), (*Encoder).fastpathEncMapUint16IntR, (*Decoder).fastpathDecMapUint16IntR)
-	fn(map[uint16]int8(nil), (*Encoder).fastpathEncMapUint16Int8R, (*Decoder).fastpathDecMapUint16Int8R)
-	fn(map[uint16]int16(nil), (*Encoder).fastpathEncMapUint16Int16R, (*Decoder).fastpathDecMapUint16Int16R)
-	fn(map[uint16]int32(nil), (*Encoder).fastpathEncMapUint16Int32R, (*Decoder).fastpathDecMapUint16Int32R)
-	fn(map[uint16]int64(nil), (*Encoder).fastpathEncMapUint16Int64R, (*Decoder).fastpathDecMapUint16Int64R)
-	fn(map[uint16]float32(nil), (*Encoder).fastpathEncMapUint16Float32R, (*Decoder).fastpathDecMapUint16Float32R)
-	fn(map[uint16]float64(nil), (*Encoder).fastpathEncMapUint16Float64R, (*Decoder).fastpathDecMapUint16Float64R)
-	fn(map[uint16]bool(nil), (*Encoder).fastpathEncMapUint16BoolR, (*Decoder).fastpathDecMapUint16BoolR)
-	fn(map[uint32]interface{}(nil), (*Encoder).fastpathEncMapUint32IntfR, (*Decoder).fastpathDecMapUint32IntfR)
-	fn(map[uint32]string(nil), (*Encoder).fastpathEncMapUint32StringR, (*Decoder).fastpathDecMapUint32StringR)
-	fn(map[uint32]uint(nil), (*Encoder).fastpathEncMapUint32UintR, (*Decoder).fastpathDecMapUint32UintR)
-	fn(map[uint32]uint8(nil), (*Encoder).fastpathEncMapUint32Uint8R, (*Decoder).fastpathDecMapUint32Uint8R)
-	fn(map[uint32]uint16(nil), (*Encoder).fastpathEncMapUint32Uint16R, (*Decoder).fastpathDecMapUint32Uint16R)
-	fn(map[uint32]uint32(nil), (*Encoder).fastpathEncMapUint32Uint32R, (*Decoder).fastpathDecMapUint32Uint32R)
-	fn(map[uint32]uint64(nil), (*Encoder).fastpathEncMapUint32Uint64R, (*Decoder).fastpathDecMapUint32Uint64R)
-	fn(map[uint32]uintptr(nil), (*Encoder).fastpathEncMapUint32UintptrR, (*Decoder).fastpathDecMapUint32UintptrR)
-	fn(map[uint32]int(nil), (*Encoder).fastpathEncMapUint32IntR, (*Decoder).fastpathDecMapUint32IntR)
-	fn(map[uint32]int8(nil), (*Encoder).fastpathEncMapUint32Int8R, (*Decoder).fastpathDecMapUint32Int8R)
-	fn(map[uint32]int16(nil), (*Encoder).fastpathEncMapUint32Int16R, (*Decoder).fastpathDecMapUint32Int16R)
-	fn(map[uint32]int32(nil), (*Encoder).fastpathEncMapUint32Int32R, (*Decoder).fastpathDecMapUint32Int32R)
-	fn(map[uint32]int64(nil), (*Encoder).fastpathEncMapUint32Int64R, (*Decoder).fastpathDecMapUint32Int64R)
-	fn(map[uint32]float32(nil), (*Encoder).fastpathEncMapUint32Float32R, (*Decoder).fastpathDecMapUint32Float32R)
-	fn(map[uint32]float64(nil), (*Encoder).fastpathEncMapUint32Float64R, (*Decoder).fastpathDecMapUint32Float64R)
-	fn(map[uint32]bool(nil), (*Encoder).fastpathEncMapUint32BoolR, (*Decoder).fastpathDecMapUint32BoolR)
-	fn(map[uint64]interface{}(nil), (*Encoder).fastpathEncMapUint64IntfR, (*Decoder).fastpathDecMapUint64IntfR)
-	fn(map[uint64]string(nil), (*Encoder).fastpathEncMapUint64StringR, (*Decoder).fastpathDecMapUint64StringR)
-	fn(map[uint64]uint(nil), (*Encoder).fastpathEncMapUint64UintR, (*Decoder).fastpathDecMapUint64UintR)
-	fn(map[uint64]uint8(nil), (*Encoder).fastpathEncMapUint64Uint8R, (*Decoder).fastpathDecMapUint64Uint8R)
-	fn(map[uint64]uint16(nil), (*Encoder).fastpathEncMapUint64Uint16R, (*Decoder).fastpathDecMapUint64Uint16R)
-	fn(map[uint64]uint32(nil), (*Encoder).fastpathEncMapUint64Uint32R, (*Decoder).fastpathDecMapUint64Uint32R)
-	fn(map[uint64]uint64(nil), (*Encoder).fastpathEncMapUint64Uint64R, (*Decoder).fastpathDecMapUint64Uint64R)
-	fn(map[uint64]uintptr(nil), (*Encoder).fastpathEncMapUint64UintptrR, (*Decoder).fastpathDecMapUint64UintptrR)
-	fn(map[uint64]int(nil), (*Encoder).fastpathEncMapUint64IntR, (*Decoder).fastpathDecMapUint64IntR)
-	fn(map[uint64]int8(nil), (*Encoder).fastpathEncMapUint64Int8R, (*Decoder).fastpathDecMapUint64Int8R)
-	fn(map[uint64]int16(nil), (*Encoder).fastpathEncMapUint64Int16R, (*Decoder).fastpathDecMapUint64Int16R)
-	fn(map[uint64]int32(nil), (*Encoder).fastpathEncMapUint64Int32R, (*Decoder).fastpathDecMapUint64Int32R)
-	fn(map[uint64]int64(nil), (*Encoder).fastpathEncMapUint64Int64R, (*Decoder).fastpathDecMapUint64Int64R)
-	fn(map[uint64]float32(nil), (*Encoder).fastpathEncMapUint64Float32R, (*Decoder).fastpathDecMapUint64Float32R)
-	fn(map[uint64]float64(nil), (*Encoder).fastpathEncMapUint64Float64R, (*Decoder).fastpathDecMapUint64Float64R)
-	fn(map[uint64]bool(nil), (*Encoder).fastpathEncMapUint64BoolR, (*Decoder).fastpathDecMapUint64BoolR)
-	fn(map[uintptr]interface{}(nil), (*Encoder).fastpathEncMapUintptrIntfR, (*Decoder).fastpathDecMapUintptrIntfR)
-	fn(map[uintptr]string(nil), (*Encoder).fastpathEncMapUintptrStringR, (*Decoder).fastpathDecMapUintptrStringR)
-	fn(map[uintptr]uint(nil), (*Encoder).fastpathEncMapUintptrUintR, (*Decoder).fastpathDecMapUintptrUintR)
-	fn(map[uintptr]uint8(nil), (*Encoder).fastpathEncMapUintptrUint8R, (*Decoder).fastpathDecMapUintptrUint8R)
-	fn(map[uintptr]uint16(nil), (*Encoder).fastpathEncMapUintptrUint16R, (*Decoder).fastpathDecMapUintptrUint16R)
-	fn(map[uintptr]uint32(nil), (*Encoder).fastpathEncMapUintptrUint32R, (*Decoder).fastpathDecMapUintptrUint32R)
-	fn(map[uintptr]uint64(nil), (*Encoder).fastpathEncMapUintptrUint64R, (*Decoder).fastpathDecMapUintptrUint64R)
-	fn(map[uintptr]uintptr(nil), (*Encoder).fastpathEncMapUintptrUintptrR, (*Decoder).fastpathDecMapUintptrUintptrR)
-	fn(map[uintptr]int(nil), (*Encoder).fastpathEncMapUintptrIntR, (*Decoder).fastpathDecMapUintptrIntR)
-	fn(map[uintptr]int8(nil), (*Encoder).fastpathEncMapUintptrInt8R, (*Decoder).fastpathDecMapUintptrInt8R)
-	fn(map[uintptr]int16(nil), (*Encoder).fastpathEncMapUintptrInt16R, (*Decoder).fastpathDecMapUintptrInt16R)
-	fn(map[uintptr]int32(nil), (*Encoder).fastpathEncMapUintptrInt32R, (*Decoder).fastpathDecMapUintptrInt32R)
-	fn(map[uintptr]int64(nil), (*Encoder).fastpathEncMapUintptrInt64R, (*Decoder).fastpathDecMapUintptrInt64R)
-	fn(map[uintptr]float32(nil), (*Encoder).fastpathEncMapUintptrFloat32R, (*Decoder).fastpathDecMapUintptrFloat32R)
-	fn(map[uintptr]float64(nil), (*Encoder).fastpathEncMapUintptrFloat64R, (*Decoder).fastpathDecMapUintptrFloat64R)
-	fn(map[uintptr]bool(nil), (*Encoder).fastpathEncMapUintptrBoolR, (*Decoder).fastpathDecMapUintptrBoolR)
-	fn(map[int]interface{}(nil), (*Encoder).fastpathEncMapIntIntfR, (*Decoder).fastpathDecMapIntIntfR)
-	fn(map[int]string(nil), (*Encoder).fastpathEncMapIntStringR, (*Decoder).fastpathDecMapIntStringR)
-	fn(map[int]uint(nil), (*Encoder).fastpathEncMapIntUintR, (*Decoder).fastpathDecMapIntUintR)
-	fn(map[int]uint8(nil), (*Encoder).fastpathEncMapIntUint8R, (*Decoder).fastpathDecMapIntUint8R)
-	fn(map[int]uint16(nil), (*Encoder).fastpathEncMapIntUint16R, (*Decoder).fastpathDecMapIntUint16R)
-	fn(map[int]uint32(nil), (*Encoder).fastpathEncMapIntUint32R, (*Decoder).fastpathDecMapIntUint32R)
-	fn(map[int]uint64(nil), (*Encoder).fastpathEncMapIntUint64R, (*Decoder).fastpathDecMapIntUint64R)
-	fn(map[int]uintptr(nil), (*Encoder).fastpathEncMapIntUintptrR, (*Decoder).fastpathDecMapIntUintptrR)
-	fn(map[int]int(nil), (*Encoder).fastpathEncMapIntIntR, (*Decoder).fastpathDecMapIntIntR)
-	fn(map[int]int8(nil), (*Encoder).fastpathEncMapIntInt8R, (*Decoder).fastpathDecMapIntInt8R)
-	fn(map[int]int16(nil), (*Encoder).fastpathEncMapIntInt16R, (*Decoder).fastpathDecMapIntInt16R)
-	fn(map[int]int32(nil), (*Encoder).fastpathEncMapIntInt32R, (*Decoder).fastpathDecMapIntInt32R)
-	fn(map[int]int64(nil), (*Encoder).fastpathEncMapIntInt64R, (*Decoder).fastpathDecMapIntInt64R)
-	fn(map[int]float32(nil), (*Encoder).fastpathEncMapIntFloat32R, (*Decoder).fastpathDecMapIntFloat32R)
-	fn(map[int]float64(nil), (*Encoder).fastpathEncMapIntFloat64R, (*Decoder).fastpathDecMapIntFloat64R)
-	fn(map[int]bool(nil), (*Encoder).fastpathEncMapIntBoolR, (*Decoder).fastpathDecMapIntBoolR)
-	fn(map[int8]interface{}(nil), (*Encoder).fastpathEncMapInt8IntfR, (*Decoder).fastpathDecMapInt8IntfR)
-	fn(map[int8]string(nil), (*Encoder).fastpathEncMapInt8StringR, (*Decoder).fastpathDecMapInt8StringR)
-	fn(map[int8]uint(nil), (*Encoder).fastpathEncMapInt8UintR, (*Decoder).fastpathDecMapInt8UintR)
-	fn(map[int8]uint8(nil), (*Encoder).fastpathEncMapInt8Uint8R, (*Decoder).fastpathDecMapInt8Uint8R)
-	fn(map[int8]uint16(nil), (*Encoder).fastpathEncMapInt8Uint16R, (*Decoder).fastpathDecMapInt8Uint16R)
-	fn(map[int8]uint32(nil), (*Encoder).fastpathEncMapInt8Uint32R, (*Decoder).fastpathDecMapInt8Uint32R)
-	fn(map[int8]uint64(nil), (*Encoder).fastpathEncMapInt8Uint64R, (*Decoder).fastpathDecMapInt8Uint64R)
-	fn(map[int8]uintptr(nil), (*Encoder).fastpathEncMapInt8UintptrR, (*Decoder).fastpathDecMapInt8UintptrR)
-	fn(map[int8]int(nil), (*Encoder).fastpathEncMapInt8IntR, (*Decoder).fastpathDecMapInt8IntR)
-	fn(map[int8]int8(nil), (*Encoder).fastpathEncMapInt8Int8R, (*Decoder).fastpathDecMapInt8Int8R)
-	fn(map[int8]int16(nil), (*Encoder).fastpathEncMapInt8Int16R, (*Decoder).fastpathDecMapInt8Int16R)
-	fn(map[int8]int32(nil), (*Encoder).fastpathEncMapInt8Int32R, (*Decoder).fastpathDecMapInt8Int32R)
-	fn(map[int8]int64(nil), (*Encoder).fastpathEncMapInt8Int64R, (*Decoder).fastpathDecMapInt8Int64R)
-	fn(map[int8]float32(nil), (*Encoder).fastpathEncMapInt8Float32R, (*Decoder).fastpathDecMapInt8Float32R)
-	fn(map[int8]float64(nil), (*Encoder).fastpathEncMapInt8Float64R, (*Decoder).fastpathDecMapInt8Float64R)
-	fn(map[int8]bool(nil), (*Encoder).fastpathEncMapInt8BoolR, (*Decoder).fastpathDecMapInt8BoolR)
-	fn(map[int16]interface{}(nil), (*Encoder).fastpathEncMapInt16IntfR, (*Decoder).fastpathDecMapInt16IntfR)
-	fn(map[int16]string(nil), (*Encoder).fastpathEncMapInt16StringR, (*Decoder).fastpathDecMapInt16StringR)
-	fn(map[int16]uint(nil), (*Encoder).fastpathEncMapInt16UintR, (*Decoder).fastpathDecMapInt16UintR)
-	fn(map[int16]uint8(nil), (*Encoder).fastpathEncMapInt16Uint8R, (*Decoder).fastpathDecMapInt16Uint8R)
-	fn(map[int16]uint16(nil), (*Encoder).fastpathEncMapInt16Uint16R, (*Decoder).fastpathDecMapInt16Uint16R)
-	fn(map[int16]uint32(nil), (*Encoder).fastpathEncMapInt16Uint32R, (*Decoder).fastpathDecMapInt16Uint32R)
-	fn(map[int16]uint64(nil), (*Encoder).fastpathEncMapInt16Uint64R, (*Decoder).fastpathDecMapInt16Uint64R)
-	fn(map[int16]uintptr(nil), (*Encoder).fastpathEncMapInt16UintptrR, (*Decoder).fastpathDecMapInt16UintptrR)
-	fn(map[int16]int(nil), (*Encoder).fastpathEncMapInt16IntR, (*Decoder).fastpathDecMapInt16IntR)
-	fn(map[int16]int8(nil), (*Encoder).fastpathEncMapInt16Int8R, (*Decoder).fastpathDecMapInt16Int8R)
-	fn(map[int16]int16(nil), (*Encoder).fastpathEncMapInt16Int16R, (*Decoder).fastpathDecMapInt16Int16R)
-	fn(map[int16]int32(nil), (*Encoder).fastpathEncMapInt16Int32R, (*Decoder).fastpathDecMapInt16Int32R)
-	fn(map[int16]int64(nil), (*Encoder).fastpathEncMapInt16Int64R, (*Decoder).fastpathDecMapInt16Int64R)
-	fn(map[int16]float32(nil), (*Encoder).fastpathEncMapInt16Float32R, (*Decoder).fastpathDecMapInt16Float32R)
-	fn(map[int16]float64(nil), (*Encoder).fastpathEncMapInt16Float64R, (*Decoder).fastpathDecMapInt16Float64R)
-	fn(map[int16]bool(nil), (*Encoder).fastpathEncMapInt16BoolR, (*Decoder).fastpathDecMapInt16BoolR)
-	fn(map[int32]interface{}(nil), (*Encoder).fastpathEncMapInt32IntfR, (*Decoder).fastpathDecMapInt32IntfR)
-	fn(map[int32]string(nil), (*Encoder).fastpathEncMapInt32StringR, (*Decoder).fastpathDecMapInt32StringR)
-	fn(map[int32]uint(nil), (*Encoder).fastpathEncMapInt32UintR, (*Decoder).fastpathDecMapInt32UintR)
-	fn(map[int32]uint8(nil), (*Encoder).fastpathEncMapInt32Uint8R, (*Decoder).fastpathDecMapInt32Uint8R)
-	fn(map[int32]uint16(nil), (*Encoder).fastpathEncMapInt32Uint16R, (*Decoder).fastpathDecMapInt32Uint16R)
-	fn(map[int32]uint32(nil), (*Encoder).fastpathEncMapInt32Uint32R, (*Decoder).fastpathDecMapInt32Uint32R)
-	fn(map[int32]uint64(nil), (*Encoder).fastpathEncMapInt32Uint64R, (*Decoder).fastpathDecMapInt32Uint64R)
-	fn(map[int32]uintptr(nil), (*Encoder).fastpathEncMapInt32UintptrR, (*Decoder).fastpathDecMapInt32UintptrR)
-	fn(map[int32]int(nil), (*Encoder).fastpathEncMapInt32IntR, (*Decoder).fastpathDecMapInt32IntR)
-	fn(map[int32]int8(nil), (*Encoder).fastpathEncMapInt32Int8R, (*Decoder).fastpathDecMapInt32Int8R)
-	fn(map[int32]int16(nil), (*Encoder).fastpathEncMapInt32Int16R, (*Decoder).fastpathDecMapInt32Int16R)
-	fn(map[int32]int32(nil), (*Encoder).fastpathEncMapInt32Int32R, (*Decoder).fastpathDecMapInt32Int32R)
-	fn(map[int32]int64(nil), (*Encoder).fastpathEncMapInt32Int64R, (*Decoder).fastpathDecMapInt32Int64R)
-	fn(map[int32]float32(nil), (*Encoder).fastpathEncMapInt32Float32R, (*Decoder).fastpathDecMapInt32Float32R)
-	fn(map[int32]float64(nil), (*Encoder).fastpathEncMapInt32Float64R, (*Decoder).fastpathDecMapInt32Float64R)
-	fn(map[int32]bool(nil), (*Encoder).fastpathEncMapInt32BoolR, (*Decoder).fastpathDecMapInt32BoolR)
-	fn(map[int64]interface{}(nil), (*Encoder).fastpathEncMapInt64IntfR, (*Decoder).fastpathDecMapInt64IntfR)
-	fn(map[int64]string(nil), (*Encoder).fastpathEncMapInt64StringR, (*Decoder).fastpathDecMapInt64StringR)
-	fn(map[int64]uint(nil), (*Encoder).fastpathEncMapInt64UintR, (*Decoder).fastpathDecMapInt64UintR)
-	fn(map[int64]uint8(nil), (*Encoder).fastpathEncMapInt64Uint8R, (*Decoder).fastpathDecMapInt64Uint8R)
-	fn(map[int64]uint16(nil), (*Encoder).fastpathEncMapInt64Uint16R, (*Decoder).fastpathDecMapInt64Uint16R)
-	fn(map[int64]uint32(nil), (*Encoder).fastpathEncMapInt64Uint32R, (*Decoder).fastpathDecMapInt64Uint32R)
-	fn(map[int64]uint64(nil), (*Encoder).fastpathEncMapInt64Uint64R, (*Decoder).fastpathDecMapInt64Uint64R)
-	fn(map[int64]uintptr(nil), (*Encoder).fastpathEncMapInt64UintptrR, (*Decoder).fastpathDecMapInt64UintptrR)
-	fn(map[int64]int(nil), (*Encoder).fastpathEncMapInt64IntR, (*Decoder).fastpathDecMapInt64IntR)
-	fn(map[int64]int8(nil), (*Encoder).fastpathEncMapInt64Int8R, (*Decoder).fastpathDecMapInt64Int8R)
-	fn(map[int64]int16(nil), (*Encoder).fastpathEncMapInt64Int16R, (*Decoder).fastpathDecMapInt64Int16R)
-	fn(map[int64]int32(nil), (*Encoder).fastpathEncMapInt64Int32R, (*Decoder).fastpathDecMapInt64Int32R)
-	fn(map[int64]int64(nil), (*Encoder).fastpathEncMapInt64Int64R, (*Decoder).fastpathDecMapInt64Int64R)
-	fn(map[int64]float32(nil), (*Encoder).fastpathEncMapInt64Float32R, (*Decoder).fastpathDecMapInt64Float32R)
-	fn(map[int64]float64(nil), (*Encoder).fastpathEncMapInt64Float64R, (*Decoder).fastpathDecMapInt64Float64R)
-	fn(map[int64]bool(nil), (*Encoder).fastpathEncMapInt64BoolR, (*Decoder).fastpathDecMapInt64BoolR)
-	fn(map[bool]interface{}(nil), (*Encoder).fastpathEncMapBoolIntfR, (*Decoder).fastpathDecMapBoolIntfR)
-	fn(map[bool]string(nil), (*Encoder).fastpathEncMapBoolStringR, (*Decoder).fastpathDecMapBoolStringR)
-	fn(map[bool]uint(nil), (*Encoder).fastpathEncMapBoolUintR, (*Decoder).fastpathDecMapBoolUintR)
-	fn(map[bool]uint8(nil), (*Encoder).fastpathEncMapBoolUint8R, (*Decoder).fastpathDecMapBoolUint8R)
-	fn(map[bool]uint16(nil), (*Encoder).fastpathEncMapBoolUint16R, (*Decoder).fastpathDecMapBoolUint16R)
-	fn(map[bool]uint32(nil), (*Encoder).fastpathEncMapBoolUint32R, (*Decoder).fastpathDecMapBoolUint32R)
-	fn(map[bool]uint64(nil), (*Encoder).fastpathEncMapBoolUint64R, (*Decoder).fastpathDecMapBoolUint64R)
-	fn(map[bool]uintptr(nil), (*Encoder).fastpathEncMapBoolUintptrR, (*Decoder).fastpathDecMapBoolUintptrR)
-	fn(map[bool]int(nil), (*Encoder).fastpathEncMapBoolIntR, (*Decoder).fastpathDecMapBoolIntR)
-	fn(map[bool]int8(nil), (*Encoder).fastpathEncMapBoolInt8R, (*Decoder).fastpathDecMapBoolInt8R)
-	fn(map[bool]int16(nil), (*Encoder).fastpathEncMapBoolInt16R, (*Decoder).fastpathDecMapBoolInt16R)
-	fn(map[bool]int32(nil), (*Encoder).fastpathEncMapBoolInt32R, (*Decoder).fastpathDecMapBoolInt32R)
-	fn(map[bool]int64(nil), (*Encoder).fastpathEncMapBoolInt64R, (*Decoder).fastpathDecMapBoolInt64R)
-	fn(map[bool]float32(nil), (*Encoder).fastpathEncMapBoolFloat32R, (*Decoder).fastpathDecMapBoolFloat32R)
-	fn(map[bool]float64(nil), (*Encoder).fastpathEncMapBoolFloat64R, (*Decoder).fastpathDecMapBoolFloat64R)
-	fn(map[bool]bool(nil), (*Encoder).fastpathEncMapBoolBoolR, (*Decoder).fastpathDecMapBoolBoolR)
-
-	sort.Sort(fastpathAslice(fastpathAV[:]))
-}
-
-// -- encode
-
-// -- -- fast path type switch
-func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
-	switch v := iv.(type) {
-
-	case []interface{}:
-		fastpathTV.EncSliceIntfV(v, e)
-	case *[]interface{}:
-		fastpathTV.EncSliceIntfV(*v, e)
-	case []string:
-		fastpathTV.EncSliceStringV(v, e)
-	case *[]string:
-		fastpathTV.EncSliceStringV(*v, e)
-	case []float32:
-		fastpathTV.EncSliceFloat32V(v, e)
-	case *[]float32:
-		fastpathTV.EncSliceFloat32V(*v, e)
-	case []float64:
-		fastpathTV.EncSliceFloat64V(v, e)
-	case *[]float64:
-		fastpathTV.EncSliceFloat64V(*v, e)
-	case []uint:
-		fastpathTV.EncSliceUintV(v, e)
-	case *[]uint:
-		fastpathTV.EncSliceUintV(*v, e)
-	case []uint16:
-		fastpathTV.EncSliceUint16V(v, e)
-	case *[]uint16:
-		fastpathTV.EncSliceUint16V(*v, e)
-	case []uint32:
-		fastpathTV.EncSliceUint32V(v, e)
-	case *[]uint32:
-		fastpathTV.EncSliceUint32V(*v, e)
-	case []uint64:
-		fastpathTV.EncSliceUint64V(v, e)
-	case *[]uint64:
-		fastpathTV.EncSliceUint64V(*v, e)
-	case []uintptr:
-		fastpathTV.EncSliceUintptrV(v, e)
-	case *[]uintptr:
-		fastpathTV.EncSliceUintptrV(*v, e)
-	case []int:
-		fastpathTV.EncSliceIntV(v, e)
-	case *[]int:
-		fastpathTV.EncSliceIntV(*v, e)
-	case []int8:
-		fastpathTV.EncSliceInt8V(v, e)
-	case *[]int8:
-		fastpathTV.EncSliceInt8V(*v, e)
-	case []int16:
-		fastpathTV.EncSliceInt16V(v, e)
-	case *[]int16:
-		fastpathTV.EncSliceInt16V(*v, e)
-	case []int32:
-		fastpathTV.EncSliceInt32V(v, e)
-	case *[]int32:
-		fastpathTV.EncSliceInt32V(*v, e)
-	case []int64:
-		fastpathTV.EncSliceInt64V(v, e)
-	case *[]int64:
-		fastpathTV.EncSliceInt64V(*v, e)
-	case []bool:
-		fastpathTV.EncSliceBoolV(v, e)
-	case *[]bool:
-		fastpathTV.EncSliceBoolV(*v, e)
-
-	case map[interface{}]interface{}:
-		fastpathTV.EncMapIntfIntfV(v, e)
-	case *map[interface{}]interface{}:
-		fastpathTV.EncMapIntfIntfV(*v, e)
-	case map[interface{}]string:
-		fastpathTV.EncMapIntfStringV(v, e)
-	case *map[interface{}]string:
-		fastpathTV.EncMapIntfStringV(*v, e)
-	case map[interface{}]uint:
-		fastpathTV.EncMapIntfUintV(v, e)
-	case *map[interface{}]uint:
-		fastpathTV.EncMapIntfUintV(*v, e)
-	case map[interface{}]uint8:
-		fastpathTV.EncMapIntfUint8V(v, e)
-	case *map[interface{}]uint8:
-		fastpathTV.EncMapIntfUint8V(*v, e)
-	case map[interface{}]uint16:
-		fastpathTV.EncMapIntfUint16V(v, e)
-	case *map[interface{}]uint16:
-		fastpathTV.EncMapIntfUint16V(*v, e)
-	case map[interface{}]uint32:
-		fastpathTV.EncMapIntfUint32V(v, e)
-	case *map[interface{}]uint32:
-		fastpathTV.EncMapIntfUint32V(*v, e)
-	case map[interface{}]uint64:
-		fastpathTV.EncMapIntfUint64V(v, e)
-	case *map[interface{}]uint64:
-		fastpathTV.EncMapIntfUint64V(*v, e)
-	case map[interface{}]uintptr:
-		fastpathTV.EncMapIntfUintptrV(v, e)
-	case *map[interface{}]uintptr:
-		fastpathTV.EncMapIntfUintptrV(*v, e)
-	case map[interface{}]int:
-		fastpathTV.EncMapIntfIntV(v, e)
-	case *map[interface{}]int:
-		fastpathTV.EncMapIntfIntV(*v, e)
-	case map[interface{}]int8:
-		fastpathTV.EncMapIntfInt8V(v, e)
-	case *map[interface{}]int8:
-		fastpathTV.EncMapIntfInt8V(*v, e)
-	case map[interface{}]int16:
-		fastpathTV.EncMapIntfInt16V(v, e)
-	case *map[interface{}]int16:
-		fastpathTV.EncMapIntfInt16V(*v, e)
-	case map[interface{}]int32:
-		fastpathTV.EncMapIntfInt32V(v, e)
-	case *map[interface{}]int32:
-		fastpathTV.EncMapIntfInt32V(*v, e)
-	case map[interface{}]int64:
-		fastpathTV.EncMapIntfInt64V(v, e)
-	case *map[interface{}]int64:
-		fastpathTV.EncMapIntfInt64V(*v, e)
-	case map[interface{}]float32:
-		fastpathTV.EncMapIntfFloat32V(v, e)
-	case *map[interface{}]float32:
-		fastpathTV.EncMapIntfFloat32V(*v, e)
-	case map[interface{}]float64:
-		fastpathTV.EncMapIntfFloat64V(v, e)
-	case *map[interface{}]float64:
-		fastpathTV.EncMapIntfFloat64V(*v, e)
-	case map[interface{}]bool:
-		fastpathTV.EncMapIntfBoolV(v, e)
-	case *map[interface{}]bool:
-		fastpathTV.EncMapIntfBoolV(*v, e)
-	case map[string]interface{}:
-		fastpathTV.EncMapStringIntfV(v, e)
-	case *map[string]interface{}:
-		fastpathTV.EncMapStringIntfV(*v, e)
-	case map[string]string:
-		fastpathTV.EncMapStringStringV(v, e)
-	case *map[string]string:
-		fastpathTV.EncMapStringStringV(*v, e)
-	case map[string]uint:
-		fastpathTV.EncMapStringUintV(v, e)
-	case *map[string]uint:
-		fastpathTV.EncMapStringUintV(*v, e)
-	case map[string]uint8:
-		fastpathTV.EncMapStringUint8V(v, e)
-	case *map[string]uint8:
-		fastpathTV.EncMapStringUint8V(*v, e)
-	case map[string]uint16:
-		fastpathTV.EncMapStringUint16V(v, e)
-	case *map[string]uint16:
-		fastpathTV.EncMapStringUint16V(*v, e)
-	case map[string]uint32:
-		fastpathTV.EncMapStringUint32V(v, e)
-	case *map[string]uint32:
-		fastpathTV.EncMapStringUint32V(*v, e)
-	case map[string]uint64:
-		fastpathTV.EncMapStringUint64V(v, e)
-	case *map[string]uint64:
-		fastpathTV.EncMapStringUint64V(*v, e)
-	case map[string]uintptr:
-		fastpathTV.EncMapStringUintptrV(v, e)
-	case *map[string]uintptr:
-		fastpathTV.EncMapStringUintptrV(*v, e)
-	case map[string]int:
-		fastpathTV.EncMapStringIntV(v, e)
-	case *map[string]int:
-		fastpathTV.EncMapStringIntV(*v, e)
-	case map[string]int8:
-		fastpathTV.EncMapStringInt8V(v, e)
-	case *map[string]int8:
-		fastpathTV.EncMapStringInt8V(*v, e)
-	case map[string]int16:
-		fastpathTV.EncMapStringInt16V(v, e)
-	case *map[string]int16:
-		fastpathTV.EncMapStringInt16V(*v, e)
-	case map[string]int32:
-		fastpathTV.EncMapStringInt32V(v, e)
-	case *map[string]int32:
-		fastpathTV.EncMapStringInt32V(*v, e)
-	case map[string]int64:
-		fastpathTV.EncMapStringInt64V(v, e)
-	case *map[string]int64:
-		fastpathTV.EncMapStringInt64V(*v, e)
-	case map[string]float32:
-		fastpathTV.EncMapStringFloat32V(v, e)
-	case *map[string]float32:
-		fastpathTV.EncMapStringFloat32V(*v, e)
-	case map[string]float64:
-		fastpathTV.EncMapStringFloat64V(v, e)
-	case *map[string]float64:
-		fastpathTV.EncMapStringFloat64V(*v, e)
-	case map[string]bool:
-		fastpathTV.EncMapStringBoolV(v, e)
-	case *map[string]bool:
-		fastpathTV.EncMapStringBoolV(*v, e)
-	case map[float32]interface{}:
-		fastpathTV.EncMapFloat32IntfV(v, e)
-	case *map[float32]interface{}:
-		fastpathTV.EncMapFloat32IntfV(*v, e)
-	case map[float32]string:
-		fastpathTV.EncMapFloat32StringV(v, e)
-	case *map[float32]string:
-		fastpathTV.EncMapFloat32StringV(*v, e)
-	case map[float32]uint:
-		fastpathTV.EncMapFloat32UintV(v, e)
-	case *map[float32]uint:
-		fastpathTV.EncMapFloat32UintV(*v, e)
-	case map[float32]uint8:
-		fastpathTV.EncMapFloat32Uint8V(v, e)
-	case *map[float32]uint8:
-		fastpathTV.EncMapFloat32Uint8V(*v, e)
-	case map[float32]uint16:
-		fastpathTV.EncMapFloat32Uint16V(v, e)
-	case *map[float32]uint16:
-		fastpathTV.EncMapFloat32Uint16V(*v, e)
-	case map[float32]uint32:
-		fastpathTV.EncMapFloat32Uint32V(v, e)
-	case *map[float32]uint32:
-		fastpathTV.EncMapFloat32Uint32V(*v, e)
-	case map[float32]uint64:
-		fastpathTV.EncMapFloat32Uint64V(v, e)
-	case *map[float32]uint64:
-		fastpathTV.EncMapFloat32Uint64V(*v, e)
-	case map[float32]uintptr:
-		fastpathTV.EncMapFloat32UintptrV(v, e)
-	case *map[float32]uintptr:
-		fastpathTV.EncMapFloat32UintptrV(*v, e)
-	case map[float32]int:
-		fastpathTV.EncMapFloat32IntV(v, e)
-	case *map[float32]int:
-		fastpathTV.EncMapFloat32IntV(*v, e)
-	case map[float32]int8:
-		fastpathTV.EncMapFloat32Int8V(v, e)
-	case *map[float32]int8:
-		fastpathTV.EncMapFloat32Int8V(*v, e)
-	case map[float32]int16:
-		fastpathTV.EncMapFloat32Int16V(v, e)
-	case *map[float32]int16:
-		fastpathTV.EncMapFloat32Int16V(*v, e)
-	case map[float32]int32:
-		fastpathTV.EncMapFloat32Int32V(v, e)
-	case *map[float32]int32:
-		fastpathTV.EncMapFloat32Int32V(*v, e)
-	case map[float32]int64:
-		fastpathTV.EncMapFloat32Int64V(v, e)
-	case *map[float32]int64:
-		fastpathTV.EncMapFloat32Int64V(*v, e)
-	case map[float32]float32:
-		fastpathTV.EncMapFloat32Float32V(v, e)
-	case *map[float32]float32:
-		fastpathTV.EncMapFloat32Float32V(*v, e)
-	case map[float32]float64:
-		fastpathTV.EncMapFloat32Float64V(v, e)
-	case *map[float32]float64:
-		fastpathTV.EncMapFloat32Float64V(*v, e)
-	case map[float32]bool:
-		fastpathTV.EncMapFloat32BoolV(v, e)
-	case *map[float32]bool:
-		fastpathTV.EncMapFloat32BoolV(*v, e)
-	case map[float64]interface{}:
-		fastpathTV.EncMapFloat64IntfV(v, e)
-	case *map[float64]interface{}:
-		fastpathTV.EncMapFloat64IntfV(*v, e)
-	case map[float64]string:
-		fastpathTV.EncMapFloat64StringV(v, e)
-	case *map[float64]string:
-		fastpathTV.EncMapFloat64StringV(*v, e)
-	case map[float64]uint:
-		fastpathTV.EncMapFloat64UintV(v, e)
-	case *map[float64]uint:
-		fastpathTV.EncMapFloat64UintV(*v, e)
-	case map[float64]uint8:
-		fastpathTV.EncMapFloat64Uint8V(v, e)
-	case *map[float64]uint8:
-		fastpathTV.EncMapFloat64Uint8V(*v, e)
-	case map[float64]uint16:
-		fastpathTV.EncMapFloat64Uint16V(v, e)
-	case *map[float64]uint16:
-		fastpathTV.EncMapFloat64Uint16V(*v, e)
-	case map[float64]uint32:
-		fastpathTV.EncMapFloat64Uint32V(v, e)
-	case *map[float64]uint32:
-		fastpathTV.EncMapFloat64Uint32V(*v, e)
-	case map[float64]uint64:
-		fastpathTV.EncMapFloat64Uint64V(v, e)
-	case *map[float64]uint64:
-		fastpathTV.EncMapFloat64Uint64V(*v, e)
-	case map[float64]uintptr:
-		fastpathTV.EncMapFloat64UintptrV(v, e)
-	case *map[float64]uintptr:
-		fastpathTV.EncMapFloat64UintptrV(*v, e)
-	case map[float64]int:
-		fastpathTV.EncMapFloat64IntV(v, e)
-	case *map[float64]int:
-		fastpathTV.EncMapFloat64IntV(*v, e)
-	case map[float64]int8:
-		fastpathTV.EncMapFloat64Int8V(v, e)
-	case *map[float64]int8:
-		fastpathTV.EncMapFloat64Int8V(*v, e)
-	case map[float64]int16:
-		fastpathTV.EncMapFloat64Int16V(v, e)
-	case *map[float64]int16:
-		fastpathTV.EncMapFloat64Int16V(*v, e)
-	case map[float64]int32:
-		fastpathTV.EncMapFloat64Int32V(v, e)
-	case *map[float64]int32:
-		fastpathTV.EncMapFloat64Int32V(*v, e)
-	case map[float64]int64:
-		fastpathTV.EncMapFloat64Int64V(v, e)
-	case *map[float64]int64:
-		fastpathTV.EncMapFloat64Int64V(*v, e)
-	case map[float64]float32:
-		fastpathTV.EncMapFloat64Float32V(v, e)
-	case *map[float64]float32:
-		fastpathTV.EncMapFloat64Float32V(*v, e)
-	case map[float64]float64:
-		fastpathTV.EncMapFloat64Float64V(v, e)
-	case *map[float64]float64:
-		fastpathTV.EncMapFloat64Float64V(*v, e)
-	case map[float64]bool:
-		fastpathTV.EncMapFloat64BoolV(v, e)
-	case *map[float64]bool:
-		fastpathTV.EncMapFloat64BoolV(*v, e)
-	case map[uint]interface{}:
-		fastpathTV.EncMapUintIntfV(v, e)
-	case *map[uint]interface{}:
-		fastpathTV.EncMapUintIntfV(*v, e)
-	case map[uint]string:
-		fastpathTV.EncMapUintStringV(v, e)
-	case *map[uint]string:
-		fastpathTV.EncMapUintStringV(*v, e)
-	case map[uint]uint:
-		fastpathTV.EncMapUintUintV(v, e)
-	case *map[uint]uint:
-		fastpathTV.EncMapUintUintV(*v, e)
-	case map[uint]uint8:
-		fastpathTV.EncMapUintUint8V(v, e)
-	case *map[uint]uint8:
-		fastpathTV.EncMapUintUint8V(*v, e)
-	case map[uint]uint16:
-		fastpathTV.EncMapUintUint16V(v, e)
-	case *map[uint]uint16:
-		fastpathTV.EncMapUintUint16V(*v, e)
-	case map[uint]uint32:
-		fastpathTV.EncMapUintUint32V(v, e)
-	case *map[uint]uint32:
-		fastpathTV.EncMapUintUint32V(*v, e)
-	case map[uint]uint64:
-		fastpathTV.EncMapUintUint64V(v, e)
-	case *map[uint]uint64:
-		fastpathTV.EncMapUintUint64V(*v, e)
-	case map[uint]uintptr:
-		fastpathTV.EncMapUintUintptrV(v, e)
-	case *map[uint]uintptr:
-		fastpathTV.EncMapUintUintptrV(*v, e)
-	case map[uint]int:
-		fastpathTV.EncMapUintIntV(v, e)
-	case *map[uint]int:
-		fastpathTV.EncMapUintIntV(*v, e)
-	case map[uint]int8:
-		fastpathTV.EncMapUintInt8V(v, e)
-	case *map[uint]int8:
-		fastpathTV.EncMapUintInt8V(*v, e)
-	case map[uint]int16:
-		fastpathTV.EncMapUintInt16V(v, e)
-	case *map[uint]int16:
-		fastpathTV.EncMapUintInt16V(*v, e)
-	case map[uint]int32:
-		fastpathTV.EncMapUintInt32V(v, e)
-	case *map[uint]int32:
-		fastpathTV.EncMapUintInt32V(*v, e)
-	case map[uint]int64:
-		fastpathTV.EncMapUintInt64V(v, e)
-	case *map[uint]int64:
-		fastpathTV.EncMapUintInt64V(*v, e)
-	case map[uint]float32:
-		fastpathTV.EncMapUintFloat32V(v, e)
-	case *map[uint]float32:
-		fastpathTV.EncMapUintFloat32V(*v, e)
-	case map[uint]float64:
-		fastpathTV.EncMapUintFloat64V(v, e)
-	case *map[uint]float64:
-		fastpathTV.EncMapUintFloat64V(*v, e)
-	case map[uint]bool:
-		fastpathTV.EncMapUintBoolV(v, e)
-	case *map[uint]bool:
-		fastpathTV.EncMapUintBoolV(*v, e)
-	case map[uint8]interface{}:
-		fastpathTV.EncMapUint8IntfV(v, e)
-	case *map[uint8]interface{}:
-		fastpathTV.EncMapUint8IntfV(*v, e)
-	case map[uint8]string:
-		fastpathTV.EncMapUint8StringV(v, e)
-	case *map[uint8]string:
-		fastpathTV.EncMapUint8StringV(*v, e)
-	case map[uint8]uint:
-		fastpathTV.EncMapUint8UintV(v, e)
-	case *map[uint8]uint:
-		fastpathTV.EncMapUint8UintV(*v, e)
-	case map[uint8]uint8:
-		fastpathTV.EncMapUint8Uint8V(v, e)
-	case *map[uint8]uint8:
-		fastpathTV.EncMapUint8Uint8V(*v, e)
-	case map[uint8]uint16:
-		fastpathTV.EncMapUint8Uint16V(v, e)
-	case *map[uint8]uint16:
-		fastpathTV.EncMapUint8Uint16V(*v, e)
-	case map[uint8]uint32:
-		fastpathTV.EncMapUint8Uint32V(v, e)
-	case *map[uint8]uint32:
-		fastpathTV.EncMapUint8Uint32V(*v, e)
-	case map[uint8]uint64:
-		fastpathTV.EncMapUint8Uint64V(v, e)
-	case *map[uint8]uint64:
-		fastpathTV.EncMapUint8Uint64V(*v, e)
-	case map[uint8]uintptr:
-		fastpathTV.EncMapUint8UintptrV(v, e)
-	case *map[uint8]uintptr:
-		fastpathTV.EncMapUint8UintptrV(*v, e)
-	case map[uint8]int:
-		fastpathTV.EncMapUint8IntV(v, e)
-	case *map[uint8]int:
-		fastpathTV.EncMapUint8IntV(*v, e)
-	case map[uint8]int8:
-		fastpathTV.EncMapUint8Int8V(v, e)
-	case *map[uint8]int8:
-		fastpathTV.EncMapUint8Int8V(*v, e)
-	case map[uint8]int16:
-		fastpathTV.EncMapUint8Int16V(v, e)
-	case *map[uint8]int16:
-		fastpathTV.EncMapUint8Int16V(*v, e)
-	case map[uint8]int32:
-		fastpathTV.EncMapUint8Int32V(v, e)
-	case *map[uint8]int32:
-		fastpathTV.EncMapUint8Int32V(*v, e)
-	case map[uint8]int64:
-		fastpathTV.EncMapUint8Int64V(v, e)
-	case *map[uint8]int64:
-		fastpathTV.EncMapUint8Int64V(*v, e)
-	case map[uint8]float32:
-		fastpathTV.EncMapUint8Float32V(v, e)
-	case *map[uint8]float32:
-		fastpathTV.EncMapUint8Float32V(*v, e)
-	case map[uint8]float64:
-		fastpathTV.EncMapUint8Float64V(v, e)
-	case *map[uint8]float64:
-		fastpathTV.EncMapUint8Float64V(*v, e)
-	case map[uint8]bool:
-		fastpathTV.EncMapUint8BoolV(v, e)
-	case *map[uint8]bool:
-		fastpathTV.EncMapUint8BoolV(*v, e)
-	case map[uint16]interface{}:
-		fastpathTV.EncMapUint16IntfV(v, e)
-	case *map[uint16]interface{}:
-		fastpathTV.EncMapUint16IntfV(*v, e)
-	case map[uint16]string:
-		fastpathTV.EncMapUint16StringV(v, e)
-	case *map[uint16]string:
-		fastpathTV.EncMapUint16StringV(*v, e)
-	case map[uint16]uint:
-		fastpathTV.EncMapUint16UintV(v, e)
-	case *map[uint16]uint:
-		fastpathTV.EncMapUint16UintV(*v, e)
-	case map[uint16]uint8:
-		fastpathTV.EncMapUint16Uint8V(v, e)
-	case *map[uint16]uint8:
-		fastpathTV.EncMapUint16Uint8V(*v, e)
-	case map[uint16]uint16:
-		fastpathTV.EncMapUint16Uint16V(v, e)
-	case *map[uint16]uint16:
-		fastpathTV.EncMapUint16Uint16V(*v, e)
-	case map[uint16]uint32:
-		fastpathTV.EncMapUint16Uint32V(v, e)
-	case *map[uint16]uint32:
-		fastpathTV.EncMapUint16Uint32V(*v, e)
-	case map[uint16]uint64:
-		fastpathTV.EncMapUint16Uint64V(v, e)
-	case *map[uint16]uint64:
-		fastpathTV.EncMapUint16Uint64V(*v, e)
-	case map[uint16]uintptr:
-		fastpathTV.EncMapUint16UintptrV(v, e)
-	case *map[uint16]uintptr:
-		fastpathTV.EncMapUint16UintptrV(*v, e)
-	case map[uint16]int:
-		fastpathTV.EncMapUint16IntV(v, e)
-	case *map[uint16]int:
-		fastpathTV.EncMapUint16IntV(*v, e)
-	case map[uint16]int8:
-		fastpathTV.EncMapUint16Int8V(v, e)
-	case *map[uint16]int8:
-		fastpathTV.EncMapUint16Int8V(*v, e)
-	case map[uint16]int16:
-		fastpathTV.EncMapUint16Int16V(v, e)
-	case *map[uint16]int16:
-		fastpathTV.EncMapUint16Int16V(*v, e)
-	case map[uint16]int32:
-		fastpathTV.EncMapUint16Int32V(v, e)
-	case *map[uint16]int32:
-		fastpathTV.EncMapUint16Int32V(*v, e)
-	case map[uint16]int64:
-		fastpathTV.EncMapUint16Int64V(v, e)
-	case *map[uint16]int64:
-		fastpathTV.EncMapUint16Int64V(*v, e)
-	case map[uint16]float32:
-		fastpathTV.EncMapUint16Float32V(v, e)
-	case *map[uint16]float32:
-		fastpathTV.EncMapUint16Float32V(*v, e)
-	case map[uint16]float64:
-		fastpathTV.EncMapUint16Float64V(v, e)
-	case *map[uint16]float64:
-		fastpathTV.EncMapUint16Float64V(*v, e)
-	case map[uint16]bool:
-		fastpathTV.EncMapUint16BoolV(v, e)
-	case *map[uint16]bool:
-		fastpathTV.EncMapUint16BoolV(*v, e)
-	case map[uint32]interface{}:
-		fastpathTV.EncMapUint32IntfV(v, e)
-	case *map[uint32]interface{}:
-		fastpathTV.EncMapUint32IntfV(*v, e)
-	case map[uint32]string:
-		fastpathTV.EncMapUint32StringV(v, e)
-	case *map[uint32]string:
-		fastpathTV.EncMapUint32StringV(*v, e)
-	case map[uint32]uint:
-		fastpathTV.EncMapUint32UintV(v, e)
-	case *map[uint32]uint:
-		fastpathTV.EncMapUint32UintV(*v, e)
-	case map[uint32]uint8:
-		fastpathTV.EncMapUint32Uint8V(v, e)
-	case *map[uint32]uint8:
-		fastpathTV.EncMapUint32Uint8V(*v, e)
-	case map[uint32]uint16:
-		fastpathTV.EncMapUint32Uint16V(v, e)
-	case *map[uint32]uint16:
-		fastpathTV.EncMapUint32Uint16V(*v, e)
-	case map[uint32]uint32:
-		fastpathTV.EncMapUint32Uint32V(v, e)
-	case *map[uint32]uint32:
-		fastpathTV.EncMapUint32Uint32V(*v, e)
-	case map[uint32]uint64:
-		fastpathTV.EncMapUint32Uint64V(v, e)
-	case *map[uint32]uint64:
-		fastpathTV.EncMapUint32Uint64V(*v, e)
-	case map[uint32]uintptr:
-		fastpathTV.EncMapUint32UintptrV(v, e)
-	case *map[uint32]uintptr:
-		fastpathTV.EncMapUint32UintptrV(*v, e)
-	case map[uint32]int:
-		fastpathTV.EncMapUint32IntV(v, e)
-	case *map[uint32]int:
-		fastpathTV.EncMapUint32IntV(*v, e)
-	case map[uint32]int8:
-		fastpathTV.EncMapUint32Int8V(v, e)
-	case *map[uint32]int8:
-		fastpathTV.EncMapUint32Int8V(*v, e)
-	case map[uint32]int16:
-		fastpathTV.EncMapUint32Int16V(v, e)
-	case *map[uint32]int16:
-		fastpathTV.EncMapUint32Int16V(*v, e)
-	case map[uint32]int32:
-		fastpathTV.EncMapUint32Int32V(v, e)
-	case *map[uint32]int32:
-		fastpathTV.EncMapUint32Int32V(*v, e)
-	case map[uint32]int64:
-		fastpathTV.EncMapUint32Int64V(v, e)
-	case *map[uint32]int64:
-		fastpathTV.EncMapUint32Int64V(*v, e)
-	case map[uint32]float32:
-		fastpathTV.EncMapUint32Float32V(v, e)
-	case *map[uint32]float32:
-		fastpathTV.EncMapUint32Float32V(*v, e)
-	case map[uint32]float64:
-		fastpathTV.EncMapUint32Float64V(v, e)
-	case *map[uint32]float64:
-		fastpathTV.EncMapUint32Float64V(*v, e)
-	case map[uint32]bool:
-		fastpathTV.EncMapUint32BoolV(v, e)
-	case *map[uint32]bool:
-		fastpathTV.EncMapUint32BoolV(*v, e)
-	case map[uint64]interface{}:
-		fastpathTV.EncMapUint64IntfV(v, e)
-	case *map[uint64]interface{}:
-		fastpathTV.EncMapUint64IntfV(*v, e)
-	case map[uint64]string:
-		fastpathTV.EncMapUint64StringV(v, e)
-	case *map[uint64]string:
-		fastpathTV.EncMapUint64StringV(*v, e)
-	case map[uint64]uint:
-		fastpathTV.EncMapUint64UintV(v, e)
-	case *map[uint64]uint:
-		fastpathTV.EncMapUint64UintV(*v, e)
-	case map[uint64]uint8:
-		fastpathTV.EncMapUint64Uint8V(v, e)
-	case *map[uint64]uint8:
-		fastpathTV.EncMapUint64Uint8V(*v, e)
-	case map[uint64]uint16:
-		fastpathTV.EncMapUint64Uint16V(v, e)
-	case *map[uint64]uint16:
-		fastpathTV.EncMapUint64Uint16V(*v, e)
-	case map[uint64]uint32:
-		fastpathTV.EncMapUint64Uint32V(v, e)
-	case *map[uint64]uint32:
-		fastpathTV.EncMapUint64Uint32V(*v, e)
-	case map[uint64]uint64:
-		fastpathTV.EncMapUint64Uint64V(v, e)
-	case *map[uint64]uint64:
-		fastpathTV.EncMapUint64Uint64V(*v, e)
-	case map[uint64]uintptr:
-		fastpathTV.EncMapUint64UintptrV(v, e)
-	case *map[uint64]uintptr:
-		fastpathTV.EncMapUint64UintptrV(*v, e)
-	case map[uint64]int:
-		fastpathTV.EncMapUint64IntV(v, e)
-	case *map[uint64]int:
-		fastpathTV.EncMapUint64IntV(*v, e)
-	case map[uint64]int8:
-		fastpathTV.EncMapUint64Int8V(v, e)
-	case *map[uint64]int8:
-		fastpathTV.EncMapUint64Int8V(*v, e)
-	case map[uint64]int16:
-		fastpathTV.EncMapUint64Int16V(v, e)
-	case *map[uint64]int16:
-		fastpathTV.EncMapUint64Int16V(*v, e)
-	case map[uint64]int32:
-		fastpathTV.EncMapUint64Int32V(v, e)
-	case *map[uint64]int32:
-		fastpathTV.EncMapUint64Int32V(*v, e)
-	case map[uint64]int64:
-		fastpathTV.EncMapUint64Int64V(v, e)
-	case *map[uint64]int64:
-		fastpathTV.EncMapUint64Int64V(*v, e)
-	case map[uint64]float32:
-		fastpathTV.EncMapUint64Float32V(v, e)
-	case *map[uint64]float32:
-		fastpathTV.EncMapUint64Float32V(*v, e)
-	case map[uint64]float64:
-		fastpathTV.EncMapUint64Float64V(v, e)
-	case *map[uint64]float64:
-		fastpathTV.EncMapUint64Float64V(*v, e)
-	case map[uint64]bool:
-		fastpathTV.EncMapUint64BoolV(v, e)
-	case *map[uint64]bool:
-		fastpathTV.EncMapUint64BoolV(*v, e)
-	case map[uintptr]interface{}:
-		fastpathTV.EncMapUintptrIntfV(v, e)
-	case *map[uintptr]interface{}:
-		fastpathTV.EncMapUintptrIntfV(*v, e)
-	case map[uintptr]string:
-		fastpathTV.EncMapUintptrStringV(v, e)
-	case *map[uintptr]string:
-		fastpathTV.EncMapUintptrStringV(*v, e)
-	case map[uintptr]uint:
-		fastpathTV.EncMapUintptrUintV(v, e)
-	case *map[uintptr]uint:
-		fastpathTV.EncMapUintptrUintV(*v, e)
-	case map[uintptr]uint8:
-		fastpathTV.EncMapUintptrUint8V(v, e)
-	case *map[uintptr]uint8:
-		fastpathTV.EncMapUintptrUint8V(*v, e)
-	case map[uintptr]uint16:
-		fastpathTV.EncMapUintptrUint16V(v, e)
-	case *map[uintptr]uint16:
-		fastpathTV.EncMapUintptrUint16V(*v, e)
-	case map[uintptr]uint32:
-		fastpathTV.EncMapUintptrUint32V(v, e)
-	case *map[uintptr]uint32:
-		fastpathTV.EncMapUintptrUint32V(*v, e)
-	case map[uintptr]uint64:
-		fastpathTV.EncMapUintptrUint64V(v, e)
-	case *map[uintptr]uint64:
-		fastpathTV.EncMapUintptrUint64V(*v, e)
-	case map[uintptr]uintptr:
-		fastpathTV.EncMapUintptrUintptrV(v, e)
-	case *map[uintptr]uintptr:
-		fastpathTV.EncMapUintptrUintptrV(*v, e)
-	case map[uintptr]int:
-		fastpathTV.EncMapUintptrIntV(v, e)
-	case *map[uintptr]int:
-		fastpathTV.EncMapUintptrIntV(*v, e)
-	case map[uintptr]int8:
-		fastpathTV.EncMapUintptrInt8V(v, e)
-	case *map[uintptr]int8:
-		fastpathTV.EncMapUintptrInt8V(*v, e)
-	case map[uintptr]int16:
-		fastpathTV.EncMapUintptrInt16V(v, e)
-	case *map[uintptr]int16:
-		fastpathTV.EncMapUintptrInt16V(*v, e)
-	case map[uintptr]int32:
-		fastpathTV.EncMapUintptrInt32V(v, e)
-	case *map[uintptr]int32:
-		fastpathTV.EncMapUintptrInt32V(*v, e)
-	case map[uintptr]int64:
-		fastpathTV.EncMapUintptrInt64V(v, e)
-	case *map[uintptr]int64:
-		fastpathTV.EncMapUintptrInt64V(*v, e)
-	case map[uintptr]float32:
-		fastpathTV.EncMapUintptrFloat32V(v, e)
-	case *map[uintptr]float32:
-		fastpathTV.EncMapUintptrFloat32V(*v, e)
-	case map[uintptr]float64:
-		fastpathTV.EncMapUintptrFloat64V(v, e)
-	case *map[uintptr]float64:
-		fastpathTV.EncMapUintptrFloat64V(*v, e)
-	case map[uintptr]bool:
-		fastpathTV.EncMapUintptrBoolV(v, e)
-	case *map[uintptr]bool:
-		fastpathTV.EncMapUintptrBoolV(*v, e)
-	case map[int]interface{}:
-		fastpathTV.EncMapIntIntfV(v, e)
-	case *map[int]interface{}:
-		fastpathTV.EncMapIntIntfV(*v, e)
-	case map[int]string:
-		fastpathTV.EncMapIntStringV(v, e)
-	case *map[int]string:
-		fastpathTV.EncMapIntStringV(*v, e)
-	case map[int]uint:
-		fastpathTV.EncMapIntUintV(v, e)
-	case *map[int]uint:
-		fastpathTV.EncMapIntUintV(*v, e)
-	case map[int]uint8:
-		fastpathTV.EncMapIntUint8V(v, e)
-	case *map[int]uint8:
-		fastpathTV.EncMapIntUint8V(*v, e)
-	case map[int]uint16:
-		fastpathTV.EncMapIntUint16V(v, e)
-	case *map[int]uint16:
-		fastpathTV.EncMapIntUint16V(*v, e)
-	case map[int]uint32:
-		fastpathTV.EncMapIntUint32V(v, e)
-	case *map[int]uint32:
-		fastpathTV.EncMapIntUint32V(*v, e)
-	case map[int]uint64:
-		fastpathTV.EncMapIntUint64V(v, e)
-	case *map[int]uint64:
-		fastpathTV.EncMapIntUint64V(*v, e)
-	case map[int]uintptr:
-		fastpathTV.EncMapIntUintptrV(v, e)
-	case *map[int]uintptr:
-		fastpathTV.EncMapIntUintptrV(*v, e)
-	case map[int]int:
-		fastpathTV.EncMapIntIntV(v, e)
-	case *map[int]int:
-		fastpathTV.EncMapIntIntV(*v, e)
-	case map[int]int8:
-		fastpathTV.EncMapIntInt8V(v, e)
-	case *map[int]int8:
-		fastpathTV.EncMapIntInt8V(*v, e)
-	case map[int]int16:
-		fastpathTV.EncMapIntInt16V(v, e)
-	case *map[int]int16:
-		fastpathTV.EncMapIntInt16V(*v, e)
-	case map[int]int32:
-		fastpathTV.EncMapIntInt32V(v, e)
-	case *map[int]int32:
-		fastpathTV.EncMapIntInt32V(*v, e)
-	case map[int]int64:
-		fastpathTV.EncMapIntInt64V(v, e)
-	case *map[int]int64:
-		fastpathTV.EncMapIntInt64V(*v, e)
-	case map[int]float32:
-		fastpathTV.EncMapIntFloat32V(v, e)
-	case *map[int]float32:
-		fastpathTV.EncMapIntFloat32V(*v, e)
-	case map[int]float64:
-		fastpathTV.EncMapIntFloat64V(v, e)
-	case *map[int]float64:
-		fastpathTV.EncMapIntFloat64V(*v, e)
-	case map[int]bool:
-		fastpathTV.EncMapIntBoolV(v, e)
-	case *map[int]bool:
-		fastpathTV.EncMapIntBoolV(*v, e)
-	case map[int8]interface{}:
-		fastpathTV.EncMapInt8IntfV(v, e)
-	case *map[int8]interface{}:
-		fastpathTV.EncMapInt8IntfV(*v, e)
-	case map[int8]string:
-		fastpathTV.EncMapInt8StringV(v, e)
-	case *map[int8]string:
-		fastpathTV.EncMapInt8StringV(*v, e)
-	case map[int8]uint:
-		fastpathTV.EncMapInt8UintV(v, e)
-	case *map[int8]uint:
-		fastpathTV.EncMapInt8UintV(*v, e)
-	case map[int8]uint8:
-		fastpathTV.EncMapInt8Uint8V(v, e)
-	case *map[int8]uint8:
-		fastpathTV.EncMapInt8Uint8V(*v, e)
-	case map[int8]uint16:
-		fastpathTV.EncMapInt8Uint16V(v, e)
-	case *map[int8]uint16:
-		fastpathTV.EncMapInt8Uint16V(*v, e)
-	case map[int8]uint32:
-		fastpathTV.EncMapInt8Uint32V(v, e)
-	case *map[int8]uint32:
-		fastpathTV.EncMapInt8Uint32V(*v, e)
-	case map[int8]uint64:
-		fastpathTV.EncMapInt8Uint64V(v, e)
-	case *map[int8]uint64:
-		fastpathTV.EncMapInt8Uint64V(*v, e)
-	case map[int8]uintptr:
-		fastpathTV.EncMapInt8UintptrV(v, e)
-	case *map[int8]uintptr:
-		fastpathTV.EncMapInt8UintptrV(*v, e)
-	case map[int8]int:
-		fastpathTV.EncMapInt8IntV(v, e)
-	case *map[int8]int:
-		fastpathTV.EncMapInt8IntV(*v, e)
-	case map[int8]int8:
-		fastpathTV.EncMapInt8Int8V(v, e)
-	case *map[int8]int8:
-		fastpathTV.EncMapInt8Int8V(*v, e)
-	case map[int8]int16:
-		fastpathTV.EncMapInt8Int16V(v, e)
-	case *map[int8]int16:
-		fastpathTV.EncMapInt8Int16V(*v, e)
-	case map[int8]int32:
-		fastpathTV.EncMapInt8Int32V(v, e)
-	case *map[int8]int32:
-		fastpathTV.EncMapInt8Int32V(*v, e)
-	case map[int8]int64:
-		fastpathTV.EncMapInt8Int64V(v, e)
-	case *map[int8]int64:
-		fastpathTV.EncMapInt8Int64V(*v, e)
-	case map[int8]float32:
-		fastpathTV.EncMapInt8Float32V(v, e)
-	case *map[int8]float32:
-		fastpathTV.EncMapInt8Float32V(*v, e)
-	case map[int8]float64:
-		fastpathTV.EncMapInt8Float64V(v, e)
-	case *map[int8]float64:
-		fastpathTV.EncMapInt8Float64V(*v, e)
-	case map[int8]bool:
-		fastpathTV.EncMapInt8BoolV(v, e)
-	case *map[int8]bool:
-		fastpathTV.EncMapInt8BoolV(*v, e)
-	case map[int16]interface{}:
-		fastpathTV.EncMapInt16IntfV(v, e)
-	case *map[int16]interface{}:
-		fastpathTV.EncMapInt16IntfV(*v, e)
-	case map[int16]string:
-		fastpathTV.EncMapInt16StringV(v, e)
-	case *map[int16]string:
-		fastpathTV.EncMapInt16StringV(*v, e)
-	case map[int16]uint:
-		fastpathTV.EncMapInt16UintV(v, e)
-	case *map[int16]uint:
-		fastpathTV.EncMapInt16UintV(*v, e)
-	case map[int16]uint8:
-		fastpathTV.EncMapInt16Uint8V(v, e)
-	case *map[int16]uint8:
-		fastpathTV.EncMapInt16Uint8V(*v, e)
-	case map[int16]uint16:
-		fastpathTV.EncMapInt16Uint16V(v, e)
-	case *map[int16]uint16:
-		fastpathTV.EncMapInt16Uint16V(*v, e)
-	case map[int16]uint32:
-		fastpathTV.EncMapInt16Uint32V(v, e)
-	case *map[int16]uint32:
-		fastpathTV.EncMapInt16Uint32V(*v, e)
-	case map[int16]uint64:
-		fastpathTV.EncMapInt16Uint64V(v, e)
-	case *map[int16]uint64:
-		fastpathTV.EncMapInt16Uint64V(*v, e)
-	case map[int16]uintptr:
-		fastpathTV.EncMapInt16UintptrV(v, e)
-	case *map[int16]uintptr:
-		fastpathTV.EncMapInt16UintptrV(*v, e)
-	case map[int16]int:
-		fastpathTV.EncMapInt16IntV(v, e)
-	case *map[int16]int:
-		fastpathTV.EncMapInt16IntV(*v, e)
-	case map[int16]int8:
-		fastpathTV.EncMapInt16Int8V(v, e)
-	case *map[int16]int8:
-		fastpathTV.EncMapInt16Int8V(*v, e)
-	case map[int16]int16:
-		fastpathTV.EncMapInt16Int16V(v, e)
-	case *map[int16]int16:
-		fastpathTV.EncMapInt16Int16V(*v, e)
-	case map[int16]int32:
-		fastpathTV.EncMapInt16Int32V(v, e)
-	case *map[int16]int32:
-		fastpathTV.EncMapInt16Int32V(*v, e)
-	case map[int16]int64:
-		fastpathTV.EncMapInt16Int64V(v, e)
-	case *map[int16]int64:
-		fastpathTV.EncMapInt16Int64V(*v, e)
-	case map[int16]float32:
-		fastpathTV.EncMapInt16Float32V(v, e)
-	case *map[int16]float32:
-		fastpathTV.EncMapInt16Float32V(*v, e)
-	case map[int16]float64:
-		fastpathTV.EncMapInt16Float64V(v, e)
-	case *map[int16]float64:
-		fastpathTV.EncMapInt16Float64V(*v, e)
-	case map[int16]bool:
-		fastpathTV.EncMapInt16BoolV(v, e)
-	case *map[int16]bool:
-		fastpathTV.EncMapInt16BoolV(*v, e)
-	case map[int32]interface{}:
-		fastpathTV.EncMapInt32IntfV(v, e)
-	case *map[int32]interface{}:
-		fastpathTV.EncMapInt32IntfV(*v, e)
-	case map[int32]string:
-		fastpathTV.EncMapInt32StringV(v, e)
-	case *map[int32]string:
-		fastpathTV.EncMapInt32StringV(*v, e)
-	case map[int32]uint:
-		fastpathTV.EncMapInt32UintV(v, e)
-	case *map[int32]uint:
-		fastpathTV.EncMapInt32UintV(*v, e)
-	case map[int32]uint8:
-		fastpathTV.EncMapInt32Uint8V(v, e)
-	case *map[int32]uint8:
-		fastpathTV.EncMapInt32Uint8V(*v, e)
-	case map[int32]uint16:
-		fastpathTV.EncMapInt32Uint16V(v, e)
-	case *map[int32]uint16:
-		fastpathTV.EncMapInt32Uint16V(*v, e)
-	case map[int32]uint32:
-		fastpathTV.EncMapInt32Uint32V(v, e)
-	case *map[int32]uint32:
-		fastpathTV.EncMapInt32Uint32V(*v, e)
-	case map[int32]uint64:
-		fastpathTV.EncMapInt32Uint64V(v, e)
-	case *map[int32]uint64:
-		fastpathTV.EncMapInt32Uint64V(*v, e)
-	case map[int32]uintptr:
-		fastpathTV.EncMapInt32UintptrV(v, e)
-	case *map[int32]uintptr:
-		fastpathTV.EncMapInt32UintptrV(*v, e)
-	case map[int32]int:
-		fastpathTV.EncMapInt32IntV(v, e)
-	case *map[int32]int:
-		fastpathTV.EncMapInt32IntV(*v, e)
-	case map[int32]int8:
-		fastpathTV.EncMapInt32Int8V(v, e)
-	case *map[int32]int8:
-		fastpathTV.EncMapInt32Int8V(*v, e)
-	case map[int32]int16:
-		fastpathTV.EncMapInt32Int16V(v, e)
-	case *map[int32]int16:
-		fastpathTV.EncMapInt32Int16V(*v, e)
-	case map[int32]int32:
-		fastpathTV.EncMapInt32Int32V(v, e)
-	case *map[int32]int32:
-		fastpathTV.EncMapInt32Int32V(*v, e)
-	case map[int32]int64:
-		fastpathTV.EncMapInt32Int64V(v, e)
-	case *map[int32]int64:
-		fastpathTV.EncMapInt32Int64V(*v, e)
-	case map[int32]float32:
-		fastpathTV.EncMapInt32Float32V(v, e)
-	case *map[int32]float32:
-		fastpathTV.EncMapInt32Float32V(*v, e)
-	case map[int32]float64:
-		fastpathTV.EncMapInt32Float64V(v, e)
-	case *map[int32]float64:
-		fastpathTV.EncMapInt32Float64V(*v, e)
-	case map[int32]bool:
-		fastpathTV.EncMapInt32BoolV(v, e)
-	case *map[int32]bool:
-		fastpathTV.EncMapInt32BoolV(*v, e)
-	case map[int64]interface{}:
-		fastpathTV.EncMapInt64IntfV(v, e)
-	case *map[int64]interface{}:
-		fastpathTV.EncMapInt64IntfV(*v, e)
-	case map[int64]string:
-		fastpathTV.EncMapInt64StringV(v, e)
-	case *map[int64]string:
-		fastpathTV.EncMapInt64StringV(*v, e)
-	case map[int64]uint:
-		fastpathTV.EncMapInt64UintV(v, e)
-	case *map[int64]uint:
-		fastpathTV.EncMapInt64UintV(*v, e)
-	case map[int64]uint8:
-		fastpathTV.EncMapInt64Uint8V(v, e)
-	case *map[int64]uint8:
-		fastpathTV.EncMapInt64Uint8V(*v, e)
-	case map[int64]uint16:
-		fastpathTV.EncMapInt64Uint16V(v, e)
-	case *map[int64]uint16:
-		fastpathTV.EncMapInt64Uint16V(*v, e)
-	case map[int64]uint32:
-		fastpathTV.EncMapInt64Uint32V(v, e)
-	case *map[int64]uint32:
-		fastpathTV.EncMapInt64Uint32V(*v, e)
-	case map[int64]uint64:
-		fastpathTV.EncMapInt64Uint64V(v, e)
-	case *map[int64]uint64:
-		fastpathTV.EncMapInt64Uint64V(*v, e)
-	case map[int64]uintptr:
-		fastpathTV.EncMapInt64UintptrV(v, e)
-	case *map[int64]uintptr:
-		fastpathTV.EncMapInt64UintptrV(*v, e)
-	case map[int64]int:
-		fastpathTV.EncMapInt64IntV(v, e)
-	case *map[int64]int:
-		fastpathTV.EncMapInt64IntV(*v, e)
-	case map[int64]int8:
-		fastpathTV.EncMapInt64Int8V(v, e)
-	case *map[int64]int8:
-		fastpathTV.EncMapInt64Int8V(*v, e)
-	case map[int64]int16:
-		fastpathTV.EncMapInt64Int16V(v, e)
-	case *map[int64]int16:
-		fastpathTV.EncMapInt64Int16V(*v, e)
-	case map[int64]int32:
-		fastpathTV.EncMapInt64Int32V(v, e)
-	case *map[int64]int32:
-		fastpathTV.EncMapInt64Int32V(*v, e)
-	case map[int64]int64:
-		fastpathTV.EncMapInt64Int64V(v, e)
-	case *map[int64]int64:
-		fastpathTV.EncMapInt64Int64V(*v, e)
-	case map[int64]float32:
-		fastpathTV.EncMapInt64Float32V(v, e)
-	case *map[int64]float32:
-		fastpathTV.EncMapInt64Float32V(*v, e)
-	case map[int64]float64:
-		fastpathTV.EncMapInt64Float64V(v, e)
-	case *map[int64]float64:
-		fastpathTV.EncMapInt64Float64V(*v, e)
-	case map[int64]bool:
-		fastpathTV.EncMapInt64BoolV(v, e)
-	case *map[int64]bool:
-		fastpathTV.EncMapInt64BoolV(*v, e)
-	case map[bool]interface{}:
-		fastpathTV.EncMapBoolIntfV(v, e)
-	case *map[bool]interface{}:
-		fastpathTV.EncMapBoolIntfV(*v, e)
-	case map[bool]string:
-		fastpathTV.EncMapBoolStringV(v, e)
-	case *map[bool]string:
-		fastpathTV.EncMapBoolStringV(*v, e)
-	case map[bool]uint:
-		fastpathTV.EncMapBoolUintV(v, e)
-	case *map[bool]uint:
-		fastpathTV.EncMapBoolUintV(*v, e)
-	case map[bool]uint8:
-		fastpathTV.EncMapBoolUint8V(v, e)
-	case *map[bool]uint8:
-		fastpathTV.EncMapBoolUint8V(*v, e)
-	case map[bool]uint16:
-		fastpathTV.EncMapBoolUint16V(v, e)
-	case *map[bool]uint16:
-		fastpathTV.EncMapBoolUint16V(*v, e)
-	case map[bool]uint32:
-		fastpathTV.EncMapBoolUint32V(v, e)
-	case *map[bool]uint32:
-		fastpathTV.EncMapBoolUint32V(*v, e)
-	case map[bool]uint64:
-		fastpathTV.EncMapBoolUint64V(v, e)
-	case *map[bool]uint64:
-		fastpathTV.EncMapBoolUint64V(*v, e)
-	case map[bool]uintptr:
-		fastpathTV.EncMapBoolUintptrV(v, e)
-	case *map[bool]uintptr:
-		fastpathTV.EncMapBoolUintptrV(*v, e)
-	case map[bool]int:
-		fastpathTV.EncMapBoolIntV(v, e)
-	case *map[bool]int:
-		fastpathTV.EncMapBoolIntV(*v, e)
-	case map[bool]int8:
-		fastpathTV.EncMapBoolInt8V(v, e)
-	case *map[bool]int8:
-		fastpathTV.EncMapBoolInt8V(*v, e)
-	case map[bool]int16:
-		fastpathTV.EncMapBoolInt16V(v, e)
-	case *map[bool]int16:
-		fastpathTV.EncMapBoolInt16V(*v, e)
-	case map[bool]int32:
-		fastpathTV.EncMapBoolInt32V(v, e)
-	case *map[bool]int32:
-		fastpathTV.EncMapBoolInt32V(*v, e)
-	case map[bool]int64:
-		fastpathTV.EncMapBoolInt64V(v, e)
-	case *map[bool]int64:
-		fastpathTV.EncMapBoolInt64V(*v, e)
-	case map[bool]float32:
-		fastpathTV.EncMapBoolFloat32V(v, e)
-	case *map[bool]float32:
-		fastpathTV.EncMapBoolFloat32V(*v, e)
-	case map[bool]float64:
-		fastpathTV.EncMapBoolFloat64V(v, e)
-	case *map[bool]float64:
-		fastpathTV.EncMapBoolFloat64V(*v, e)
-	case map[bool]bool:
-		fastpathTV.EncMapBoolBoolV(v, e)
-	case *map[bool]bool:
-		fastpathTV.EncMapBoolBoolV(*v, e)
-
-	default:
-		_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
-		return false
-	}
-	return true
-}
-
-// -- -- fast path functions
-
-func (e *Encoder) fastpathEncSliceIntfR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceIntfV(rv2i(rv).([]interface{}), e)
-	} else {
-		fastpathTV.EncSliceIntfV(rv2i(rv).([]interface{}), e)
-	}
-}
-func (_ fastpathT) EncSliceIntfV(v []interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			e.encode(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			e.encode(v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceIntfV(v []interface{}, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			e.encode(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			e.encode(v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceStringR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceStringV(rv2i(rv).([]string), e)
-	} else {
-		fastpathTV.EncSliceStringV(rv2i(rv).([]string), e)
-	}
-}
-func (_ fastpathT) EncSliceStringV(v []string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeString(cUTF8, v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeString(cUTF8, v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceStringV(v []string, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeString(cUTF8, v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeString(cUTF8, v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceFloat32V(rv2i(rv).([]float32), e)
-	} else {
-		fastpathTV.EncSliceFloat32V(rv2i(rv).([]float32), e)
-	}
-}
-func (_ fastpathT) EncSliceFloat32V(v []float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeFloat32(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeFloat32(v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceFloat32V(v []float32, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeFloat32(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeFloat32(v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceFloat64V(rv2i(rv).([]float64), e)
-	} else {
-		fastpathTV.EncSliceFloat64V(rv2i(rv).([]float64), e)
-	}
-}
-func (_ fastpathT) EncSliceFloat64V(v []float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeFloat64(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeFloat64(v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceFloat64V(v []float64, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeFloat64(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeFloat64(v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceUintR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUintV(rv2i(rv).([]uint), e)
-	} else {
-		fastpathTV.EncSliceUintV(rv2i(rv).([]uint), e)
-	}
-}
-func (_ fastpathT) EncSliceUintV(v []uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUintV(v []uint, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceUint8R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUint8V(rv2i(rv).([]uint8), e)
-	} else {
-		fastpathTV.EncSliceUint8V(rv2i(rv).([]uint8), e)
-	}
-}
-func (_ fastpathT) EncSliceUint8V(v []uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUint8V(v []uint8, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceUint16R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUint16V(rv2i(rv).([]uint16), e)
-	} else {
-		fastpathTV.EncSliceUint16V(rv2i(rv).([]uint16), e)
-	}
-}
-func (_ fastpathT) EncSliceUint16V(v []uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUint16V(v []uint16, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceUint32R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUint32V(rv2i(rv).([]uint32), e)
-	} else {
-		fastpathTV.EncSliceUint32V(rv2i(rv).([]uint32), e)
-	}
-}
-func (_ fastpathT) EncSliceUint32V(v []uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUint32V(v []uint32, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceUint64R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUint64V(rv2i(rv).([]uint64), e)
-	} else {
-		fastpathTV.EncSliceUint64V(rv2i(rv).([]uint64), e)
-	}
-}
-func (_ fastpathT) EncSliceUint64V(v []uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUint64V(v []uint64, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeUint(uint64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeUint(uint64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceUintptrV(rv2i(rv).([]uintptr), e)
-	} else {
-		fastpathTV.EncSliceUintptrV(rv2i(rv).([]uintptr), e)
-	}
-}
-func (_ fastpathT) EncSliceUintptrV(v []uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			e.encode(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			e.encode(v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceUintptrV(v []uintptr, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			e.encode(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			e.encode(v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceIntR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceIntV(rv2i(rv).([]int), e)
-	} else {
-		fastpathTV.EncSliceIntV(rv2i(rv).([]int), e)
-	}
-}
-func (_ fastpathT) EncSliceIntV(v []int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceIntV(v []int, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceInt8R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceInt8V(rv2i(rv).([]int8), e)
-	} else {
-		fastpathTV.EncSliceInt8V(rv2i(rv).([]int8), e)
-	}
-}
-func (_ fastpathT) EncSliceInt8V(v []int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceInt8V(v []int8, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceInt16R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceInt16V(rv2i(rv).([]int16), e)
-	} else {
-		fastpathTV.EncSliceInt16V(rv2i(rv).([]int16), e)
-	}
-}
-func (_ fastpathT) EncSliceInt16V(v []int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceInt16V(v []int16, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceInt32R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceInt32V(rv2i(rv).([]int32), e)
-	} else {
-		fastpathTV.EncSliceInt32V(rv2i(rv).([]int32), e)
-	}
-}
-func (_ fastpathT) EncSliceInt32V(v []int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceInt32V(v []int32, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceInt64R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceInt64V(rv2i(rv).([]int64), e)
-	} else {
-		fastpathTV.EncSliceInt64V(rv2i(rv).([]int64), e)
-	}
-}
-func (_ fastpathT) EncSliceInt64V(v []int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceInt64V(v []int64, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeInt(int64(v2))
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeInt(int64(v2))
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncSliceBoolR(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.EncAsMapSliceBoolV(rv2i(rv).([]bool), e)
-	} else {
-		fastpathTV.EncSliceBoolV(rv2i(rv).([]bool), e)
-	}
-}
-func (_ fastpathT) EncSliceBoolV(v []bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			ee.EncodeBool(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeBool(v2)
-		}
-	}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) EncAsMapSliceBoolV(v []bool, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			ee.EncodeBool(v2)
-		}
-	} else {
-		for _, v2 := range v {
-			ee.EncodeBool(v2)
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfIntfV(rv2i(rv).(map[interface{}]interface{}), e)
-}
-func (_ fastpathT) EncMapIntfIntfV(v map[interface{}]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfStringV(rv2i(rv).(map[interface{}]string), e)
-}
-func (_ fastpathT) EncMapIntfStringV(v map[interface{}]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUintV(rv2i(rv).(map[interface{}]uint), e)
-}
-func (_ fastpathT) EncMapIntfUintV(v map[interface{}]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUint8V(rv2i(rv).(map[interface{}]uint8), e)
-}
-func (_ fastpathT) EncMapIntfUint8V(v map[interface{}]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUint16V(rv2i(rv).(map[interface{}]uint16), e)
-}
-func (_ fastpathT) EncMapIntfUint16V(v map[interface{}]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUint32V(rv2i(rv).(map[interface{}]uint32), e)
-}
-func (_ fastpathT) EncMapIntfUint32V(v map[interface{}]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUint64V(rv2i(rv).(map[interface{}]uint64), e)
-}
-func (_ fastpathT) EncMapIntfUint64V(v map[interface{}]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfUintptrV(rv2i(rv).(map[interface{}]uintptr), e)
-}
-func (_ fastpathT) EncMapIntfUintptrV(v map[interface{}]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfIntV(rv2i(rv).(map[interface{}]int), e)
-}
-func (_ fastpathT) EncMapIntfIntV(v map[interface{}]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfInt8V(rv2i(rv).(map[interface{}]int8), e)
-}
-func (_ fastpathT) EncMapIntfInt8V(v map[interface{}]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfInt16V(rv2i(rv).(map[interface{}]int16), e)
-}
-func (_ fastpathT) EncMapIntfInt16V(v map[interface{}]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfInt32V(rv2i(rv).(map[interface{}]int32), e)
-}
-func (_ fastpathT) EncMapIntfInt32V(v map[interface{}]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfInt64V(rv2i(rv).(map[interface{}]int64), e)
-}
-func (_ fastpathT) EncMapIntfInt64V(v map[interface{}]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfFloat32V(rv2i(rv).(map[interface{}]float32), e)
-}
-func (_ fastpathT) EncMapIntfFloat32V(v map[interface{}]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfFloat64V(rv2i(rv).(map[interface{}]float64), e)
-}
-func (_ fastpathT) EncMapIntfFloat64V(v map[interface{}]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntfBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntfBoolV(rv2i(rv).(map[interface{}]bool), e)
-}
-func (_ fastpathT) EncMapIntfBoolV(v map[interface{}]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringIntfV(rv2i(rv).(map[string]interface{}), e)
-}
-func (_ fastpathT) EncMapStringIntfV(v map[string]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				e.encode(v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				e.encode(v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringStringV(rv2i(rv).(map[string]string), e)
-}
-func (_ fastpathT) EncMapStringStringV(v map[string]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeString(cUTF8, v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUintV(rv2i(rv).(map[string]uint), e)
-}
-func (_ fastpathT) EncMapStringUintV(v map[string]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUint8V(rv2i(rv).(map[string]uint8), e)
-}
-func (_ fastpathT) EncMapStringUint8V(v map[string]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUint16V(rv2i(rv).(map[string]uint16), e)
-}
-func (_ fastpathT) EncMapStringUint16V(v map[string]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUint32V(rv2i(rv).(map[string]uint32), e)
-}
-func (_ fastpathT) EncMapStringUint32V(v map[string]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUint64V(rv2i(rv).(map[string]uint64), e)
-}
-func (_ fastpathT) EncMapStringUint64V(v map[string]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringUintptrV(rv2i(rv).(map[string]uintptr), e)
-}
-func (_ fastpathT) EncMapStringUintptrV(v map[string]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				e.encode(v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				e.encode(v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringIntV(rv2i(rv).(map[string]int), e)
-}
-func (_ fastpathT) EncMapStringIntV(v map[string]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringInt8V(rv2i(rv).(map[string]int8), e)
-}
-func (_ fastpathT) EncMapStringInt8V(v map[string]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringInt16V(rv2i(rv).(map[string]int16), e)
-}
-func (_ fastpathT) EncMapStringInt16V(v map[string]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringInt32V(rv2i(rv).(map[string]int32), e)
-}
-func (_ fastpathT) EncMapStringInt32V(v map[string]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringInt64V(rv2i(rv).(map[string]int64), e)
-}
-func (_ fastpathT) EncMapStringInt64V(v map[string]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v[string(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringFloat32V(rv2i(rv).(map[string]float32), e)
-}
-func (_ fastpathT) EncMapStringFloat32V(v map[string]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeFloat32(v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringFloat64V(rv2i(rv).(map[string]float64), e)
-}
-func (_ fastpathT) EncMapStringFloat64V(v map[string]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeFloat64(v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapStringBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapStringBoolV(rv2i(rv).(map[string]bool), e)
-}
-func (_ fastpathT) EncMapStringBoolV(v map[string]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]string, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = string(k)
-			i++
-		}
-		sort.Sort(stringSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[string(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeBool(v[string(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeString(cUTF8, k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeString(cUTF8, k2)
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32IntfV(rv2i(rv).(map[float32]interface{}), e)
-}
-func (_ fastpathT) EncMapFloat32IntfV(v map[float32]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				e.encode(v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32StringV(rv2i(rv).(map[float32]string), e)
-}
-func (_ fastpathT) EncMapFloat32StringV(v map[float32]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeString(cUTF8, v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32UintV(rv2i(rv).(map[float32]uint), e)
-}
-func (_ fastpathT) EncMapFloat32UintV(v map[float32]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Uint8V(rv2i(rv).(map[float32]uint8), e)
-}
-func (_ fastpathT) EncMapFloat32Uint8V(v map[float32]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Uint16V(rv2i(rv).(map[float32]uint16), e)
-}
-func (_ fastpathT) EncMapFloat32Uint16V(v map[float32]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Uint32V(rv2i(rv).(map[float32]uint32), e)
-}
-func (_ fastpathT) EncMapFloat32Uint32V(v map[float32]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Uint64V(rv2i(rv).(map[float32]uint64), e)
-}
-func (_ fastpathT) EncMapFloat32Uint64V(v map[float32]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeUint(uint64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32UintptrV(rv2i(rv).(map[float32]uintptr), e)
-}
-func (_ fastpathT) EncMapFloat32UintptrV(v map[float32]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				e.encode(v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32IntV(rv2i(rv).(map[float32]int), e)
-}
-func (_ fastpathT) EncMapFloat32IntV(v map[float32]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Int8V(rv2i(rv).(map[float32]int8), e)
-}
-func (_ fastpathT) EncMapFloat32Int8V(v map[float32]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Int16V(rv2i(rv).(map[float32]int16), e)
-}
-func (_ fastpathT) EncMapFloat32Int16V(v map[float32]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Int32V(rv2i(rv).(map[float32]int32), e)
-}
-func (_ fastpathT) EncMapFloat32Int32V(v map[float32]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Int64V(rv2i(rv).(map[float32]int64), e)
-}
-func (_ fastpathT) EncMapFloat32Int64V(v map[float32]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeInt(int64(v[float32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Float32V(rv2i(rv).(map[float32]float32), e)
-}
-func (_ fastpathT) EncMapFloat32Float32V(v map[float32]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeFloat32(v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32Float64V(rv2i(rv).(map[float32]float64), e)
-}
-func (_ fastpathT) EncMapFloat32Float64V(v map[float32]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeFloat64(v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat32BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat32BoolV(rv2i(rv).(map[float32]bool), e)
-}
-func (_ fastpathT) EncMapFloat32BoolV(v map[float32]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(float32(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[float32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat32(float32(k2))
-				ee.EncodeBool(v[float32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat32(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat32(k2)
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64IntfV(rv2i(rv).(map[float64]interface{}), e)
-}
-func (_ fastpathT) EncMapFloat64IntfV(v map[float64]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[float64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				e.encode(v[float64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64StringV(rv2i(rv).(map[float64]string), e)
-}
-func (_ fastpathT) EncMapFloat64StringV(v map[float64]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[float64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeString(cUTF8, v[float64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64UintV(rv2i(rv).(map[float64]uint), e)
-}
-func (_ fastpathT) EncMapFloat64UintV(v map[float64]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Uint8V(rv2i(rv).(map[float64]uint8), e)
-}
-func (_ fastpathT) EncMapFloat64Uint8V(v map[float64]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Uint16V(rv2i(rv).(map[float64]uint16), e)
-}
-func (_ fastpathT) EncMapFloat64Uint16V(v map[float64]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Uint32V(rv2i(rv).(map[float64]uint32), e)
-}
-func (_ fastpathT) EncMapFloat64Uint32V(v map[float64]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Uint64V(rv2i(rv).(map[float64]uint64), e)
-}
-func (_ fastpathT) EncMapFloat64Uint64V(v map[float64]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeUint(uint64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64UintptrV(rv2i(rv).(map[float64]uintptr), e)
-}
-func (_ fastpathT) EncMapFloat64UintptrV(v map[float64]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[float64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				e.encode(v[float64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64IntV(rv2i(rv).(map[float64]int), e)
-}
-func (_ fastpathT) EncMapFloat64IntV(v map[float64]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Int8V(rv2i(rv).(map[float64]int8), e)
-}
-func (_ fastpathT) EncMapFloat64Int8V(v map[float64]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Int16V(rv2i(rv).(map[float64]int16), e)
-}
-func (_ fastpathT) EncMapFloat64Int16V(v map[float64]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Int32V(rv2i(rv).(map[float64]int32), e)
-}
-func (_ fastpathT) EncMapFloat64Int32V(v map[float64]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Int64V(rv2i(rv).(map[float64]int64), e)
-}
-func (_ fastpathT) EncMapFloat64Int64V(v map[float64]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeInt(int64(v[float64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Float32V(rv2i(rv).(map[float64]float32), e)
-}
-func (_ fastpathT) EncMapFloat64Float32V(v map[float64]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[float64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeFloat32(v[float64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64Float64V(rv2i(rv).(map[float64]float64), e)
-}
-func (_ fastpathT) EncMapFloat64Float64V(v map[float64]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[float64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeFloat64(v[float64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapFloat64BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapFloat64BoolV(rv2i(rv).(map[float64]bool), e)
-}
-func (_ fastpathT) EncMapFloat64BoolV(v map[float64]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]float64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = float64(k)
-			i++
-		}
-		sort.Sort(floatSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(float64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[float64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeFloat64(float64(k2))
-				ee.EncodeBool(v[float64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeFloat64(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeFloat64(k2)
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintIntfV(rv2i(rv).(map[uint]interface{}), e)
-}
-func (_ fastpathT) EncMapUintIntfV(v map[uint]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				e.encode(v[uint(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintStringV(rv2i(rv).(map[uint]string), e)
-}
-func (_ fastpathT) EncMapUintStringV(v map[uint]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uint(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeString(cUTF8, v[uint(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUintV(rv2i(rv).(map[uint]uint), e)
-}
-func (_ fastpathT) EncMapUintUintV(v map[uint]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeUint(uint64(v[uint(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUint8V(rv2i(rv).(map[uint]uint8), e)
-}
-func (_ fastpathT) EncMapUintUint8V(v map[uint]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeUint(uint64(v[uint(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUint16V(rv2i(rv).(map[uint]uint16), e)
-}
-func (_ fastpathT) EncMapUintUint16V(v map[uint]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeUint(uint64(v[uint(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUint32V(rv2i(rv).(map[uint]uint32), e)
-}
-func (_ fastpathT) EncMapUintUint32V(v map[uint]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeUint(uint64(v[uint(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUint64V(rv2i(rv).(map[uint]uint64), e)
-}
-func (_ fastpathT) EncMapUintUint64V(v map[uint]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeUint(uint64(v[uint(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintUintptrV(rv2i(rv).(map[uint]uintptr), e)
-}
-func (_ fastpathT) EncMapUintUintptrV(v map[uint]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				e.encode(v[uint(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintIntV(rv2i(rv).(map[uint]int), e)
-}
-func (_ fastpathT) EncMapUintIntV(v map[uint]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeInt(int64(v[uint(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintInt8V(rv2i(rv).(map[uint]int8), e)
-}
-func (_ fastpathT) EncMapUintInt8V(v map[uint]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeInt(int64(v[uint(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintInt16V(rv2i(rv).(map[uint]int16), e)
-}
-func (_ fastpathT) EncMapUintInt16V(v map[uint]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeInt(int64(v[uint(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintInt32V(rv2i(rv).(map[uint]int32), e)
-}
-func (_ fastpathT) EncMapUintInt32V(v map[uint]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeInt(int64(v[uint(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintInt64V(rv2i(rv).(map[uint]int64), e)
-}
-func (_ fastpathT) EncMapUintInt64V(v map[uint]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeInt(int64(v[uint(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintFloat32V(rv2i(rv).(map[uint]float32), e)
-}
-func (_ fastpathT) EncMapUintFloat32V(v map[uint]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uint(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeFloat32(v[uint(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintFloat64V(rv2i(rv).(map[uint]float64), e)
-}
-func (_ fastpathT) EncMapUintFloat64V(v map[uint]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uint(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeFloat64(v[uint(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintBoolV(rv2i(rv).(map[uint]bool), e)
-}
-func (_ fastpathT) EncMapUintBoolV(v map[uint]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uint(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint(k2)))
-				ee.EncodeBool(v[uint(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8IntfV(rv2i(rv).(map[uint8]interface{}), e)
-}
-func (_ fastpathT) EncMapUint8IntfV(v map[uint8]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				e.encode(v[uint8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8StringV(rv2i(rv).(map[uint8]string), e)
-}
-func (_ fastpathT) EncMapUint8StringV(v map[uint8]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uint8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeString(cUTF8, v[uint8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8UintV(rv2i(rv).(map[uint8]uint), e)
-}
-func (_ fastpathT) EncMapUint8UintV(v map[uint8]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeUint(uint64(v[uint8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Uint8V(rv2i(rv).(map[uint8]uint8), e)
-}
-func (_ fastpathT) EncMapUint8Uint8V(v map[uint8]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeUint(uint64(v[uint8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Uint16V(rv2i(rv).(map[uint8]uint16), e)
-}
-func (_ fastpathT) EncMapUint8Uint16V(v map[uint8]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeUint(uint64(v[uint8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Uint32V(rv2i(rv).(map[uint8]uint32), e)
-}
-func (_ fastpathT) EncMapUint8Uint32V(v map[uint8]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeUint(uint64(v[uint8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Uint64V(rv2i(rv).(map[uint8]uint64), e)
-}
-func (_ fastpathT) EncMapUint8Uint64V(v map[uint8]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeUint(uint64(v[uint8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8UintptrV(rv2i(rv).(map[uint8]uintptr), e)
-}
-func (_ fastpathT) EncMapUint8UintptrV(v map[uint8]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				e.encode(v[uint8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8IntV(rv2i(rv).(map[uint8]int), e)
-}
-func (_ fastpathT) EncMapUint8IntV(v map[uint8]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeInt(int64(v[uint8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Int8V(rv2i(rv).(map[uint8]int8), e)
-}
-func (_ fastpathT) EncMapUint8Int8V(v map[uint8]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeInt(int64(v[uint8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Int16V(rv2i(rv).(map[uint8]int16), e)
-}
-func (_ fastpathT) EncMapUint8Int16V(v map[uint8]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeInt(int64(v[uint8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Int32V(rv2i(rv).(map[uint8]int32), e)
-}
-func (_ fastpathT) EncMapUint8Int32V(v map[uint8]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeInt(int64(v[uint8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Int64V(rv2i(rv).(map[uint8]int64), e)
-}
-func (_ fastpathT) EncMapUint8Int64V(v map[uint8]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeInt(int64(v[uint8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Float32V(rv2i(rv).(map[uint8]float32), e)
-}
-func (_ fastpathT) EncMapUint8Float32V(v map[uint8]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uint8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeFloat32(v[uint8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8Float64V(rv2i(rv).(map[uint8]float64), e)
-}
-func (_ fastpathT) EncMapUint8Float64V(v map[uint8]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uint8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeFloat64(v[uint8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint8BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint8BoolV(rv2i(rv).(map[uint8]bool), e)
-}
-func (_ fastpathT) EncMapUint8BoolV(v map[uint8]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uint8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint8(k2)))
-				ee.EncodeBool(v[uint8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16IntfV(rv2i(rv).(map[uint16]interface{}), e)
-}
-func (_ fastpathT) EncMapUint16IntfV(v map[uint16]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				e.encode(v[uint16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16StringV(rv2i(rv).(map[uint16]string), e)
-}
-func (_ fastpathT) EncMapUint16StringV(v map[uint16]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uint16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeString(cUTF8, v[uint16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16UintV(rv2i(rv).(map[uint16]uint), e)
-}
-func (_ fastpathT) EncMapUint16UintV(v map[uint16]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeUint(uint64(v[uint16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Uint8V(rv2i(rv).(map[uint16]uint8), e)
-}
-func (_ fastpathT) EncMapUint16Uint8V(v map[uint16]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeUint(uint64(v[uint16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Uint16V(rv2i(rv).(map[uint16]uint16), e)
-}
-func (_ fastpathT) EncMapUint16Uint16V(v map[uint16]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeUint(uint64(v[uint16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Uint32V(rv2i(rv).(map[uint16]uint32), e)
-}
-func (_ fastpathT) EncMapUint16Uint32V(v map[uint16]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeUint(uint64(v[uint16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Uint64V(rv2i(rv).(map[uint16]uint64), e)
-}
-func (_ fastpathT) EncMapUint16Uint64V(v map[uint16]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeUint(uint64(v[uint16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16UintptrV(rv2i(rv).(map[uint16]uintptr), e)
-}
-func (_ fastpathT) EncMapUint16UintptrV(v map[uint16]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				e.encode(v[uint16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16IntV(rv2i(rv).(map[uint16]int), e)
-}
-func (_ fastpathT) EncMapUint16IntV(v map[uint16]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeInt(int64(v[uint16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Int8V(rv2i(rv).(map[uint16]int8), e)
-}
-func (_ fastpathT) EncMapUint16Int8V(v map[uint16]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeInt(int64(v[uint16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Int16V(rv2i(rv).(map[uint16]int16), e)
-}
-func (_ fastpathT) EncMapUint16Int16V(v map[uint16]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeInt(int64(v[uint16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Int32V(rv2i(rv).(map[uint16]int32), e)
-}
-func (_ fastpathT) EncMapUint16Int32V(v map[uint16]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeInt(int64(v[uint16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Int64V(rv2i(rv).(map[uint16]int64), e)
-}
-func (_ fastpathT) EncMapUint16Int64V(v map[uint16]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeInt(int64(v[uint16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Float32V(rv2i(rv).(map[uint16]float32), e)
-}
-func (_ fastpathT) EncMapUint16Float32V(v map[uint16]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uint16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeFloat32(v[uint16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16Float64V(rv2i(rv).(map[uint16]float64), e)
-}
-func (_ fastpathT) EncMapUint16Float64V(v map[uint16]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uint16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeFloat64(v[uint16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint16BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint16BoolV(rv2i(rv).(map[uint16]bool), e)
-}
-func (_ fastpathT) EncMapUint16BoolV(v map[uint16]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uint16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint16(k2)))
-				ee.EncodeBool(v[uint16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32IntfV(rv2i(rv).(map[uint32]interface{}), e)
-}
-func (_ fastpathT) EncMapUint32IntfV(v map[uint32]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				e.encode(v[uint32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32StringV(rv2i(rv).(map[uint32]string), e)
-}
-func (_ fastpathT) EncMapUint32StringV(v map[uint32]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uint32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeString(cUTF8, v[uint32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32UintV(rv2i(rv).(map[uint32]uint), e)
-}
-func (_ fastpathT) EncMapUint32UintV(v map[uint32]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeUint(uint64(v[uint32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Uint8V(rv2i(rv).(map[uint32]uint8), e)
-}
-func (_ fastpathT) EncMapUint32Uint8V(v map[uint32]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeUint(uint64(v[uint32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Uint16V(rv2i(rv).(map[uint32]uint16), e)
-}
-func (_ fastpathT) EncMapUint32Uint16V(v map[uint32]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeUint(uint64(v[uint32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Uint32V(rv2i(rv).(map[uint32]uint32), e)
-}
-func (_ fastpathT) EncMapUint32Uint32V(v map[uint32]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeUint(uint64(v[uint32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Uint64V(rv2i(rv).(map[uint32]uint64), e)
-}
-func (_ fastpathT) EncMapUint32Uint64V(v map[uint32]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeUint(uint64(v[uint32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32UintptrV(rv2i(rv).(map[uint32]uintptr), e)
-}
-func (_ fastpathT) EncMapUint32UintptrV(v map[uint32]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				e.encode(v[uint32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32IntV(rv2i(rv).(map[uint32]int), e)
-}
-func (_ fastpathT) EncMapUint32IntV(v map[uint32]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeInt(int64(v[uint32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Int8V(rv2i(rv).(map[uint32]int8), e)
-}
-func (_ fastpathT) EncMapUint32Int8V(v map[uint32]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeInt(int64(v[uint32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Int16V(rv2i(rv).(map[uint32]int16), e)
-}
-func (_ fastpathT) EncMapUint32Int16V(v map[uint32]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeInt(int64(v[uint32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Int32V(rv2i(rv).(map[uint32]int32), e)
-}
-func (_ fastpathT) EncMapUint32Int32V(v map[uint32]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeInt(int64(v[uint32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Int64V(rv2i(rv).(map[uint32]int64), e)
-}
-func (_ fastpathT) EncMapUint32Int64V(v map[uint32]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeInt(int64(v[uint32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Float32V(rv2i(rv).(map[uint32]float32), e)
-}
-func (_ fastpathT) EncMapUint32Float32V(v map[uint32]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uint32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeFloat32(v[uint32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32Float64V(rv2i(rv).(map[uint32]float64), e)
-}
-func (_ fastpathT) EncMapUint32Float64V(v map[uint32]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uint32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeFloat64(v[uint32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint32BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint32BoolV(rv2i(rv).(map[uint32]bool), e)
-}
-func (_ fastpathT) EncMapUint32BoolV(v map[uint32]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uint32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint32(k2)))
-				ee.EncodeBool(v[uint32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64IntfV(rv2i(rv).(map[uint64]interface{}), e)
-}
-func (_ fastpathT) EncMapUint64IntfV(v map[uint64]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				e.encode(v[uint64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64StringV(rv2i(rv).(map[uint64]string), e)
-}
-func (_ fastpathT) EncMapUint64StringV(v map[uint64]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uint64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeString(cUTF8, v[uint64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64UintV(rv2i(rv).(map[uint64]uint), e)
-}
-func (_ fastpathT) EncMapUint64UintV(v map[uint64]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeUint(uint64(v[uint64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Uint8V(rv2i(rv).(map[uint64]uint8), e)
-}
-func (_ fastpathT) EncMapUint64Uint8V(v map[uint64]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeUint(uint64(v[uint64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Uint16V(rv2i(rv).(map[uint64]uint16), e)
-}
-func (_ fastpathT) EncMapUint64Uint16V(v map[uint64]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeUint(uint64(v[uint64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Uint32V(rv2i(rv).(map[uint64]uint32), e)
-}
-func (_ fastpathT) EncMapUint64Uint32V(v map[uint64]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeUint(uint64(v[uint64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Uint64V(rv2i(rv).(map[uint64]uint64), e)
-}
-func (_ fastpathT) EncMapUint64Uint64V(v map[uint64]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uint64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeUint(uint64(v[uint64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64UintptrV(rv2i(rv).(map[uint64]uintptr), e)
-}
-func (_ fastpathT) EncMapUint64UintptrV(v map[uint64]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[uint64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				e.encode(v[uint64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64IntV(rv2i(rv).(map[uint64]int), e)
-}
-func (_ fastpathT) EncMapUint64IntV(v map[uint64]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeInt(int64(v[uint64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Int8V(rv2i(rv).(map[uint64]int8), e)
-}
-func (_ fastpathT) EncMapUint64Int8V(v map[uint64]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeInt(int64(v[uint64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Int16V(rv2i(rv).(map[uint64]int16), e)
-}
-func (_ fastpathT) EncMapUint64Int16V(v map[uint64]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeInt(int64(v[uint64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Int32V(rv2i(rv).(map[uint64]int32), e)
-}
-func (_ fastpathT) EncMapUint64Int32V(v map[uint64]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeInt(int64(v[uint64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Int64V(rv2i(rv).(map[uint64]int64), e)
-}
-func (_ fastpathT) EncMapUint64Int64V(v map[uint64]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uint64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeInt(int64(v[uint64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Float32V(rv2i(rv).(map[uint64]float32), e)
-}
-func (_ fastpathT) EncMapUint64Float32V(v map[uint64]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uint64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeFloat32(v[uint64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64Float64V(rv2i(rv).(map[uint64]float64), e)
-}
-func (_ fastpathT) EncMapUint64Float64V(v map[uint64]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uint64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeFloat64(v[uint64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUint64BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUint64BoolV(rv2i(rv).(map[uint64]bool), e)
-}
-func (_ fastpathT) EncMapUint64BoolV(v map[uint64]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uint64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeUint(uint64(uint64(k2)))
-				ee.EncodeBool(v[uint64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeUint(uint64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeUint(uint64(k2))
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrIntfV(rv2i(rv).(map[uintptr]interface{}), e)
-}
-func (_ fastpathT) EncMapUintptrIntfV(v map[uintptr]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[uintptr(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				e.encode(v[uintptr(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrStringV(rv2i(rv).(map[uintptr]string), e)
-}
-func (_ fastpathT) EncMapUintptrStringV(v map[uintptr]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[uintptr(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeString(cUTF8, v[uintptr(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUintV(rv2i(rv).(map[uintptr]uint), e)
-}
-func (_ fastpathT) EncMapUintptrUintV(v map[uintptr]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUint8V(rv2i(rv).(map[uintptr]uint8), e)
-}
-func (_ fastpathT) EncMapUintptrUint8V(v map[uintptr]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUint16V(rv2i(rv).(map[uintptr]uint16), e)
-}
-func (_ fastpathT) EncMapUintptrUint16V(v map[uintptr]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUint32V(rv2i(rv).(map[uintptr]uint32), e)
-}
-func (_ fastpathT) EncMapUintptrUint32V(v map[uintptr]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUint64V(rv2i(rv).(map[uintptr]uint64), e)
-}
-func (_ fastpathT) EncMapUintptrUint64V(v map[uintptr]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeUint(uint64(v[uintptr(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrUintptrV(rv2i(rv).(map[uintptr]uintptr), e)
-}
-func (_ fastpathT) EncMapUintptrUintptrV(v map[uintptr]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[uintptr(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				e.encode(v[uintptr(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrIntV(rv2i(rv).(map[uintptr]int), e)
-}
-func (_ fastpathT) EncMapUintptrIntV(v map[uintptr]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uintptr(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeInt(int64(v[uintptr(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrInt8V(rv2i(rv).(map[uintptr]int8), e)
-}
-func (_ fastpathT) EncMapUintptrInt8V(v map[uintptr]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uintptr(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeInt(int64(v[uintptr(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrInt16V(rv2i(rv).(map[uintptr]int16), e)
-}
-func (_ fastpathT) EncMapUintptrInt16V(v map[uintptr]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uintptr(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeInt(int64(v[uintptr(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrInt32V(rv2i(rv).(map[uintptr]int32), e)
-}
-func (_ fastpathT) EncMapUintptrInt32V(v map[uintptr]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uintptr(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeInt(int64(v[uintptr(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrInt64V(rv2i(rv).(map[uintptr]int64), e)
-}
-func (_ fastpathT) EncMapUintptrInt64V(v map[uintptr]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[uintptr(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeInt(int64(v[uintptr(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrFloat32V(rv2i(rv).(map[uintptr]float32), e)
-}
-func (_ fastpathT) EncMapUintptrFloat32V(v map[uintptr]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[uintptr(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeFloat32(v[uintptr(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrFloat64V(rv2i(rv).(map[uintptr]float64), e)
-}
-func (_ fastpathT) EncMapUintptrFloat64V(v map[uintptr]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[uintptr(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeFloat64(v[uintptr(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapUintptrBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapUintptrBoolV(rv2i(rv).(map[uintptr]bool), e)
-}
-func (_ fastpathT) EncMapUintptrBoolV(v map[uintptr]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]uint64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = uint64(k)
-			i++
-		}
-		sort.Sort(uintSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				e.encode(uintptr(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[uintptr(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				e.encode(uintptr(k2))
-				ee.EncodeBool(v[uintptr(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				e.encode(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				e.encode(k2)
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntIntfV(rv2i(rv).(map[int]interface{}), e)
-}
-func (_ fastpathT) EncMapIntIntfV(v map[int]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				e.encode(v[int(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntStringV(rv2i(rv).(map[int]string), e)
-}
-func (_ fastpathT) EncMapIntStringV(v map[int]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[int(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeString(cUTF8, v[int(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUintV(rv2i(rv).(map[int]uint), e)
-}
-func (_ fastpathT) EncMapIntUintV(v map[int]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeUint(uint64(v[int(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUint8V(rv2i(rv).(map[int]uint8), e)
-}
-func (_ fastpathT) EncMapIntUint8V(v map[int]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeUint(uint64(v[int(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUint16V(rv2i(rv).(map[int]uint16), e)
-}
-func (_ fastpathT) EncMapIntUint16V(v map[int]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeUint(uint64(v[int(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUint32V(rv2i(rv).(map[int]uint32), e)
-}
-func (_ fastpathT) EncMapIntUint32V(v map[int]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeUint(uint64(v[int(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUint64V(rv2i(rv).(map[int]uint64), e)
-}
-func (_ fastpathT) EncMapIntUint64V(v map[int]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeUint(uint64(v[int(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntUintptrV(rv2i(rv).(map[int]uintptr), e)
-}
-func (_ fastpathT) EncMapIntUintptrV(v map[int]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				e.encode(v[int(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntIntV(rv2i(rv).(map[int]int), e)
-}
-func (_ fastpathT) EncMapIntIntV(v map[int]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeInt(int64(v[int(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntInt8V(rv2i(rv).(map[int]int8), e)
-}
-func (_ fastpathT) EncMapIntInt8V(v map[int]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeInt(int64(v[int(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntInt16V(rv2i(rv).(map[int]int16), e)
-}
-func (_ fastpathT) EncMapIntInt16V(v map[int]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeInt(int64(v[int(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntInt32V(rv2i(rv).(map[int]int32), e)
-}
-func (_ fastpathT) EncMapIntInt32V(v map[int]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeInt(int64(v[int(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntInt64V(rv2i(rv).(map[int]int64), e)
-}
-func (_ fastpathT) EncMapIntInt64V(v map[int]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeInt(int64(v[int(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntFloat32V(rv2i(rv).(map[int]float32), e)
-}
-func (_ fastpathT) EncMapIntFloat32V(v map[int]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[int(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeFloat32(v[int(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntFloat64V(rv2i(rv).(map[int]float64), e)
-}
-func (_ fastpathT) EncMapIntFloat64V(v map[int]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[int(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeFloat64(v[int(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapIntBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapIntBoolV(rv2i(rv).(map[int]bool), e)
-}
-func (_ fastpathT) EncMapIntBoolV(v map[int]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[int(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int(k2)))
-				ee.EncodeBool(v[int(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8IntfV(rv2i(rv).(map[int8]interface{}), e)
-}
-func (_ fastpathT) EncMapInt8IntfV(v map[int8]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				e.encode(v[int8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8StringV(rv2i(rv).(map[int8]string), e)
-}
-func (_ fastpathT) EncMapInt8StringV(v map[int8]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[int8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeString(cUTF8, v[int8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8UintV(rv2i(rv).(map[int8]uint), e)
-}
-func (_ fastpathT) EncMapInt8UintV(v map[int8]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeUint(uint64(v[int8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Uint8V(rv2i(rv).(map[int8]uint8), e)
-}
-func (_ fastpathT) EncMapInt8Uint8V(v map[int8]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeUint(uint64(v[int8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Uint16V(rv2i(rv).(map[int8]uint16), e)
-}
-func (_ fastpathT) EncMapInt8Uint16V(v map[int8]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeUint(uint64(v[int8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Uint32V(rv2i(rv).(map[int8]uint32), e)
-}
-func (_ fastpathT) EncMapInt8Uint32V(v map[int8]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeUint(uint64(v[int8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Uint64V(rv2i(rv).(map[int8]uint64), e)
-}
-func (_ fastpathT) EncMapInt8Uint64V(v map[int8]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeUint(uint64(v[int8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8UintptrV(rv2i(rv).(map[int8]uintptr), e)
-}
-func (_ fastpathT) EncMapInt8UintptrV(v map[int8]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				e.encode(v[int8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8IntV(rv2i(rv).(map[int8]int), e)
-}
-func (_ fastpathT) EncMapInt8IntV(v map[int8]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeInt(int64(v[int8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Int8V(rv2i(rv).(map[int8]int8), e)
-}
-func (_ fastpathT) EncMapInt8Int8V(v map[int8]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeInt(int64(v[int8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Int16V(rv2i(rv).(map[int8]int16), e)
-}
-func (_ fastpathT) EncMapInt8Int16V(v map[int8]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeInt(int64(v[int8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Int32V(rv2i(rv).(map[int8]int32), e)
-}
-func (_ fastpathT) EncMapInt8Int32V(v map[int8]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeInt(int64(v[int8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Int64V(rv2i(rv).(map[int8]int64), e)
-}
-func (_ fastpathT) EncMapInt8Int64V(v map[int8]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int8(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeInt(int64(v[int8(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Float32V(rv2i(rv).(map[int8]float32), e)
-}
-func (_ fastpathT) EncMapInt8Float32V(v map[int8]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[int8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeFloat32(v[int8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8Float64V(rv2i(rv).(map[int8]float64), e)
-}
-func (_ fastpathT) EncMapInt8Float64V(v map[int8]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[int8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeFloat64(v[int8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt8BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt8BoolV(rv2i(rv).(map[int8]bool), e)
-}
-func (_ fastpathT) EncMapInt8BoolV(v map[int8]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int8(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[int8(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int8(k2)))
-				ee.EncodeBool(v[int8(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16IntfV(rv2i(rv).(map[int16]interface{}), e)
-}
-func (_ fastpathT) EncMapInt16IntfV(v map[int16]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				e.encode(v[int16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16StringV(rv2i(rv).(map[int16]string), e)
-}
-func (_ fastpathT) EncMapInt16StringV(v map[int16]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[int16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeString(cUTF8, v[int16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16UintV(rv2i(rv).(map[int16]uint), e)
-}
-func (_ fastpathT) EncMapInt16UintV(v map[int16]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeUint(uint64(v[int16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Uint8V(rv2i(rv).(map[int16]uint8), e)
-}
-func (_ fastpathT) EncMapInt16Uint8V(v map[int16]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeUint(uint64(v[int16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Uint16V(rv2i(rv).(map[int16]uint16), e)
-}
-func (_ fastpathT) EncMapInt16Uint16V(v map[int16]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeUint(uint64(v[int16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Uint32V(rv2i(rv).(map[int16]uint32), e)
-}
-func (_ fastpathT) EncMapInt16Uint32V(v map[int16]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeUint(uint64(v[int16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Uint64V(rv2i(rv).(map[int16]uint64), e)
-}
-func (_ fastpathT) EncMapInt16Uint64V(v map[int16]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeUint(uint64(v[int16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16UintptrV(rv2i(rv).(map[int16]uintptr), e)
-}
-func (_ fastpathT) EncMapInt16UintptrV(v map[int16]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				e.encode(v[int16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16IntV(rv2i(rv).(map[int16]int), e)
-}
-func (_ fastpathT) EncMapInt16IntV(v map[int16]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeInt(int64(v[int16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Int8V(rv2i(rv).(map[int16]int8), e)
-}
-func (_ fastpathT) EncMapInt16Int8V(v map[int16]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeInt(int64(v[int16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Int16V(rv2i(rv).(map[int16]int16), e)
-}
-func (_ fastpathT) EncMapInt16Int16V(v map[int16]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeInt(int64(v[int16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Int32V(rv2i(rv).(map[int16]int32), e)
-}
-func (_ fastpathT) EncMapInt16Int32V(v map[int16]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeInt(int64(v[int16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Int64V(rv2i(rv).(map[int16]int64), e)
-}
-func (_ fastpathT) EncMapInt16Int64V(v map[int16]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int16(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeInt(int64(v[int16(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Float32V(rv2i(rv).(map[int16]float32), e)
-}
-func (_ fastpathT) EncMapInt16Float32V(v map[int16]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[int16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeFloat32(v[int16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16Float64V(rv2i(rv).(map[int16]float64), e)
-}
-func (_ fastpathT) EncMapInt16Float64V(v map[int16]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[int16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeFloat64(v[int16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt16BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt16BoolV(rv2i(rv).(map[int16]bool), e)
-}
-func (_ fastpathT) EncMapInt16BoolV(v map[int16]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int16(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[int16(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int16(k2)))
-				ee.EncodeBool(v[int16(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32IntfV(rv2i(rv).(map[int32]interface{}), e)
-}
-func (_ fastpathT) EncMapInt32IntfV(v map[int32]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				e.encode(v[int32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32StringV(rv2i(rv).(map[int32]string), e)
-}
-func (_ fastpathT) EncMapInt32StringV(v map[int32]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[int32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeString(cUTF8, v[int32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32UintV(rv2i(rv).(map[int32]uint), e)
-}
-func (_ fastpathT) EncMapInt32UintV(v map[int32]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeUint(uint64(v[int32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Uint8V(rv2i(rv).(map[int32]uint8), e)
-}
-func (_ fastpathT) EncMapInt32Uint8V(v map[int32]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeUint(uint64(v[int32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Uint16V(rv2i(rv).(map[int32]uint16), e)
-}
-func (_ fastpathT) EncMapInt32Uint16V(v map[int32]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeUint(uint64(v[int32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Uint32V(rv2i(rv).(map[int32]uint32), e)
-}
-func (_ fastpathT) EncMapInt32Uint32V(v map[int32]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeUint(uint64(v[int32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Uint64V(rv2i(rv).(map[int32]uint64), e)
-}
-func (_ fastpathT) EncMapInt32Uint64V(v map[int32]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeUint(uint64(v[int32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32UintptrV(rv2i(rv).(map[int32]uintptr), e)
-}
-func (_ fastpathT) EncMapInt32UintptrV(v map[int32]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				e.encode(v[int32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32IntV(rv2i(rv).(map[int32]int), e)
-}
-func (_ fastpathT) EncMapInt32IntV(v map[int32]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeInt(int64(v[int32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Int8V(rv2i(rv).(map[int32]int8), e)
-}
-func (_ fastpathT) EncMapInt32Int8V(v map[int32]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeInt(int64(v[int32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Int16V(rv2i(rv).(map[int32]int16), e)
-}
-func (_ fastpathT) EncMapInt32Int16V(v map[int32]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeInt(int64(v[int32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Int32V(rv2i(rv).(map[int32]int32), e)
-}
-func (_ fastpathT) EncMapInt32Int32V(v map[int32]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeInt(int64(v[int32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Int64V(rv2i(rv).(map[int32]int64), e)
-}
-func (_ fastpathT) EncMapInt32Int64V(v map[int32]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int32(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeInt(int64(v[int32(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Float32V(rv2i(rv).(map[int32]float32), e)
-}
-func (_ fastpathT) EncMapInt32Float32V(v map[int32]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[int32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeFloat32(v[int32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32Float64V(rv2i(rv).(map[int32]float64), e)
-}
-func (_ fastpathT) EncMapInt32Float64V(v map[int32]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[int32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeFloat64(v[int32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt32BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt32BoolV(rv2i(rv).(map[int32]bool), e)
-}
-func (_ fastpathT) EncMapInt32BoolV(v map[int32]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int32(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[int32(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int32(k2)))
-				ee.EncodeBool(v[int32(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64IntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64IntfV(rv2i(rv).(map[int64]interface{}), e)
-}
-func (_ fastpathT) EncMapInt64IntfV(v map[int64]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				e.encode(v[int64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64StringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64StringV(rv2i(rv).(map[int64]string), e)
-}
-func (_ fastpathT) EncMapInt64StringV(v map[int64]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[int64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeString(cUTF8, v[int64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64UintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64UintV(rv2i(rv).(map[int64]uint), e)
-}
-func (_ fastpathT) EncMapInt64UintV(v map[int64]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeUint(uint64(v[int64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Uint8V(rv2i(rv).(map[int64]uint8), e)
-}
-func (_ fastpathT) EncMapInt64Uint8V(v map[int64]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeUint(uint64(v[int64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Uint16V(rv2i(rv).(map[int64]uint16), e)
-}
-func (_ fastpathT) EncMapInt64Uint16V(v map[int64]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeUint(uint64(v[int64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Uint32V(rv2i(rv).(map[int64]uint32), e)
-}
-func (_ fastpathT) EncMapInt64Uint32V(v map[int64]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeUint(uint64(v[int64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Uint64V(rv2i(rv).(map[int64]uint64), e)
-}
-func (_ fastpathT) EncMapInt64Uint64V(v map[int64]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[int64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeUint(uint64(v[int64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64UintptrV(rv2i(rv).(map[int64]uintptr), e)
-}
-func (_ fastpathT) EncMapInt64UintptrV(v map[int64]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				e.encode(v[int64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				e.encode(v[int64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64IntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64IntV(rv2i(rv).(map[int64]int), e)
-}
-func (_ fastpathT) EncMapInt64IntV(v map[int64]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeInt(int64(v[int64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64Int8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Int8V(rv2i(rv).(map[int64]int8), e)
-}
-func (_ fastpathT) EncMapInt64Int8V(v map[int64]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeInt(int64(v[int64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64Int16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Int16V(rv2i(rv).(map[int64]int16), e)
-}
-func (_ fastpathT) EncMapInt64Int16V(v map[int64]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeInt(int64(v[int64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64Int32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Int32V(rv2i(rv).(map[int64]int32), e)
-}
-func (_ fastpathT) EncMapInt64Int32V(v map[int64]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeInt(int64(v[int64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64Int64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Int64V(rv2i(rv).(map[int64]int64), e)
-}
-func (_ fastpathT) EncMapInt64Int64V(v map[int64]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[int64(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeInt(int64(v[int64(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64Float32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Float32V(rv2i(rv).(map[int64]float32), e)
-}
-func (_ fastpathT) EncMapInt64Float32V(v map[int64]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[int64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeFloat32(v[int64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64Float64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64Float64V(rv2i(rv).(map[int64]float64), e)
-}
-func (_ fastpathT) EncMapInt64Float64V(v map[int64]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[int64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeFloat64(v[int64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapInt64BoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapInt64BoolV(rv2i(rv).(map[int64]bool), e)
-}
-func (_ fastpathT) EncMapInt64BoolV(v map[int64]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]int64, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = int64(k)
-			i++
-		}
-		sort.Sort(intSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(int64(k2)))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[int64(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeInt(int64(int64(k2)))
-				ee.EncodeBool(v[int64(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeInt(int64(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeInt(int64(k2))
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolIntfR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolIntfV(rv2i(rv).(map[bool]interface{}), e)
-}
-func (_ fastpathT) EncMapBoolIntfV(v map[bool]interface{}, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[bool(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				e.encode(v[bool(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolStringR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolStringV(rv2i(rv).(map[bool]string), e)
-}
-func (_ fastpathT) EncMapBoolStringV(v map[bool]string, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v[bool(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeString(cUTF8, v[bool(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeString(cUTF8, v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeString(cUTF8, v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolUintR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUintV(rv2i(rv).(map[bool]uint), e)
-}
-func (_ fastpathT) EncMapBoolUintV(v map[bool]uint, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[bool(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeUint(uint64(v[bool(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolUint8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUint8V(rv2i(rv).(map[bool]uint8), e)
-}
-func (_ fastpathT) EncMapBoolUint8V(v map[bool]uint8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[bool(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeUint(uint64(v[bool(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolUint16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUint16V(rv2i(rv).(map[bool]uint16), e)
-}
-func (_ fastpathT) EncMapBoolUint16V(v map[bool]uint16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[bool(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeUint(uint64(v[bool(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolUint32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUint32V(rv2i(rv).(map[bool]uint32), e)
-}
-func (_ fastpathT) EncMapBoolUint32V(v map[bool]uint32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[bool(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeUint(uint64(v[bool(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolUint64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUint64V(rv2i(rv).(map[bool]uint64), e)
-}
-func (_ fastpathT) EncMapBoolUint64V(v map[bool]uint64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v[bool(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeUint(uint64(v[bool(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeUint(uint64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeUint(uint64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolUintptrR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolUintptrV(rv2i(rv).(map[bool]uintptr), e)
-}
-func (_ fastpathT) EncMapBoolUintptrV(v map[bool]uintptr, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				e.encode(v[bool(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				e.encode(v[bool(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				e.encode(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				e.encode(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolIntR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolIntV(rv2i(rv).(map[bool]int), e)
-}
-func (_ fastpathT) EncMapBoolIntV(v map[bool]int, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[bool(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeInt(int64(v[bool(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolInt8R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolInt8V(rv2i(rv).(map[bool]int8), e)
-}
-func (_ fastpathT) EncMapBoolInt8V(v map[bool]int8, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[bool(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeInt(int64(v[bool(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolInt16R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolInt16V(rv2i(rv).(map[bool]int16), e)
-}
-func (_ fastpathT) EncMapBoolInt16V(v map[bool]int16, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[bool(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeInt(int64(v[bool(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolInt32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolInt32V(rv2i(rv).(map[bool]int32), e)
-}
-func (_ fastpathT) EncMapBoolInt32V(v map[bool]int32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[bool(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeInt(int64(v[bool(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolInt64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolInt64V(rv2i(rv).(map[bool]int64), e)
-}
-func (_ fastpathT) EncMapBoolInt64V(v map[bool]int64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v[bool(k2)]))
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeInt(int64(v[bool(k2)]))
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeInt(int64(v2))
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeInt(int64(v2))
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolFloat32R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolFloat32V(rv2i(rv).(map[bool]float32), e)
-}
-func (_ fastpathT) EncMapBoolFloat32V(v map[bool]float32, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v[bool(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeFloat32(v[bool(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat32(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeFloat32(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolFloat64R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolFloat64V(rv2i(rv).(map[bool]float64), e)
-}
-func (_ fastpathT) EncMapBoolFloat64V(v map[bool]float64, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v[bool(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeFloat64(v[bool(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeFloat64(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeFloat64(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-func (e *Encoder) fastpathEncMapBoolBoolR(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.EncMapBoolBoolV(rv2i(rv).(map[bool]bool), e)
-}
-func (_ fastpathT) EncMapBoolBoolV(v map[bool]bool, e *Encoder) {
-	if v == nil {
-		e.e.EncodeNil()
-		return
-	}
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		v2 := make([]bool, len(v))
-		var i int
-		for k, _ := range v {
-			v2[i] = bool(k)
-			i++
-		}
-		sort.Sort(boolSlice(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(bool(k2))
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v[bool(k2)])
-			}
-		} else {
-			for _, k2 := range v2 {
-				ee.EncodeBool(bool(k2))
-				ee.EncodeBool(v[bool(k2)])
-			}
-		}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				ee.EncodeBool(k2)
-				ee.WriteMapElemValue()
-				ee.EncodeBool(v2)
-			}
-		} else {
-			for k2, v2 := range v {
-				ee.EncodeBool(k2)
-				ee.EncodeBool(v2)
-			}
-		}
-	}
-	ee.WriteMapEnd()
-}
-
-// -- decode
-
-// -- -- fast path type switch
-func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
-	var changed bool
-	switch v := iv.(type) {
-
-	case []interface{}:
-		var v2 []interface{}
-		v2, changed = fastpathTV.DecSliceIntfV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]interface{}:
-		var v2 []interface{}
-		v2, changed = fastpathTV.DecSliceIntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []string:
-		var v2 []string
-		v2, changed = fastpathTV.DecSliceStringV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]string:
-		var v2 []string
-		v2, changed = fastpathTV.DecSliceStringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []float32:
-		var v2 []float32
-		v2, changed = fastpathTV.DecSliceFloat32V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]float32:
-		var v2 []float32
-		v2, changed = fastpathTV.DecSliceFloat32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []float64:
-		var v2 []float64
-		v2, changed = fastpathTV.DecSliceFloat64V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]float64:
-		var v2 []float64
-		v2, changed = fastpathTV.DecSliceFloat64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []uint:
-		var v2 []uint
-		v2, changed = fastpathTV.DecSliceUintV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]uint:
-		var v2 []uint
-		v2, changed = fastpathTV.DecSliceUintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []uint16:
-		var v2 []uint16
-		v2, changed = fastpathTV.DecSliceUint16V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]uint16:
-		var v2 []uint16
-		v2, changed = fastpathTV.DecSliceUint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []uint32:
-		var v2 []uint32
-		v2, changed = fastpathTV.DecSliceUint32V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]uint32:
-		var v2 []uint32
-		v2, changed = fastpathTV.DecSliceUint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []uint64:
-		var v2 []uint64
-		v2, changed = fastpathTV.DecSliceUint64V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]uint64:
-		var v2 []uint64
-		v2, changed = fastpathTV.DecSliceUint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []uintptr:
-		var v2 []uintptr
-		v2, changed = fastpathTV.DecSliceUintptrV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]uintptr:
-		var v2 []uintptr
-		v2, changed = fastpathTV.DecSliceUintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []int:
-		var v2 []int
-		v2, changed = fastpathTV.DecSliceIntV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]int:
-		var v2 []int
-		v2, changed = fastpathTV.DecSliceIntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []int8:
-		var v2 []int8
-		v2, changed = fastpathTV.DecSliceInt8V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]int8:
-		var v2 []int8
-		v2, changed = fastpathTV.DecSliceInt8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []int16:
-		var v2 []int16
-		v2, changed = fastpathTV.DecSliceInt16V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]int16:
-		var v2 []int16
-		v2, changed = fastpathTV.DecSliceInt16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []int32:
-		var v2 []int32
-		v2, changed = fastpathTV.DecSliceInt32V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]int32:
-		var v2 []int32
-		v2, changed = fastpathTV.DecSliceInt32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []int64:
-		var v2 []int64
-		v2, changed = fastpathTV.DecSliceInt64V(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]int64:
-		var v2 []int64
-		v2, changed = fastpathTV.DecSliceInt64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case []bool:
-		var v2 []bool
-		v2, changed = fastpathTV.DecSliceBoolV(v, false, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]bool:
-		var v2 []bool
-		v2, changed = fastpathTV.DecSliceBoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-
-	case map[interface{}]interface{}:
-		fastpathTV.DecMapIntfIntfV(v, false, d)
-	case *map[interface{}]interface{}:
-		var v2 map[interface{}]interface{}
-		v2, changed = fastpathTV.DecMapIntfIntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]string:
-		fastpathTV.DecMapIntfStringV(v, false, d)
-	case *map[interface{}]string:
-		var v2 map[interface{}]string
-		v2, changed = fastpathTV.DecMapIntfStringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uint:
-		fastpathTV.DecMapIntfUintV(v, false, d)
-	case *map[interface{}]uint:
-		var v2 map[interface{}]uint
-		v2, changed = fastpathTV.DecMapIntfUintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uint8:
-		fastpathTV.DecMapIntfUint8V(v, false, d)
-	case *map[interface{}]uint8:
-		var v2 map[interface{}]uint8
-		v2, changed = fastpathTV.DecMapIntfUint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uint16:
-		fastpathTV.DecMapIntfUint16V(v, false, d)
-	case *map[interface{}]uint16:
-		var v2 map[interface{}]uint16
-		v2, changed = fastpathTV.DecMapIntfUint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uint32:
-		fastpathTV.DecMapIntfUint32V(v, false, d)
-	case *map[interface{}]uint32:
-		var v2 map[interface{}]uint32
-		v2, changed = fastpathTV.DecMapIntfUint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uint64:
-		fastpathTV.DecMapIntfUint64V(v, false, d)
-	case *map[interface{}]uint64:
-		var v2 map[interface{}]uint64
-		v2, changed = fastpathTV.DecMapIntfUint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]uintptr:
-		fastpathTV.DecMapIntfUintptrV(v, false, d)
-	case *map[interface{}]uintptr:
-		var v2 map[interface{}]uintptr
-		v2, changed = fastpathTV.DecMapIntfUintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]int:
-		fastpathTV.DecMapIntfIntV(v, false, d)
-	case *map[interface{}]int:
-		var v2 map[interface{}]int
-		v2, changed = fastpathTV.DecMapIntfIntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]int8:
-		fastpathTV.DecMapIntfInt8V(v, false, d)
-	case *map[interface{}]int8:
-		var v2 map[interface{}]int8
-		v2, changed = fastpathTV.DecMapIntfInt8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]int16:
-		fastpathTV.DecMapIntfInt16V(v, false, d)
-	case *map[interface{}]int16:
-		var v2 map[interface{}]int16
-		v2, changed = fastpathTV.DecMapIntfInt16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]int32:
-		fastpathTV.DecMapIntfInt32V(v, false, d)
-	case *map[interface{}]int32:
-		var v2 map[interface{}]int32
-		v2, changed = fastpathTV.DecMapIntfInt32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]int64:
-		fastpathTV.DecMapIntfInt64V(v, false, d)
-	case *map[interface{}]int64:
-		var v2 map[interface{}]int64
-		v2, changed = fastpathTV.DecMapIntfInt64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]float32:
-		fastpathTV.DecMapIntfFloat32V(v, false, d)
-	case *map[interface{}]float32:
-		var v2 map[interface{}]float32
-		v2, changed = fastpathTV.DecMapIntfFloat32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]float64:
-		fastpathTV.DecMapIntfFloat64V(v, false, d)
-	case *map[interface{}]float64:
-		var v2 map[interface{}]float64
-		v2, changed = fastpathTV.DecMapIntfFloat64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[interface{}]bool:
-		fastpathTV.DecMapIntfBoolV(v, false, d)
-	case *map[interface{}]bool:
-		var v2 map[interface{}]bool
-		v2, changed = fastpathTV.DecMapIntfBoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]interface{}:
-		fastpathTV.DecMapStringIntfV(v, false, d)
-	case *map[string]interface{}:
-		var v2 map[string]interface{}
-		v2, changed = fastpathTV.DecMapStringIntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]string:
-		fastpathTV.DecMapStringStringV(v, false, d)
-	case *map[string]string:
-		var v2 map[string]string
-		v2, changed = fastpathTV.DecMapStringStringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uint:
-		fastpathTV.DecMapStringUintV(v, false, d)
-	case *map[string]uint:
-		var v2 map[string]uint
-		v2, changed = fastpathTV.DecMapStringUintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uint8:
-		fastpathTV.DecMapStringUint8V(v, false, d)
-	case *map[string]uint8:
-		var v2 map[string]uint8
-		v2, changed = fastpathTV.DecMapStringUint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uint16:
-		fastpathTV.DecMapStringUint16V(v, false, d)
-	case *map[string]uint16:
-		var v2 map[string]uint16
-		v2, changed = fastpathTV.DecMapStringUint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uint32:
-		fastpathTV.DecMapStringUint32V(v, false, d)
-	case *map[string]uint32:
-		var v2 map[string]uint32
-		v2, changed = fastpathTV.DecMapStringUint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uint64:
-		fastpathTV.DecMapStringUint64V(v, false, d)
-	case *map[string]uint64:
-		var v2 map[string]uint64
-		v2, changed = fastpathTV.DecMapStringUint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]uintptr:
-		fastpathTV.DecMapStringUintptrV(v, false, d)
-	case *map[string]uintptr:
-		var v2 map[string]uintptr
-		v2, changed = fastpathTV.DecMapStringUintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]int:
-		fastpathTV.DecMapStringIntV(v, false, d)
-	case *map[string]int:
-		var v2 map[string]int
-		v2, changed = fastpathTV.DecMapStringIntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]int8:
-		fastpathTV.DecMapStringInt8V(v, false, d)
-	case *map[string]int8:
-		var v2 map[string]int8
-		v2, changed = fastpathTV.DecMapStringInt8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]int16:
-		fastpathTV.DecMapStringInt16V(v, false, d)
-	case *map[string]int16:
-		var v2 map[string]int16
-		v2, changed = fastpathTV.DecMapStringInt16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]int32:
-		fastpathTV.DecMapStringInt32V(v, false, d)
-	case *map[string]int32:
-		var v2 map[string]int32
-		v2, changed = fastpathTV.DecMapStringInt32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]int64:
-		fastpathTV.DecMapStringInt64V(v, false, d)
-	case *map[string]int64:
-		var v2 map[string]int64
-		v2, changed = fastpathTV.DecMapStringInt64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]float32:
-		fastpathTV.DecMapStringFloat32V(v, false, d)
-	case *map[string]float32:
-		var v2 map[string]float32
-		v2, changed = fastpathTV.DecMapStringFloat32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]float64:
-		fastpathTV.DecMapStringFloat64V(v, false, d)
-	case *map[string]float64:
-		var v2 map[string]float64
-		v2, changed = fastpathTV.DecMapStringFloat64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[string]bool:
-		fastpathTV.DecMapStringBoolV(v, false, d)
-	case *map[string]bool:
-		var v2 map[string]bool
-		v2, changed = fastpathTV.DecMapStringBoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]interface{}:
-		fastpathTV.DecMapFloat32IntfV(v, false, d)
-	case *map[float32]interface{}:
-		var v2 map[float32]interface{}
-		v2, changed = fastpathTV.DecMapFloat32IntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]string:
-		fastpathTV.DecMapFloat32StringV(v, false, d)
-	case *map[float32]string:
-		var v2 map[float32]string
-		v2, changed = fastpathTV.DecMapFloat32StringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]uint:
-		fastpathTV.DecMapFloat32UintV(v, false, d)
-	case *map[float32]uint:
-		var v2 map[float32]uint
-		v2, changed = fastpathTV.DecMapFloat32UintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]uint8:
-		fastpathTV.DecMapFloat32Uint8V(v, false, d)
-	case *map[float32]uint8:
-		var v2 map[float32]uint8
-		v2, changed = fastpathTV.DecMapFloat32Uint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]uint16:
-		fastpathTV.DecMapFloat32Uint16V(v, false, d)
-	case *map[float32]uint16:
-		var v2 map[float32]uint16
-		v2, changed = fastpathTV.DecMapFloat32Uint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]uint32:
-		fastpathTV.DecMapFloat32Uint32V(v, false, d)
-	case *map[float32]uint32:
-		var v2 map[float32]uint32
-		v2, changed = fastpathTV.DecMapFloat32Uint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]uint64:
-		fastpathTV.DecMapFloat32Uint64V(v, false, d)
-	case *map[float32]uint64:
-		var v2 map[float32]uint64
-		v2, changed = fastpathTV.DecMapFloat32Uint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]uintptr:
-		fastpathTV.DecMapFloat32UintptrV(v, false, d)
-	case *map[float32]uintptr:
-		var v2 map[float32]uintptr
-		v2, changed = fastpathTV.DecMapFloat32UintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]int:
-		fastpathTV.DecMapFloat32IntV(v, false, d)
-	case *map[float32]int:
-		var v2 map[float32]int
-		v2, changed = fastpathTV.DecMapFloat32IntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]int8:
-		fastpathTV.DecMapFloat32Int8V(v, false, d)
-	case *map[float32]int8:
-		var v2 map[float32]int8
-		v2, changed = fastpathTV.DecMapFloat32Int8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]int16:
-		fastpathTV.DecMapFloat32Int16V(v, false, d)
-	case *map[float32]int16:
-		var v2 map[float32]int16
-		v2, changed = fastpathTV.DecMapFloat32Int16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]int32:
-		fastpathTV.DecMapFloat32Int32V(v, false, d)
-	case *map[float32]int32:
-		var v2 map[float32]int32
-		v2, changed = fastpathTV.DecMapFloat32Int32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]int64:
-		fastpathTV.DecMapFloat32Int64V(v, false, d)
-	case *map[float32]int64:
-		var v2 map[float32]int64
-		v2, changed = fastpathTV.DecMapFloat32Int64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]float32:
-		fastpathTV.DecMapFloat32Float32V(v, false, d)
-	case *map[float32]float32:
-		var v2 map[float32]float32
-		v2, changed = fastpathTV.DecMapFloat32Float32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]float64:
-		fastpathTV.DecMapFloat32Float64V(v, false, d)
-	case *map[float32]float64:
-		var v2 map[float32]float64
-		v2, changed = fastpathTV.DecMapFloat32Float64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float32]bool:
-		fastpathTV.DecMapFloat32BoolV(v, false, d)
-	case *map[float32]bool:
-		var v2 map[float32]bool
-		v2, changed = fastpathTV.DecMapFloat32BoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]interface{}:
-		fastpathTV.DecMapFloat64IntfV(v, false, d)
-	case *map[float64]interface{}:
-		var v2 map[float64]interface{}
-		v2, changed = fastpathTV.DecMapFloat64IntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]string:
-		fastpathTV.DecMapFloat64StringV(v, false, d)
-	case *map[float64]string:
-		var v2 map[float64]string
-		v2, changed = fastpathTV.DecMapFloat64StringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]uint:
-		fastpathTV.DecMapFloat64UintV(v, false, d)
-	case *map[float64]uint:
-		var v2 map[float64]uint
-		v2, changed = fastpathTV.DecMapFloat64UintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]uint8:
-		fastpathTV.DecMapFloat64Uint8V(v, false, d)
-	case *map[float64]uint8:
-		var v2 map[float64]uint8
-		v2, changed = fastpathTV.DecMapFloat64Uint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]uint16:
-		fastpathTV.DecMapFloat64Uint16V(v, false, d)
-	case *map[float64]uint16:
-		var v2 map[float64]uint16
-		v2, changed = fastpathTV.DecMapFloat64Uint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]uint32:
-		fastpathTV.DecMapFloat64Uint32V(v, false, d)
-	case *map[float64]uint32:
-		var v2 map[float64]uint32
-		v2, changed = fastpathTV.DecMapFloat64Uint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]uint64:
-		fastpathTV.DecMapFloat64Uint64V(v, false, d)
-	case *map[float64]uint64:
-		var v2 map[float64]uint64
-		v2, changed = fastpathTV.DecMapFloat64Uint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]uintptr:
-		fastpathTV.DecMapFloat64UintptrV(v, false, d)
-	case *map[float64]uintptr:
-		var v2 map[float64]uintptr
-		v2, changed = fastpathTV.DecMapFloat64UintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]int:
-		fastpathTV.DecMapFloat64IntV(v, false, d)
-	case *map[float64]int:
-		var v2 map[float64]int
-		v2, changed = fastpathTV.DecMapFloat64IntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]int8:
-		fastpathTV.DecMapFloat64Int8V(v, false, d)
-	case *map[float64]int8:
-		var v2 map[float64]int8
-		v2, changed = fastpathTV.DecMapFloat64Int8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]int16:
-		fastpathTV.DecMapFloat64Int16V(v, false, d)
-	case *map[float64]int16:
-		var v2 map[float64]int16
-		v2, changed = fastpathTV.DecMapFloat64Int16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]int32:
-		fastpathTV.DecMapFloat64Int32V(v, false, d)
-	case *map[float64]int32:
-		var v2 map[float64]int32
-		v2, changed = fastpathTV.DecMapFloat64Int32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]int64:
-		fastpathTV.DecMapFloat64Int64V(v, false, d)
-	case *map[float64]int64:
-		var v2 map[float64]int64
-		v2, changed = fastpathTV.DecMapFloat64Int64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]float32:
-		fastpathTV.DecMapFloat64Float32V(v, false, d)
-	case *map[float64]float32:
-		var v2 map[float64]float32
-		v2, changed = fastpathTV.DecMapFloat64Float32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]float64:
-		fastpathTV.DecMapFloat64Float64V(v, false, d)
-	case *map[float64]float64:
-		var v2 map[float64]float64
-		v2, changed = fastpathTV.DecMapFloat64Float64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[float64]bool:
-		fastpathTV.DecMapFloat64BoolV(v, false, d)
-	case *map[float64]bool:
-		var v2 map[float64]bool
-		v2, changed = fastpathTV.DecMapFloat64BoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]interface{}:
-		fastpathTV.DecMapUintIntfV(v, false, d)
-	case *map[uint]interface{}:
-		var v2 map[uint]interface{}
-		v2, changed = fastpathTV.DecMapUintIntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]string:
-		fastpathTV.DecMapUintStringV(v, false, d)
-	case *map[uint]string:
-		var v2 map[uint]string
-		v2, changed = fastpathTV.DecMapUintStringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]uint:
-		fastpathTV.DecMapUintUintV(v, false, d)
-	case *map[uint]uint:
-		var v2 map[uint]uint
-		v2, changed = fastpathTV.DecMapUintUintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]uint8:
-		fastpathTV.DecMapUintUint8V(v, false, d)
-	case *map[uint]uint8:
-		var v2 map[uint]uint8
-		v2, changed = fastpathTV.DecMapUintUint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]uint16:
-		fastpathTV.DecMapUintUint16V(v, false, d)
-	case *map[uint]uint16:
-		var v2 map[uint]uint16
-		v2, changed = fastpathTV.DecMapUintUint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]uint32:
-		fastpathTV.DecMapUintUint32V(v, false, d)
-	case *map[uint]uint32:
-		var v2 map[uint]uint32
-		v2, changed = fastpathTV.DecMapUintUint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]uint64:
-		fastpathTV.DecMapUintUint64V(v, false, d)
-	case *map[uint]uint64:
-		var v2 map[uint]uint64
-		v2, changed = fastpathTV.DecMapUintUint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]uintptr:
-		fastpathTV.DecMapUintUintptrV(v, false, d)
-	case *map[uint]uintptr:
-		var v2 map[uint]uintptr
-		v2, changed = fastpathTV.DecMapUintUintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]int:
-		fastpathTV.DecMapUintIntV(v, false, d)
-	case *map[uint]int:
-		var v2 map[uint]int
-		v2, changed = fastpathTV.DecMapUintIntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]int8:
-		fastpathTV.DecMapUintInt8V(v, false, d)
-	case *map[uint]int8:
-		var v2 map[uint]int8
-		v2, changed = fastpathTV.DecMapUintInt8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]int16:
-		fastpathTV.DecMapUintInt16V(v, false, d)
-	case *map[uint]int16:
-		var v2 map[uint]int16
-		v2, changed = fastpathTV.DecMapUintInt16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]int32:
-		fastpathTV.DecMapUintInt32V(v, false, d)
-	case *map[uint]int32:
-		var v2 map[uint]int32
-		v2, changed = fastpathTV.DecMapUintInt32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]int64:
-		fastpathTV.DecMapUintInt64V(v, false, d)
-	case *map[uint]int64:
-		var v2 map[uint]int64
-		v2, changed = fastpathTV.DecMapUintInt64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]float32:
-		fastpathTV.DecMapUintFloat32V(v, false, d)
-	case *map[uint]float32:
-		var v2 map[uint]float32
-		v2, changed = fastpathTV.DecMapUintFloat32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]float64:
-		fastpathTV.DecMapUintFloat64V(v, false, d)
-	case *map[uint]float64:
-		var v2 map[uint]float64
-		v2, changed = fastpathTV.DecMapUintFloat64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint]bool:
-		fastpathTV.DecMapUintBoolV(v, false, d)
-	case *map[uint]bool:
-		var v2 map[uint]bool
-		v2, changed = fastpathTV.DecMapUintBoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]interface{}:
-		fastpathTV.DecMapUint8IntfV(v, false, d)
-	case *map[uint8]interface{}:
-		var v2 map[uint8]interface{}
-		v2, changed = fastpathTV.DecMapUint8IntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]string:
-		fastpathTV.DecMapUint8StringV(v, false, d)
-	case *map[uint8]string:
-		var v2 map[uint8]string
-		v2, changed = fastpathTV.DecMapUint8StringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]uint:
-		fastpathTV.DecMapUint8UintV(v, false, d)
-	case *map[uint8]uint:
-		var v2 map[uint8]uint
-		v2, changed = fastpathTV.DecMapUint8UintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]uint8:
-		fastpathTV.DecMapUint8Uint8V(v, false, d)
-	case *map[uint8]uint8:
-		var v2 map[uint8]uint8
-		v2, changed = fastpathTV.DecMapUint8Uint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]uint16:
-		fastpathTV.DecMapUint8Uint16V(v, false, d)
-	case *map[uint8]uint16:
-		var v2 map[uint8]uint16
-		v2, changed = fastpathTV.DecMapUint8Uint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]uint32:
-		fastpathTV.DecMapUint8Uint32V(v, false, d)
-	case *map[uint8]uint32:
-		var v2 map[uint8]uint32
-		v2, changed = fastpathTV.DecMapUint8Uint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]uint64:
-		fastpathTV.DecMapUint8Uint64V(v, false, d)
-	case *map[uint8]uint64:
-		var v2 map[uint8]uint64
-		v2, changed = fastpathTV.DecMapUint8Uint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]uintptr:
-		fastpathTV.DecMapUint8UintptrV(v, false, d)
-	case *map[uint8]uintptr:
-		var v2 map[uint8]uintptr
-		v2, changed = fastpathTV.DecMapUint8UintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]int:
-		fastpathTV.DecMapUint8IntV(v, false, d)
-	case *map[uint8]int:
-		var v2 map[uint8]int
-		v2, changed = fastpathTV.DecMapUint8IntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]int8:
-		fastpathTV.DecMapUint8Int8V(v, false, d)
-	case *map[uint8]int8:
-		var v2 map[uint8]int8
-		v2, changed = fastpathTV.DecMapUint8Int8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]int16:
-		fastpathTV.DecMapUint8Int16V(v, false, d)
-	case *map[uint8]int16:
-		var v2 map[uint8]int16
-		v2, changed = fastpathTV.DecMapUint8Int16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]int32:
-		fastpathTV.DecMapUint8Int32V(v, false, d)
-	case *map[uint8]int32:
-		var v2 map[uint8]int32
-		v2, changed = fastpathTV.DecMapUint8Int32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]int64:
-		fastpathTV.DecMapUint8Int64V(v, false, d)
-	case *map[uint8]int64:
-		var v2 map[uint8]int64
-		v2, changed = fastpathTV.DecMapUint8Int64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]float32:
-		fastpathTV.DecMapUint8Float32V(v, false, d)
-	case *map[uint8]float32:
-		var v2 map[uint8]float32
-		v2, changed = fastpathTV.DecMapUint8Float32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]float64:
-		fastpathTV.DecMapUint8Float64V(v, false, d)
-	case *map[uint8]float64:
-		var v2 map[uint8]float64
-		v2, changed = fastpathTV.DecMapUint8Float64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint8]bool:
-		fastpathTV.DecMapUint8BoolV(v, false, d)
-	case *map[uint8]bool:
-		var v2 map[uint8]bool
-		v2, changed = fastpathTV.DecMapUint8BoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]interface{}:
-		fastpathTV.DecMapUint16IntfV(v, false, d)
-	case *map[uint16]interface{}:
-		var v2 map[uint16]interface{}
-		v2, changed = fastpathTV.DecMapUint16IntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]string:
-		fastpathTV.DecMapUint16StringV(v, false, d)
-	case *map[uint16]string:
-		var v2 map[uint16]string
-		v2, changed = fastpathTV.DecMapUint16StringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]uint:
-		fastpathTV.DecMapUint16UintV(v, false, d)
-	case *map[uint16]uint:
-		var v2 map[uint16]uint
-		v2, changed = fastpathTV.DecMapUint16UintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]uint8:
-		fastpathTV.DecMapUint16Uint8V(v, false, d)
-	case *map[uint16]uint8:
-		var v2 map[uint16]uint8
-		v2, changed = fastpathTV.DecMapUint16Uint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]uint16:
-		fastpathTV.DecMapUint16Uint16V(v, false, d)
-	case *map[uint16]uint16:
-		var v2 map[uint16]uint16
-		v2, changed = fastpathTV.DecMapUint16Uint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]uint32:
-		fastpathTV.DecMapUint16Uint32V(v, false, d)
-	case *map[uint16]uint32:
-		var v2 map[uint16]uint32
-		v2, changed = fastpathTV.DecMapUint16Uint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]uint64:
-		fastpathTV.DecMapUint16Uint64V(v, false, d)
-	case *map[uint16]uint64:
-		var v2 map[uint16]uint64
-		v2, changed = fastpathTV.DecMapUint16Uint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]uintptr:
-		fastpathTV.DecMapUint16UintptrV(v, false, d)
-	case *map[uint16]uintptr:
-		var v2 map[uint16]uintptr
-		v2, changed = fastpathTV.DecMapUint16UintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]int:
-		fastpathTV.DecMapUint16IntV(v, false, d)
-	case *map[uint16]int:
-		var v2 map[uint16]int
-		v2, changed = fastpathTV.DecMapUint16IntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]int8:
-		fastpathTV.DecMapUint16Int8V(v, false, d)
-	case *map[uint16]int8:
-		var v2 map[uint16]int8
-		v2, changed = fastpathTV.DecMapUint16Int8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]int16:
-		fastpathTV.DecMapUint16Int16V(v, false, d)
-	case *map[uint16]int16:
-		var v2 map[uint16]int16
-		v2, changed = fastpathTV.DecMapUint16Int16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]int32:
-		fastpathTV.DecMapUint16Int32V(v, false, d)
-	case *map[uint16]int32:
-		var v2 map[uint16]int32
-		v2, changed = fastpathTV.DecMapUint16Int32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]int64:
-		fastpathTV.DecMapUint16Int64V(v, false, d)
-	case *map[uint16]int64:
-		var v2 map[uint16]int64
-		v2, changed = fastpathTV.DecMapUint16Int64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]float32:
-		fastpathTV.DecMapUint16Float32V(v, false, d)
-	case *map[uint16]float32:
-		var v2 map[uint16]float32
-		v2, changed = fastpathTV.DecMapUint16Float32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]float64:
-		fastpathTV.DecMapUint16Float64V(v, false, d)
-	case *map[uint16]float64:
-		var v2 map[uint16]float64
-		v2, changed = fastpathTV.DecMapUint16Float64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint16]bool:
-		fastpathTV.DecMapUint16BoolV(v, false, d)
-	case *map[uint16]bool:
-		var v2 map[uint16]bool
-		v2, changed = fastpathTV.DecMapUint16BoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]interface{}:
-		fastpathTV.DecMapUint32IntfV(v, false, d)
-	case *map[uint32]interface{}:
-		var v2 map[uint32]interface{}
-		v2, changed = fastpathTV.DecMapUint32IntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]string:
-		fastpathTV.DecMapUint32StringV(v, false, d)
-	case *map[uint32]string:
-		var v2 map[uint32]string
-		v2, changed = fastpathTV.DecMapUint32StringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]uint:
-		fastpathTV.DecMapUint32UintV(v, false, d)
-	case *map[uint32]uint:
-		var v2 map[uint32]uint
-		v2, changed = fastpathTV.DecMapUint32UintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]uint8:
-		fastpathTV.DecMapUint32Uint8V(v, false, d)
-	case *map[uint32]uint8:
-		var v2 map[uint32]uint8
-		v2, changed = fastpathTV.DecMapUint32Uint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]uint16:
-		fastpathTV.DecMapUint32Uint16V(v, false, d)
-	case *map[uint32]uint16:
-		var v2 map[uint32]uint16
-		v2, changed = fastpathTV.DecMapUint32Uint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]uint32:
-		fastpathTV.DecMapUint32Uint32V(v, false, d)
-	case *map[uint32]uint32:
-		var v2 map[uint32]uint32
-		v2, changed = fastpathTV.DecMapUint32Uint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]uint64:
-		fastpathTV.DecMapUint32Uint64V(v, false, d)
-	case *map[uint32]uint64:
-		var v2 map[uint32]uint64
-		v2, changed = fastpathTV.DecMapUint32Uint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]uintptr:
-		fastpathTV.DecMapUint32UintptrV(v, false, d)
-	case *map[uint32]uintptr:
-		var v2 map[uint32]uintptr
-		v2, changed = fastpathTV.DecMapUint32UintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]int:
-		fastpathTV.DecMapUint32IntV(v, false, d)
-	case *map[uint32]int:
-		var v2 map[uint32]int
-		v2, changed = fastpathTV.DecMapUint32IntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]int8:
-		fastpathTV.DecMapUint32Int8V(v, false, d)
-	case *map[uint32]int8:
-		var v2 map[uint32]int8
-		v2, changed = fastpathTV.DecMapUint32Int8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]int16:
-		fastpathTV.DecMapUint32Int16V(v, false, d)
-	case *map[uint32]int16:
-		var v2 map[uint32]int16
-		v2, changed = fastpathTV.DecMapUint32Int16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]int32:
-		fastpathTV.DecMapUint32Int32V(v, false, d)
-	case *map[uint32]int32:
-		var v2 map[uint32]int32
-		v2, changed = fastpathTV.DecMapUint32Int32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]int64:
-		fastpathTV.DecMapUint32Int64V(v, false, d)
-	case *map[uint32]int64:
-		var v2 map[uint32]int64
-		v2, changed = fastpathTV.DecMapUint32Int64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]float32:
-		fastpathTV.DecMapUint32Float32V(v, false, d)
-	case *map[uint32]float32:
-		var v2 map[uint32]float32
-		v2, changed = fastpathTV.DecMapUint32Float32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]float64:
-		fastpathTV.DecMapUint32Float64V(v, false, d)
-	case *map[uint32]float64:
-		var v2 map[uint32]float64
-		v2, changed = fastpathTV.DecMapUint32Float64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint32]bool:
-		fastpathTV.DecMapUint32BoolV(v, false, d)
-	case *map[uint32]bool:
-		var v2 map[uint32]bool
-		v2, changed = fastpathTV.DecMapUint32BoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]interface{}:
-		fastpathTV.DecMapUint64IntfV(v, false, d)
-	case *map[uint64]interface{}:
-		var v2 map[uint64]interface{}
-		v2, changed = fastpathTV.DecMapUint64IntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]string:
-		fastpathTV.DecMapUint64StringV(v, false, d)
-	case *map[uint64]string:
-		var v2 map[uint64]string
-		v2, changed = fastpathTV.DecMapUint64StringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]uint:
-		fastpathTV.DecMapUint64UintV(v, false, d)
-	case *map[uint64]uint:
-		var v2 map[uint64]uint
-		v2, changed = fastpathTV.DecMapUint64UintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]uint8:
-		fastpathTV.DecMapUint64Uint8V(v, false, d)
-	case *map[uint64]uint8:
-		var v2 map[uint64]uint8
-		v2, changed = fastpathTV.DecMapUint64Uint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]uint16:
-		fastpathTV.DecMapUint64Uint16V(v, false, d)
-	case *map[uint64]uint16:
-		var v2 map[uint64]uint16
-		v2, changed = fastpathTV.DecMapUint64Uint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]uint32:
-		fastpathTV.DecMapUint64Uint32V(v, false, d)
-	case *map[uint64]uint32:
-		var v2 map[uint64]uint32
-		v2, changed = fastpathTV.DecMapUint64Uint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]uint64:
-		fastpathTV.DecMapUint64Uint64V(v, false, d)
-	case *map[uint64]uint64:
-		var v2 map[uint64]uint64
-		v2, changed = fastpathTV.DecMapUint64Uint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]uintptr:
-		fastpathTV.DecMapUint64UintptrV(v, false, d)
-	case *map[uint64]uintptr:
-		var v2 map[uint64]uintptr
-		v2, changed = fastpathTV.DecMapUint64UintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]int:
-		fastpathTV.DecMapUint64IntV(v, false, d)
-	case *map[uint64]int:
-		var v2 map[uint64]int
-		v2, changed = fastpathTV.DecMapUint64IntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]int8:
-		fastpathTV.DecMapUint64Int8V(v, false, d)
-	case *map[uint64]int8:
-		var v2 map[uint64]int8
-		v2, changed = fastpathTV.DecMapUint64Int8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]int16:
-		fastpathTV.DecMapUint64Int16V(v, false, d)
-	case *map[uint64]int16:
-		var v2 map[uint64]int16
-		v2, changed = fastpathTV.DecMapUint64Int16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]int32:
-		fastpathTV.DecMapUint64Int32V(v, false, d)
-	case *map[uint64]int32:
-		var v2 map[uint64]int32
-		v2, changed = fastpathTV.DecMapUint64Int32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]int64:
-		fastpathTV.DecMapUint64Int64V(v, false, d)
-	case *map[uint64]int64:
-		var v2 map[uint64]int64
-		v2, changed = fastpathTV.DecMapUint64Int64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]float32:
-		fastpathTV.DecMapUint64Float32V(v, false, d)
-	case *map[uint64]float32:
-		var v2 map[uint64]float32
-		v2, changed = fastpathTV.DecMapUint64Float32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]float64:
-		fastpathTV.DecMapUint64Float64V(v, false, d)
-	case *map[uint64]float64:
-		var v2 map[uint64]float64
-		v2, changed = fastpathTV.DecMapUint64Float64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uint64]bool:
-		fastpathTV.DecMapUint64BoolV(v, false, d)
-	case *map[uint64]bool:
-		var v2 map[uint64]bool
-		v2, changed = fastpathTV.DecMapUint64BoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]interface{}:
-		fastpathTV.DecMapUintptrIntfV(v, false, d)
-	case *map[uintptr]interface{}:
-		var v2 map[uintptr]interface{}
-		v2, changed = fastpathTV.DecMapUintptrIntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]string:
-		fastpathTV.DecMapUintptrStringV(v, false, d)
-	case *map[uintptr]string:
-		var v2 map[uintptr]string
-		v2, changed = fastpathTV.DecMapUintptrStringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]uint:
-		fastpathTV.DecMapUintptrUintV(v, false, d)
-	case *map[uintptr]uint:
-		var v2 map[uintptr]uint
-		v2, changed = fastpathTV.DecMapUintptrUintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]uint8:
-		fastpathTV.DecMapUintptrUint8V(v, false, d)
-	case *map[uintptr]uint8:
-		var v2 map[uintptr]uint8
-		v2, changed = fastpathTV.DecMapUintptrUint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]uint16:
-		fastpathTV.DecMapUintptrUint16V(v, false, d)
-	case *map[uintptr]uint16:
-		var v2 map[uintptr]uint16
-		v2, changed = fastpathTV.DecMapUintptrUint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]uint32:
-		fastpathTV.DecMapUintptrUint32V(v, false, d)
-	case *map[uintptr]uint32:
-		var v2 map[uintptr]uint32
-		v2, changed = fastpathTV.DecMapUintptrUint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]uint64:
-		fastpathTV.DecMapUintptrUint64V(v, false, d)
-	case *map[uintptr]uint64:
-		var v2 map[uintptr]uint64
-		v2, changed = fastpathTV.DecMapUintptrUint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]uintptr:
-		fastpathTV.DecMapUintptrUintptrV(v, false, d)
-	case *map[uintptr]uintptr:
-		var v2 map[uintptr]uintptr
-		v2, changed = fastpathTV.DecMapUintptrUintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]int:
-		fastpathTV.DecMapUintptrIntV(v, false, d)
-	case *map[uintptr]int:
-		var v2 map[uintptr]int
-		v2, changed = fastpathTV.DecMapUintptrIntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]int8:
-		fastpathTV.DecMapUintptrInt8V(v, false, d)
-	case *map[uintptr]int8:
-		var v2 map[uintptr]int8
-		v2, changed = fastpathTV.DecMapUintptrInt8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]int16:
-		fastpathTV.DecMapUintptrInt16V(v, false, d)
-	case *map[uintptr]int16:
-		var v2 map[uintptr]int16
-		v2, changed = fastpathTV.DecMapUintptrInt16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]int32:
-		fastpathTV.DecMapUintptrInt32V(v, false, d)
-	case *map[uintptr]int32:
-		var v2 map[uintptr]int32
-		v2, changed = fastpathTV.DecMapUintptrInt32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]int64:
-		fastpathTV.DecMapUintptrInt64V(v, false, d)
-	case *map[uintptr]int64:
-		var v2 map[uintptr]int64
-		v2, changed = fastpathTV.DecMapUintptrInt64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]float32:
-		fastpathTV.DecMapUintptrFloat32V(v, false, d)
-	case *map[uintptr]float32:
-		var v2 map[uintptr]float32
-		v2, changed = fastpathTV.DecMapUintptrFloat32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]float64:
-		fastpathTV.DecMapUintptrFloat64V(v, false, d)
-	case *map[uintptr]float64:
-		var v2 map[uintptr]float64
-		v2, changed = fastpathTV.DecMapUintptrFloat64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[uintptr]bool:
-		fastpathTV.DecMapUintptrBoolV(v, false, d)
-	case *map[uintptr]bool:
-		var v2 map[uintptr]bool
-		v2, changed = fastpathTV.DecMapUintptrBoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]interface{}:
-		fastpathTV.DecMapIntIntfV(v, false, d)
-	case *map[int]interface{}:
-		var v2 map[int]interface{}
-		v2, changed = fastpathTV.DecMapIntIntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]string:
-		fastpathTV.DecMapIntStringV(v, false, d)
-	case *map[int]string:
-		var v2 map[int]string
-		v2, changed = fastpathTV.DecMapIntStringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]uint:
-		fastpathTV.DecMapIntUintV(v, false, d)
-	case *map[int]uint:
-		var v2 map[int]uint
-		v2, changed = fastpathTV.DecMapIntUintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]uint8:
-		fastpathTV.DecMapIntUint8V(v, false, d)
-	case *map[int]uint8:
-		var v2 map[int]uint8
-		v2, changed = fastpathTV.DecMapIntUint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]uint16:
-		fastpathTV.DecMapIntUint16V(v, false, d)
-	case *map[int]uint16:
-		var v2 map[int]uint16
-		v2, changed = fastpathTV.DecMapIntUint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]uint32:
-		fastpathTV.DecMapIntUint32V(v, false, d)
-	case *map[int]uint32:
-		var v2 map[int]uint32
-		v2, changed = fastpathTV.DecMapIntUint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]uint64:
-		fastpathTV.DecMapIntUint64V(v, false, d)
-	case *map[int]uint64:
-		var v2 map[int]uint64
-		v2, changed = fastpathTV.DecMapIntUint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]uintptr:
-		fastpathTV.DecMapIntUintptrV(v, false, d)
-	case *map[int]uintptr:
-		var v2 map[int]uintptr
-		v2, changed = fastpathTV.DecMapIntUintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]int:
-		fastpathTV.DecMapIntIntV(v, false, d)
-	case *map[int]int:
-		var v2 map[int]int
-		v2, changed = fastpathTV.DecMapIntIntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]int8:
-		fastpathTV.DecMapIntInt8V(v, false, d)
-	case *map[int]int8:
-		var v2 map[int]int8
-		v2, changed = fastpathTV.DecMapIntInt8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]int16:
-		fastpathTV.DecMapIntInt16V(v, false, d)
-	case *map[int]int16:
-		var v2 map[int]int16
-		v2, changed = fastpathTV.DecMapIntInt16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]int32:
-		fastpathTV.DecMapIntInt32V(v, false, d)
-	case *map[int]int32:
-		var v2 map[int]int32
-		v2, changed = fastpathTV.DecMapIntInt32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]int64:
-		fastpathTV.DecMapIntInt64V(v, false, d)
-	case *map[int]int64:
-		var v2 map[int]int64
-		v2, changed = fastpathTV.DecMapIntInt64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]float32:
-		fastpathTV.DecMapIntFloat32V(v, false, d)
-	case *map[int]float32:
-		var v2 map[int]float32
-		v2, changed = fastpathTV.DecMapIntFloat32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]float64:
-		fastpathTV.DecMapIntFloat64V(v, false, d)
-	case *map[int]float64:
-		var v2 map[int]float64
-		v2, changed = fastpathTV.DecMapIntFloat64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int]bool:
-		fastpathTV.DecMapIntBoolV(v, false, d)
-	case *map[int]bool:
-		var v2 map[int]bool
-		v2, changed = fastpathTV.DecMapIntBoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]interface{}:
-		fastpathTV.DecMapInt8IntfV(v, false, d)
-	case *map[int8]interface{}:
-		var v2 map[int8]interface{}
-		v2, changed = fastpathTV.DecMapInt8IntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]string:
-		fastpathTV.DecMapInt8StringV(v, false, d)
-	case *map[int8]string:
-		var v2 map[int8]string
-		v2, changed = fastpathTV.DecMapInt8StringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]uint:
-		fastpathTV.DecMapInt8UintV(v, false, d)
-	case *map[int8]uint:
-		var v2 map[int8]uint
-		v2, changed = fastpathTV.DecMapInt8UintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]uint8:
-		fastpathTV.DecMapInt8Uint8V(v, false, d)
-	case *map[int8]uint8:
-		var v2 map[int8]uint8
-		v2, changed = fastpathTV.DecMapInt8Uint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]uint16:
-		fastpathTV.DecMapInt8Uint16V(v, false, d)
-	case *map[int8]uint16:
-		var v2 map[int8]uint16
-		v2, changed = fastpathTV.DecMapInt8Uint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]uint32:
-		fastpathTV.DecMapInt8Uint32V(v, false, d)
-	case *map[int8]uint32:
-		var v2 map[int8]uint32
-		v2, changed = fastpathTV.DecMapInt8Uint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]uint64:
-		fastpathTV.DecMapInt8Uint64V(v, false, d)
-	case *map[int8]uint64:
-		var v2 map[int8]uint64
-		v2, changed = fastpathTV.DecMapInt8Uint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]uintptr:
-		fastpathTV.DecMapInt8UintptrV(v, false, d)
-	case *map[int8]uintptr:
-		var v2 map[int8]uintptr
-		v2, changed = fastpathTV.DecMapInt8UintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]int:
-		fastpathTV.DecMapInt8IntV(v, false, d)
-	case *map[int8]int:
-		var v2 map[int8]int
-		v2, changed = fastpathTV.DecMapInt8IntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]int8:
-		fastpathTV.DecMapInt8Int8V(v, false, d)
-	case *map[int8]int8:
-		var v2 map[int8]int8
-		v2, changed = fastpathTV.DecMapInt8Int8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]int16:
-		fastpathTV.DecMapInt8Int16V(v, false, d)
-	case *map[int8]int16:
-		var v2 map[int8]int16
-		v2, changed = fastpathTV.DecMapInt8Int16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]int32:
-		fastpathTV.DecMapInt8Int32V(v, false, d)
-	case *map[int8]int32:
-		var v2 map[int8]int32
-		v2, changed = fastpathTV.DecMapInt8Int32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]int64:
-		fastpathTV.DecMapInt8Int64V(v, false, d)
-	case *map[int8]int64:
-		var v2 map[int8]int64
-		v2, changed = fastpathTV.DecMapInt8Int64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]float32:
-		fastpathTV.DecMapInt8Float32V(v, false, d)
-	case *map[int8]float32:
-		var v2 map[int8]float32
-		v2, changed = fastpathTV.DecMapInt8Float32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]float64:
-		fastpathTV.DecMapInt8Float64V(v, false, d)
-	case *map[int8]float64:
-		var v2 map[int8]float64
-		v2, changed = fastpathTV.DecMapInt8Float64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int8]bool:
-		fastpathTV.DecMapInt8BoolV(v, false, d)
-	case *map[int8]bool:
-		var v2 map[int8]bool
-		v2, changed = fastpathTV.DecMapInt8BoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]interface{}:
-		fastpathTV.DecMapInt16IntfV(v, false, d)
-	case *map[int16]interface{}:
-		var v2 map[int16]interface{}
-		v2, changed = fastpathTV.DecMapInt16IntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]string:
-		fastpathTV.DecMapInt16StringV(v, false, d)
-	case *map[int16]string:
-		var v2 map[int16]string
-		v2, changed = fastpathTV.DecMapInt16StringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]uint:
-		fastpathTV.DecMapInt16UintV(v, false, d)
-	case *map[int16]uint:
-		var v2 map[int16]uint
-		v2, changed = fastpathTV.DecMapInt16UintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]uint8:
-		fastpathTV.DecMapInt16Uint8V(v, false, d)
-	case *map[int16]uint8:
-		var v2 map[int16]uint8
-		v2, changed = fastpathTV.DecMapInt16Uint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]uint16:
-		fastpathTV.DecMapInt16Uint16V(v, false, d)
-	case *map[int16]uint16:
-		var v2 map[int16]uint16
-		v2, changed = fastpathTV.DecMapInt16Uint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]uint32:
-		fastpathTV.DecMapInt16Uint32V(v, false, d)
-	case *map[int16]uint32:
-		var v2 map[int16]uint32
-		v2, changed = fastpathTV.DecMapInt16Uint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]uint64:
-		fastpathTV.DecMapInt16Uint64V(v, false, d)
-	case *map[int16]uint64:
-		var v2 map[int16]uint64
-		v2, changed = fastpathTV.DecMapInt16Uint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]uintptr:
-		fastpathTV.DecMapInt16UintptrV(v, false, d)
-	case *map[int16]uintptr:
-		var v2 map[int16]uintptr
-		v2, changed = fastpathTV.DecMapInt16UintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]int:
-		fastpathTV.DecMapInt16IntV(v, false, d)
-	case *map[int16]int:
-		var v2 map[int16]int
-		v2, changed = fastpathTV.DecMapInt16IntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]int8:
-		fastpathTV.DecMapInt16Int8V(v, false, d)
-	case *map[int16]int8:
-		var v2 map[int16]int8
-		v2, changed = fastpathTV.DecMapInt16Int8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]int16:
-		fastpathTV.DecMapInt16Int16V(v, false, d)
-	case *map[int16]int16:
-		var v2 map[int16]int16
-		v2, changed = fastpathTV.DecMapInt16Int16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]int32:
-		fastpathTV.DecMapInt16Int32V(v, false, d)
-	case *map[int16]int32:
-		var v2 map[int16]int32
-		v2, changed = fastpathTV.DecMapInt16Int32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]int64:
-		fastpathTV.DecMapInt16Int64V(v, false, d)
-	case *map[int16]int64:
-		var v2 map[int16]int64
-		v2, changed = fastpathTV.DecMapInt16Int64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]float32:
-		fastpathTV.DecMapInt16Float32V(v, false, d)
-	case *map[int16]float32:
-		var v2 map[int16]float32
-		v2, changed = fastpathTV.DecMapInt16Float32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]float64:
-		fastpathTV.DecMapInt16Float64V(v, false, d)
-	case *map[int16]float64:
-		var v2 map[int16]float64
-		v2, changed = fastpathTV.DecMapInt16Float64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int16]bool:
-		fastpathTV.DecMapInt16BoolV(v, false, d)
-	case *map[int16]bool:
-		var v2 map[int16]bool
-		v2, changed = fastpathTV.DecMapInt16BoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]interface{}:
-		fastpathTV.DecMapInt32IntfV(v, false, d)
-	case *map[int32]interface{}:
-		var v2 map[int32]interface{}
-		v2, changed = fastpathTV.DecMapInt32IntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]string:
-		fastpathTV.DecMapInt32StringV(v, false, d)
-	case *map[int32]string:
-		var v2 map[int32]string
-		v2, changed = fastpathTV.DecMapInt32StringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]uint:
-		fastpathTV.DecMapInt32UintV(v, false, d)
-	case *map[int32]uint:
-		var v2 map[int32]uint
-		v2, changed = fastpathTV.DecMapInt32UintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]uint8:
-		fastpathTV.DecMapInt32Uint8V(v, false, d)
-	case *map[int32]uint8:
-		var v2 map[int32]uint8
-		v2, changed = fastpathTV.DecMapInt32Uint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]uint16:
-		fastpathTV.DecMapInt32Uint16V(v, false, d)
-	case *map[int32]uint16:
-		var v2 map[int32]uint16
-		v2, changed = fastpathTV.DecMapInt32Uint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]uint32:
-		fastpathTV.DecMapInt32Uint32V(v, false, d)
-	case *map[int32]uint32:
-		var v2 map[int32]uint32
-		v2, changed = fastpathTV.DecMapInt32Uint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]uint64:
-		fastpathTV.DecMapInt32Uint64V(v, false, d)
-	case *map[int32]uint64:
-		var v2 map[int32]uint64
-		v2, changed = fastpathTV.DecMapInt32Uint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]uintptr:
-		fastpathTV.DecMapInt32UintptrV(v, false, d)
-	case *map[int32]uintptr:
-		var v2 map[int32]uintptr
-		v2, changed = fastpathTV.DecMapInt32UintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]int:
-		fastpathTV.DecMapInt32IntV(v, false, d)
-	case *map[int32]int:
-		var v2 map[int32]int
-		v2, changed = fastpathTV.DecMapInt32IntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]int8:
-		fastpathTV.DecMapInt32Int8V(v, false, d)
-	case *map[int32]int8:
-		var v2 map[int32]int8
-		v2, changed = fastpathTV.DecMapInt32Int8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]int16:
-		fastpathTV.DecMapInt32Int16V(v, false, d)
-	case *map[int32]int16:
-		var v2 map[int32]int16
-		v2, changed = fastpathTV.DecMapInt32Int16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]int32:
-		fastpathTV.DecMapInt32Int32V(v, false, d)
-	case *map[int32]int32:
-		var v2 map[int32]int32
-		v2, changed = fastpathTV.DecMapInt32Int32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]int64:
-		fastpathTV.DecMapInt32Int64V(v, false, d)
-	case *map[int32]int64:
-		var v2 map[int32]int64
-		v2, changed = fastpathTV.DecMapInt32Int64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]float32:
-		fastpathTV.DecMapInt32Float32V(v, false, d)
-	case *map[int32]float32:
-		var v2 map[int32]float32
-		v2, changed = fastpathTV.DecMapInt32Float32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]float64:
-		fastpathTV.DecMapInt32Float64V(v, false, d)
-	case *map[int32]float64:
-		var v2 map[int32]float64
-		v2, changed = fastpathTV.DecMapInt32Float64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int32]bool:
-		fastpathTV.DecMapInt32BoolV(v, false, d)
-	case *map[int32]bool:
-		var v2 map[int32]bool
-		v2, changed = fastpathTV.DecMapInt32BoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]interface{}:
-		fastpathTV.DecMapInt64IntfV(v, false, d)
-	case *map[int64]interface{}:
-		var v2 map[int64]interface{}
-		v2, changed = fastpathTV.DecMapInt64IntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]string:
-		fastpathTV.DecMapInt64StringV(v, false, d)
-	case *map[int64]string:
-		var v2 map[int64]string
-		v2, changed = fastpathTV.DecMapInt64StringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]uint:
-		fastpathTV.DecMapInt64UintV(v, false, d)
-	case *map[int64]uint:
-		var v2 map[int64]uint
-		v2, changed = fastpathTV.DecMapInt64UintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]uint8:
-		fastpathTV.DecMapInt64Uint8V(v, false, d)
-	case *map[int64]uint8:
-		var v2 map[int64]uint8
-		v2, changed = fastpathTV.DecMapInt64Uint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]uint16:
-		fastpathTV.DecMapInt64Uint16V(v, false, d)
-	case *map[int64]uint16:
-		var v2 map[int64]uint16
-		v2, changed = fastpathTV.DecMapInt64Uint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]uint32:
-		fastpathTV.DecMapInt64Uint32V(v, false, d)
-	case *map[int64]uint32:
-		var v2 map[int64]uint32
-		v2, changed = fastpathTV.DecMapInt64Uint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]uint64:
-		fastpathTV.DecMapInt64Uint64V(v, false, d)
-	case *map[int64]uint64:
-		var v2 map[int64]uint64
-		v2, changed = fastpathTV.DecMapInt64Uint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]uintptr:
-		fastpathTV.DecMapInt64UintptrV(v, false, d)
-	case *map[int64]uintptr:
-		var v2 map[int64]uintptr
-		v2, changed = fastpathTV.DecMapInt64UintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]int:
-		fastpathTV.DecMapInt64IntV(v, false, d)
-	case *map[int64]int:
-		var v2 map[int64]int
-		v2, changed = fastpathTV.DecMapInt64IntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]int8:
-		fastpathTV.DecMapInt64Int8V(v, false, d)
-	case *map[int64]int8:
-		var v2 map[int64]int8
-		v2, changed = fastpathTV.DecMapInt64Int8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]int16:
-		fastpathTV.DecMapInt64Int16V(v, false, d)
-	case *map[int64]int16:
-		var v2 map[int64]int16
-		v2, changed = fastpathTV.DecMapInt64Int16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]int32:
-		fastpathTV.DecMapInt64Int32V(v, false, d)
-	case *map[int64]int32:
-		var v2 map[int64]int32
-		v2, changed = fastpathTV.DecMapInt64Int32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]int64:
-		fastpathTV.DecMapInt64Int64V(v, false, d)
-	case *map[int64]int64:
-		var v2 map[int64]int64
-		v2, changed = fastpathTV.DecMapInt64Int64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]float32:
-		fastpathTV.DecMapInt64Float32V(v, false, d)
-	case *map[int64]float32:
-		var v2 map[int64]float32
-		v2, changed = fastpathTV.DecMapInt64Float32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]float64:
-		fastpathTV.DecMapInt64Float64V(v, false, d)
-	case *map[int64]float64:
-		var v2 map[int64]float64
-		v2, changed = fastpathTV.DecMapInt64Float64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[int64]bool:
-		fastpathTV.DecMapInt64BoolV(v, false, d)
-	case *map[int64]bool:
-		var v2 map[int64]bool
-		v2, changed = fastpathTV.DecMapInt64BoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]interface{}:
-		fastpathTV.DecMapBoolIntfV(v, false, d)
-	case *map[bool]interface{}:
-		var v2 map[bool]interface{}
-		v2, changed = fastpathTV.DecMapBoolIntfV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]string:
-		fastpathTV.DecMapBoolStringV(v, false, d)
-	case *map[bool]string:
-		var v2 map[bool]string
-		v2, changed = fastpathTV.DecMapBoolStringV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]uint:
-		fastpathTV.DecMapBoolUintV(v, false, d)
-	case *map[bool]uint:
-		var v2 map[bool]uint
-		v2, changed = fastpathTV.DecMapBoolUintV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]uint8:
-		fastpathTV.DecMapBoolUint8V(v, false, d)
-	case *map[bool]uint8:
-		var v2 map[bool]uint8
-		v2, changed = fastpathTV.DecMapBoolUint8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]uint16:
-		fastpathTV.DecMapBoolUint16V(v, false, d)
-	case *map[bool]uint16:
-		var v2 map[bool]uint16
-		v2, changed = fastpathTV.DecMapBoolUint16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]uint32:
-		fastpathTV.DecMapBoolUint32V(v, false, d)
-	case *map[bool]uint32:
-		var v2 map[bool]uint32
-		v2, changed = fastpathTV.DecMapBoolUint32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]uint64:
-		fastpathTV.DecMapBoolUint64V(v, false, d)
-	case *map[bool]uint64:
-		var v2 map[bool]uint64
-		v2, changed = fastpathTV.DecMapBoolUint64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]uintptr:
-		fastpathTV.DecMapBoolUintptrV(v, false, d)
-	case *map[bool]uintptr:
-		var v2 map[bool]uintptr
-		v2, changed = fastpathTV.DecMapBoolUintptrV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]int:
-		fastpathTV.DecMapBoolIntV(v, false, d)
-	case *map[bool]int:
-		var v2 map[bool]int
-		v2, changed = fastpathTV.DecMapBoolIntV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]int8:
-		fastpathTV.DecMapBoolInt8V(v, false, d)
-	case *map[bool]int8:
-		var v2 map[bool]int8
-		v2, changed = fastpathTV.DecMapBoolInt8V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]int16:
-		fastpathTV.DecMapBoolInt16V(v, false, d)
-	case *map[bool]int16:
-		var v2 map[bool]int16
-		v2, changed = fastpathTV.DecMapBoolInt16V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]int32:
-		fastpathTV.DecMapBoolInt32V(v, false, d)
-	case *map[bool]int32:
-		var v2 map[bool]int32
-		v2, changed = fastpathTV.DecMapBoolInt32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]int64:
-		fastpathTV.DecMapBoolInt64V(v, false, d)
-	case *map[bool]int64:
-		var v2 map[bool]int64
-		v2, changed = fastpathTV.DecMapBoolInt64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]float32:
-		fastpathTV.DecMapBoolFloat32V(v, false, d)
-	case *map[bool]float32:
-		var v2 map[bool]float32
-		v2, changed = fastpathTV.DecMapBoolFloat32V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]float64:
-		fastpathTV.DecMapBoolFloat64V(v, false, d)
-	case *map[bool]float64:
-		var v2 map[bool]float64
-		v2, changed = fastpathTV.DecMapBoolFloat64V(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	case map[bool]bool:
-		fastpathTV.DecMapBoolBoolV(v, false, d)
-	case *map[bool]bool:
-		var v2 map[bool]bool
-		v2, changed = fastpathTV.DecMapBoolBoolV(*v, true, d)
-		if changed {
-			*v = v2
-		}
-	default:
-		_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
-		return false
-	}
-	return true
-}
-
-func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
-	switch v := iv.(type) {
-
-	case *[]interface{}:
-		*v = nil
-	case *[]string:
-		*v = nil
-	case *[]float32:
-		*v = nil
-	case *[]float64:
-		*v = nil
-	case *[]uint:
-		*v = nil
-	case *[]uint8:
-		*v = nil
-	case *[]uint16:
-		*v = nil
-	case *[]uint32:
-		*v = nil
-	case *[]uint64:
-		*v = nil
-	case *[]uintptr:
-		*v = nil
-	case *[]int:
-		*v = nil
-	case *[]int8:
-		*v = nil
-	case *[]int16:
-		*v = nil
-	case *[]int32:
-		*v = nil
-	case *[]int64:
-		*v = nil
-	case *[]bool:
-		*v = nil
-
-	case *map[interface{}]interface{}:
-		*v = nil
-	case *map[interface{}]string:
-		*v = nil
-	case *map[interface{}]uint:
-		*v = nil
-	case *map[interface{}]uint8:
-		*v = nil
-	case *map[interface{}]uint16:
-		*v = nil
-	case *map[interface{}]uint32:
-		*v = nil
-	case *map[interface{}]uint64:
-		*v = nil
-	case *map[interface{}]uintptr:
-		*v = nil
-	case *map[interface{}]int:
-		*v = nil
-	case *map[interface{}]int8:
-		*v = nil
-	case *map[interface{}]int16:
-		*v = nil
-	case *map[interface{}]int32:
-		*v = nil
-	case *map[interface{}]int64:
-		*v = nil
-	case *map[interface{}]float32:
-		*v = nil
-	case *map[interface{}]float64:
-		*v = nil
-	case *map[interface{}]bool:
-		*v = nil
-	case *map[string]interface{}:
-		*v = nil
-	case *map[string]string:
-		*v = nil
-	case *map[string]uint:
-		*v = nil
-	case *map[string]uint8:
-		*v = nil
-	case *map[string]uint16:
-		*v = nil
-	case *map[string]uint32:
-		*v = nil
-	case *map[string]uint64:
-		*v = nil
-	case *map[string]uintptr:
-		*v = nil
-	case *map[string]int:
-		*v = nil
-	case *map[string]int8:
-		*v = nil
-	case *map[string]int16:
-		*v = nil
-	case *map[string]int32:
-		*v = nil
-	case *map[string]int64:
-		*v = nil
-	case *map[string]float32:
-		*v = nil
-	case *map[string]float64:
-		*v = nil
-	case *map[string]bool:
-		*v = nil
-	case *map[float32]interface{}:
-		*v = nil
-	case *map[float32]string:
-		*v = nil
-	case *map[float32]uint:
-		*v = nil
-	case *map[float32]uint8:
-		*v = nil
-	case *map[float32]uint16:
-		*v = nil
-	case *map[float32]uint32:
-		*v = nil
-	case *map[float32]uint64:
-		*v = nil
-	case *map[float32]uintptr:
-		*v = nil
-	case *map[float32]int:
-		*v = nil
-	case *map[float32]int8:
-		*v = nil
-	case *map[float32]int16:
-		*v = nil
-	case *map[float32]int32:
-		*v = nil
-	case *map[float32]int64:
-		*v = nil
-	case *map[float32]float32:
-		*v = nil
-	case *map[float32]float64:
-		*v = nil
-	case *map[float32]bool:
-		*v = nil
-	case *map[float64]interface{}:
-		*v = nil
-	case *map[float64]string:
-		*v = nil
-	case *map[float64]uint:
-		*v = nil
-	case *map[float64]uint8:
-		*v = nil
-	case *map[float64]uint16:
-		*v = nil
-	case *map[float64]uint32:
-		*v = nil
-	case *map[float64]uint64:
-		*v = nil
-	case *map[float64]uintptr:
-		*v = nil
-	case *map[float64]int:
-		*v = nil
-	case *map[float64]int8:
-		*v = nil
-	case *map[float64]int16:
-		*v = nil
-	case *map[float64]int32:
-		*v = nil
-	case *map[float64]int64:
-		*v = nil
-	case *map[float64]float32:
-		*v = nil
-	case *map[float64]float64:
-		*v = nil
-	case *map[float64]bool:
-		*v = nil
-	case *map[uint]interface{}:
-		*v = nil
-	case *map[uint]string:
-		*v = nil
-	case *map[uint]uint:
-		*v = nil
-	case *map[uint]uint8:
-		*v = nil
-	case *map[uint]uint16:
-		*v = nil
-	case *map[uint]uint32:
-		*v = nil
-	case *map[uint]uint64:
-		*v = nil
-	case *map[uint]uintptr:
-		*v = nil
-	case *map[uint]int:
-		*v = nil
-	case *map[uint]int8:
-		*v = nil
-	case *map[uint]int16:
-		*v = nil
-	case *map[uint]int32:
-		*v = nil
-	case *map[uint]int64:
-		*v = nil
-	case *map[uint]float32:
-		*v = nil
-	case *map[uint]float64:
-		*v = nil
-	case *map[uint]bool:
-		*v = nil
-	case *map[uint8]interface{}:
-		*v = nil
-	case *map[uint8]string:
-		*v = nil
-	case *map[uint8]uint:
-		*v = nil
-	case *map[uint8]uint8:
-		*v = nil
-	case *map[uint8]uint16:
-		*v = nil
-	case *map[uint8]uint32:
-		*v = nil
-	case *map[uint8]uint64:
-		*v = nil
-	case *map[uint8]uintptr:
-		*v = nil
-	case *map[uint8]int:
-		*v = nil
-	case *map[uint8]int8:
-		*v = nil
-	case *map[uint8]int16:
-		*v = nil
-	case *map[uint8]int32:
-		*v = nil
-	case *map[uint8]int64:
-		*v = nil
-	case *map[uint8]float32:
-		*v = nil
-	case *map[uint8]float64:
-		*v = nil
-	case *map[uint8]bool:
-		*v = nil
-	case *map[uint16]interface{}:
-		*v = nil
-	case *map[uint16]string:
-		*v = nil
-	case *map[uint16]uint:
-		*v = nil
-	case *map[uint16]uint8:
-		*v = nil
-	case *map[uint16]uint16:
-		*v = nil
-	case *map[uint16]uint32:
-		*v = nil
-	case *map[uint16]uint64:
-		*v = nil
-	case *map[uint16]uintptr:
-		*v = nil
-	case *map[uint16]int:
-		*v = nil
-	case *map[uint16]int8:
-		*v = nil
-	case *map[uint16]int16:
-		*v = nil
-	case *map[uint16]int32:
-		*v = nil
-	case *map[uint16]int64:
-		*v = nil
-	case *map[uint16]float32:
-		*v = nil
-	case *map[uint16]float64:
-		*v = nil
-	case *map[uint16]bool:
-		*v = nil
-	case *map[uint32]interface{}:
-		*v = nil
-	case *map[uint32]string:
-		*v = nil
-	case *map[uint32]uint:
-		*v = nil
-	case *map[uint32]uint8:
-		*v = nil
-	case *map[uint32]uint16:
-		*v = nil
-	case *map[uint32]uint32:
-		*v = nil
-	case *map[uint32]uint64:
-		*v = nil
-	case *map[uint32]uintptr:
-		*v = nil
-	case *map[uint32]int:
-		*v = nil
-	case *map[uint32]int8:
-		*v = nil
-	case *map[uint32]int16:
-		*v = nil
-	case *map[uint32]int32:
-		*v = nil
-	case *map[uint32]int64:
-		*v = nil
-	case *map[uint32]float32:
-		*v = nil
-	case *map[uint32]float64:
-		*v = nil
-	case *map[uint32]bool:
-		*v = nil
-	case *map[uint64]interface{}:
-		*v = nil
-	case *map[uint64]string:
-		*v = nil
-	case *map[uint64]uint:
-		*v = nil
-	case *map[uint64]uint8:
-		*v = nil
-	case *map[uint64]uint16:
-		*v = nil
-	case *map[uint64]uint32:
-		*v = nil
-	case *map[uint64]uint64:
-		*v = nil
-	case *map[uint64]uintptr:
-		*v = nil
-	case *map[uint64]int:
-		*v = nil
-	case *map[uint64]int8:
-		*v = nil
-	case *map[uint64]int16:
-		*v = nil
-	case *map[uint64]int32:
-		*v = nil
-	case *map[uint64]int64:
-		*v = nil
-	case *map[uint64]float32:
-		*v = nil
-	case *map[uint64]float64:
-		*v = nil
-	case *map[uint64]bool:
-		*v = nil
-	case *map[uintptr]interface{}:
-		*v = nil
-	case *map[uintptr]string:
-		*v = nil
-	case *map[uintptr]uint:
-		*v = nil
-	case *map[uintptr]uint8:
-		*v = nil
-	case *map[uintptr]uint16:
-		*v = nil
-	case *map[uintptr]uint32:
-		*v = nil
-	case *map[uintptr]uint64:
-		*v = nil
-	case *map[uintptr]uintptr:
-		*v = nil
-	case *map[uintptr]int:
-		*v = nil
-	case *map[uintptr]int8:
-		*v = nil
-	case *map[uintptr]int16:
-		*v = nil
-	case *map[uintptr]int32:
-		*v = nil
-	case *map[uintptr]int64:
-		*v = nil
-	case *map[uintptr]float32:
-		*v = nil
-	case *map[uintptr]float64:
-		*v = nil
-	case *map[uintptr]bool:
-		*v = nil
-	case *map[int]interface{}:
-		*v = nil
-	case *map[int]string:
-		*v = nil
-	case *map[int]uint:
-		*v = nil
-	case *map[int]uint8:
-		*v = nil
-	case *map[int]uint16:
-		*v = nil
-	case *map[int]uint32:
-		*v = nil
-	case *map[int]uint64:
-		*v = nil
-	case *map[int]uintptr:
-		*v = nil
-	case *map[int]int:
-		*v = nil
-	case *map[int]int8:
-		*v = nil
-	case *map[int]int16:
-		*v = nil
-	case *map[int]int32:
-		*v = nil
-	case *map[int]int64:
-		*v = nil
-	case *map[int]float32:
-		*v = nil
-	case *map[int]float64:
-		*v = nil
-	case *map[int]bool:
-		*v = nil
-	case *map[int8]interface{}:
-		*v = nil
-	case *map[int8]string:
-		*v = nil
-	case *map[int8]uint:
-		*v = nil
-	case *map[int8]uint8:
-		*v = nil
-	case *map[int8]uint16:
-		*v = nil
-	case *map[int8]uint32:
-		*v = nil
-	case *map[int8]uint64:
-		*v = nil
-	case *map[int8]uintptr:
-		*v = nil
-	case *map[int8]int:
-		*v = nil
-	case *map[int8]int8:
-		*v = nil
-	case *map[int8]int16:
-		*v = nil
-	case *map[int8]int32:
-		*v = nil
-	case *map[int8]int64:
-		*v = nil
-	case *map[int8]float32:
-		*v = nil
-	case *map[int8]float64:
-		*v = nil
-	case *map[int8]bool:
-		*v = nil
-	case *map[int16]interface{}:
-		*v = nil
-	case *map[int16]string:
-		*v = nil
-	case *map[int16]uint:
-		*v = nil
-	case *map[int16]uint8:
-		*v = nil
-	case *map[int16]uint16:
-		*v = nil
-	case *map[int16]uint32:
-		*v = nil
-	case *map[int16]uint64:
-		*v = nil
-	case *map[int16]uintptr:
-		*v = nil
-	case *map[int16]int:
-		*v = nil
-	case *map[int16]int8:
-		*v = nil
-	case *map[int16]int16:
-		*v = nil
-	case *map[int16]int32:
-		*v = nil
-	case *map[int16]int64:
-		*v = nil
-	case *map[int16]float32:
-		*v = nil
-	case *map[int16]float64:
-		*v = nil
-	case *map[int16]bool:
-		*v = nil
-	case *map[int32]interface{}:
-		*v = nil
-	case *map[int32]string:
-		*v = nil
-	case *map[int32]uint:
-		*v = nil
-	case *map[int32]uint8:
-		*v = nil
-	case *map[int32]uint16:
-		*v = nil
-	case *map[int32]uint32:
-		*v = nil
-	case *map[int32]uint64:
-		*v = nil
-	case *map[int32]uintptr:
-		*v = nil
-	case *map[int32]int:
-		*v = nil
-	case *map[int32]int8:
-		*v = nil
-	case *map[int32]int16:
-		*v = nil
-	case *map[int32]int32:
-		*v = nil
-	case *map[int32]int64:
-		*v = nil
-	case *map[int32]float32:
-		*v = nil
-	case *map[int32]float64:
-		*v = nil
-	case *map[int32]bool:
-		*v = nil
-	case *map[int64]interface{}:
-		*v = nil
-	case *map[int64]string:
-		*v = nil
-	case *map[int64]uint:
-		*v = nil
-	case *map[int64]uint8:
-		*v = nil
-	case *map[int64]uint16:
-		*v = nil
-	case *map[int64]uint32:
-		*v = nil
-	case *map[int64]uint64:
-		*v = nil
-	case *map[int64]uintptr:
-		*v = nil
-	case *map[int64]int:
-		*v = nil
-	case *map[int64]int8:
-		*v = nil
-	case *map[int64]int16:
-		*v = nil
-	case *map[int64]int32:
-		*v = nil
-	case *map[int64]int64:
-		*v = nil
-	case *map[int64]float32:
-		*v = nil
-	case *map[int64]float64:
-		*v = nil
-	case *map[int64]bool:
-		*v = nil
-	case *map[bool]interface{}:
-		*v = nil
-	case *map[bool]string:
-		*v = nil
-	case *map[bool]uint:
-		*v = nil
-	case *map[bool]uint8:
-		*v = nil
-	case *map[bool]uint16:
-		*v = nil
-	case *map[bool]uint32:
-		*v = nil
-	case *map[bool]uint64:
-		*v = nil
-	case *map[bool]uintptr:
-		*v = nil
-	case *map[bool]int:
-		*v = nil
-	case *map[bool]int8:
-		*v = nil
-	case *map[bool]int16:
-		*v = nil
-	case *map[bool]int32:
-		*v = nil
-	case *map[bool]int64:
-		*v = nil
-	case *map[bool]float32:
-		*v = nil
-	case *map[bool]float64:
-		*v = nil
-	case *map[bool]bool:
-		*v = nil
-	default:
-		_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
-		return false
-	}
-	return true
-}
-
-// -- -- fast path functions
-
-func (d *Decoder) fastpathDecSliceIntfR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]interface{})
-		v, changed := fastpathTV.DecSliceIntfV(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]interface{})
-		v2, changed := fastpathTV.DecSliceIntfV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceIntfX(vp *[]interface{}, d *Decoder) {
-	v, changed := f.DecSliceIntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceIntfV(v []interface{}, canChange bool, d *Decoder) (_ []interface{}, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []interface{}{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]interface{}, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
-			} else {
-				xlen = 8
-			}
-			v = make([]interface{}, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, nil)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = nil
-		} else {
-			d.decode(&v[j])
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]interface{}, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceStringR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]string)
-		v, changed := fastpathTV.DecSliceStringV(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]string)
-		v2, changed := fastpathTV.DecSliceStringV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceStringX(vp *[]string, d *Decoder) {
-	v, changed := f.DecSliceStringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceStringV(v []string, canChange bool, d *Decoder) (_ []string, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []string{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]string, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
-			} else {
-				xlen = 8
-			}
-			v = make([]string, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, "")
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = ""
-		} else {
-			v[j] = dd.DecodeString()
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]string, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]float32)
-		v, changed := fastpathTV.DecSliceFloat32V(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]float32)
-		v2, changed := fastpathTV.DecSliceFloat32V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceFloat32X(vp *[]float32, d *Decoder) {
-	v, changed := f.DecSliceFloat32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceFloat32V(v []float32, canChange bool, d *Decoder) (_ []float32, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []float32{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]float32, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			} else {
-				xlen = 8
-			}
-			v = make([]float32, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]float32, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]float64)
-		v, changed := fastpathTV.DecSliceFloat64V(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]float64)
-		v2, changed := fastpathTV.DecSliceFloat64V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceFloat64X(vp *[]float64, d *Decoder) {
-	v, changed := f.DecSliceFloat64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceFloat64V(v []float64, canChange bool, d *Decoder) (_ []float64, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []float64{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]float64, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
-			}
-			v = make([]float64, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = dd.DecodeFloat64()
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]float64, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceUintR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uint)
-		v, changed := fastpathTV.DecSliceUintV(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]uint)
-		v2, changed := fastpathTV.DecSliceUintV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceUintX(vp *[]uint, d *Decoder) {
-	v, changed := f.DecSliceUintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceUintV(v []uint, canChange bool, d *Decoder) (_ []uint, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []uint{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]uint, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
-			}
-			v = make([]uint, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uint, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceUint8R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uint8)
-		v, changed := fastpathTV.DecSliceUint8V(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]uint8)
-		v2, changed := fastpathTV.DecSliceUint8V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceUint8X(vp *[]uint8, d *Decoder) {
-	v, changed := f.DecSliceUint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []uint8{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]uint8, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			} else {
-				xlen = 8
-			}
-			v = make([]uint8, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uint8, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceUint16R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uint16)
-		v, changed := fastpathTV.DecSliceUint16V(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]uint16)
-		v2, changed := fastpathTV.DecSliceUint16V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceUint16X(vp *[]uint16, d *Decoder) {
-	v, changed := f.DecSliceUint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceUint16V(v []uint16, canChange bool, d *Decoder) (_ []uint16, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []uint16{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]uint16, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
-			} else {
-				xlen = 8
-			}
-			v = make([]uint16, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uint16, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceUint32R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uint32)
-		v, changed := fastpathTV.DecSliceUint32V(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]uint32)
-		v2, changed := fastpathTV.DecSliceUint32V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceUint32X(vp *[]uint32, d *Decoder) {
-	v, changed := f.DecSliceUint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceUint32V(v []uint32, canChange bool, d *Decoder) (_ []uint32, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []uint32{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]uint32, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			} else {
-				xlen = 8
-			}
-			v = make([]uint32, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uint32, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceUint64R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uint64)
-		v, changed := fastpathTV.DecSliceUint64V(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]uint64)
-		v2, changed := fastpathTV.DecSliceUint64V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceUint64X(vp *[]uint64, d *Decoder) {
-	v, changed := f.DecSliceUint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceUint64V(v []uint64, canChange bool, d *Decoder) (_ []uint64, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []uint64{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]uint64, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
-			}
-			v = make([]uint64, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = dd.DecodeUint64()
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uint64, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]uintptr)
-		v, changed := fastpathTV.DecSliceUintptrV(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]uintptr)
-		v2, changed := fastpathTV.DecSliceUintptrV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceUintptrX(vp *[]uintptr, d *Decoder) {
-	v, changed := f.DecSliceUintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceUintptrV(v []uintptr, canChange bool, d *Decoder) (_ []uintptr, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []uintptr{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]uintptr, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
-			}
-			v = make([]uintptr, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]uintptr, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceIntR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]int)
-		v, changed := fastpathTV.DecSliceIntV(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]int)
-		v2, changed := fastpathTV.DecSliceIntV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceIntX(vp *[]int, d *Decoder) {
-	v, changed := f.DecSliceIntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceIntV(v []int, canChange bool, d *Decoder) (_ []int, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []int{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]int, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
-			}
-			v = make([]int, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]int, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceInt8R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]int8)
-		v, changed := fastpathTV.DecSliceInt8V(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]int8)
-		v2, changed := fastpathTV.DecSliceInt8V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceInt8X(vp *[]int8, d *Decoder) {
-	v, changed := f.DecSliceInt8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceInt8V(v []int8, canChange bool, d *Decoder) (_ []int8, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []int8{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]int8, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			} else {
-				xlen = 8
-			}
-			v = make([]int8, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]int8, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceInt16R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]int16)
-		v, changed := fastpathTV.DecSliceInt16V(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]int16)
-		v2, changed := fastpathTV.DecSliceInt16V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceInt16X(vp *[]int16, d *Decoder) {
-	v, changed := f.DecSliceInt16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceInt16V(v []int16, canChange bool, d *Decoder) (_ []int16, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []int16{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]int16, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
-			} else {
-				xlen = 8
-			}
-			v = make([]int16, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]int16, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceInt32R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]int32)
-		v, changed := fastpathTV.DecSliceInt32V(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]int32)
-		v2, changed := fastpathTV.DecSliceInt32V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceInt32X(vp *[]int32, d *Decoder) {
-	v, changed := f.DecSliceInt32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceInt32V(v []int32, canChange bool, d *Decoder) (_ []int32, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []int32{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]int32, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
-			} else {
-				xlen = 8
-			}
-			v = make([]int32, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]int32, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceInt64R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]int64)
-		v, changed := fastpathTV.DecSliceInt64V(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]int64)
-		v2, changed := fastpathTV.DecSliceInt64V(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceInt64X(vp *[]int64, d *Decoder) {
-	v, changed := f.DecSliceInt64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceInt64V(v []int64, canChange bool, d *Decoder) (_ []int64, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []int64{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]int64, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
-			} else {
-				xlen = 8
-			}
-			v = make([]int64, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, 0)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = 0
-		} else {
-			v[j] = dd.DecodeInt64()
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]int64, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecSliceBoolR(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]bool)
-		v, changed := fastpathTV.DecSliceBoolV(*vp, !array, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		v := rv2i(rv).([]bool)
-		v2, changed := fastpathTV.DecSliceBoolV(v, !array, d)
-		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	}
-}
-func (f fastpathT) DecSliceBoolX(vp *[]bool, d *Decoder) {
-	v, changed := f.DecSliceBoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecSliceBoolV(v []bool, canChange bool, d *Decoder) (_ []bool, changed bool) {
-	dd := d.d
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil {
-				v = []bool{}
-			} else if len(v) != 0 {
-				v = v[:0]
-			}
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]bool, xlen)
-			}
-			changed = true
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
-			} else {
-				xlen = 8
-			}
-			v = make([]bool, xlen)
-			changed = true
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, false)
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		}
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = false
-		} else {
-			v[j] = dd.DecodeBool()
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]bool, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]interface{})
-		v, changed := fastpathTV.DecMapIntfIntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfIntfV(rv2i(rv).(map[interface{}]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfIntfX(vp *map[interface{}]interface{}, d *Decoder) {
-	v, changed := f.DecMapIntfIntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, canChange bool,
-	d *Decoder) (_ map[interface{}]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
-		v = make(map[interface{}]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk interface{}
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]string)
-		v, changed := fastpathTV.DecMapIntfStringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfStringV(rv2i(rv).(map[interface{}]string), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfStringX(vp *map[interface{}]string, d *Decoder) {
-	v, changed := f.DecMapIntfStringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, canChange bool,
-	d *Decoder) (_ map[interface{}]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
-		v = make(map[interface{}]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uint)
-		v, changed := fastpathTV.DecMapIntfUintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfUintV(rv2i(rv).(map[interface{}]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfUintX(vp *map[interface{}]uint, d *Decoder) {
-	v, changed := f.DecMapIntfUintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, canChange bool,
-	d *Decoder) (_ map[interface{}]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[interface{}]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uint8)
-		v, changed := fastpathTV.DecMapIntfUint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfUint8V(rv2i(rv).(map[interface{}]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfUint8X(vp *map[interface{}]uint8, d *Decoder) {
-	v, changed := f.DecMapIntfUint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, canChange bool,
-	d *Decoder) (_ map[interface{}]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[interface{}]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uint16)
-		v, changed := fastpathTV.DecMapIntfUint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfUint16V(rv2i(rv).(map[interface{}]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfUint16X(vp *map[interface{}]uint16, d *Decoder) {
-	v, changed := f.DecMapIntfUint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, canChange bool,
-	d *Decoder) (_ map[interface{}]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
-		v = make(map[interface{}]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uint32)
-		v, changed := fastpathTV.DecMapIntfUint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfUint32V(rv2i(rv).(map[interface{}]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfUint32X(vp *map[interface{}]uint32, d *Decoder) {
-	v, changed := f.DecMapIntfUint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, canChange bool,
-	d *Decoder) (_ map[interface{}]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[interface{}]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uint64)
-		v, changed := fastpathTV.DecMapIntfUint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfUint64V(rv2i(rv).(map[interface{}]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfUint64X(vp *map[interface{}]uint64, d *Decoder) {
-	v, changed := f.DecMapIntfUint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, canChange bool,
-	d *Decoder) (_ map[interface{}]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[interface{}]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]uintptr)
-		v, changed := fastpathTV.DecMapIntfUintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfUintptrV(rv2i(rv).(map[interface{}]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfUintptrX(vp *map[interface{}]uintptr, d *Decoder) {
-	v, changed := f.DecMapIntfUintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfUintptrV(v map[interface{}]uintptr, canChange bool,
-	d *Decoder) (_ map[interface{}]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[interface{}]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]int)
-		v, changed := fastpathTV.DecMapIntfIntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfIntV(rv2i(rv).(map[interface{}]int), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfIntX(vp *map[interface{}]int, d *Decoder) {
-	v, changed := f.DecMapIntfIntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, canChange bool,
-	d *Decoder) (_ map[interface{}]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[interface{}]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]int8)
-		v, changed := fastpathTV.DecMapIntfInt8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfInt8V(rv2i(rv).(map[interface{}]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfInt8X(vp *map[interface{}]int8, d *Decoder) {
-	v, changed := f.DecMapIntfInt8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, canChange bool,
-	d *Decoder) (_ map[interface{}]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[interface{}]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]int16)
-		v, changed := fastpathTV.DecMapIntfInt16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfInt16V(rv2i(rv).(map[interface{}]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfInt16X(vp *map[interface{}]int16, d *Decoder) {
-	v, changed := f.DecMapIntfInt16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, canChange bool,
-	d *Decoder) (_ map[interface{}]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
-		v = make(map[interface{}]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]int32)
-		v, changed := fastpathTV.DecMapIntfInt32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfInt32V(rv2i(rv).(map[interface{}]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfInt32X(vp *map[interface{}]int32, d *Decoder) {
-	v, changed := f.DecMapIntfInt32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, canChange bool,
-	d *Decoder) (_ map[interface{}]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[interface{}]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]int64)
-		v, changed := fastpathTV.DecMapIntfInt64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfInt64V(rv2i(rv).(map[interface{}]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfInt64X(vp *map[interface{}]int64, d *Decoder) {
-	v, changed := f.DecMapIntfInt64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, canChange bool,
-	d *Decoder) (_ map[interface{}]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[interface{}]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]float32)
-		v, changed := fastpathTV.DecMapIntfFloat32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfFloat32V(rv2i(rv).(map[interface{}]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfFloat32X(vp *map[interface{}]float32, d *Decoder) {
-	v, changed := f.DecMapIntfFloat32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, canChange bool,
-	d *Decoder) (_ map[interface{}]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[interface{}]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]float64)
-		v, changed := fastpathTV.DecMapIntfFloat64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfFloat64V(rv2i(rv).(map[interface{}]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfFloat64X(vp *map[interface{}]float64, d *Decoder) {
-	v, changed := f.DecMapIntfFloat64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, canChange bool,
-	d *Decoder) (_ map[interface{}]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[interface{}]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntfBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[interface{}]bool)
-		v, changed := fastpathTV.DecMapIntfBoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntfBoolV(rv2i(rv).(map[interface{}]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapIntfBoolX(vp *map[interface{}]bool, d *Decoder) {
-	v, changed := f.DecMapIntfBoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, canChange bool,
-	d *Decoder) (_ map[interface{}]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[interface{}]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk interface{}
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = nil
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv)
-		}
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]interface{})
-		v, changed := fastpathTV.DecMapStringIntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringIntfV(rv2i(rv).(map[string]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapStringIntfX(vp *map[string]interface{}, d *Decoder) {
-	v, changed := f.DecMapStringIntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringIntfV(v map[string]interface{}, canChange bool,
-	d *Decoder) (_ map[string]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
-		v = make(map[string]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk string
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]string)
-		v, changed := fastpathTV.DecMapStringStringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringStringV(rv2i(rv).(map[string]string), false, d)
-	}
-}
-func (f fastpathT) DecMapStringStringX(vp *map[string]string, d *Decoder) {
-	v, changed := f.DecMapStringStringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringStringV(v map[string]string, canChange bool,
-	d *Decoder) (_ map[string]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
-		v = make(map[string]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uint)
-		v, changed := fastpathTV.DecMapStringUintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringUintV(rv2i(rv).(map[string]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapStringUintX(vp *map[string]uint, d *Decoder) {
-	v, changed := f.DecMapStringUintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringUintV(v map[string]uint, canChange bool,
-	d *Decoder) (_ map[string]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[string]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uint8)
-		v, changed := fastpathTV.DecMapStringUint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringUint8V(rv2i(rv).(map[string]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapStringUint8X(vp *map[string]uint8, d *Decoder) {
-	v, changed := f.DecMapStringUint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringUint8V(v map[string]uint8, canChange bool,
-	d *Decoder) (_ map[string]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[string]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uint16)
-		v, changed := fastpathTV.DecMapStringUint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringUint16V(rv2i(rv).(map[string]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapStringUint16X(vp *map[string]uint16, d *Decoder) {
-	v, changed := f.DecMapStringUint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringUint16V(v map[string]uint16, canChange bool,
-	d *Decoder) (_ map[string]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
-		v = make(map[string]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uint32)
-		v, changed := fastpathTV.DecMapStringUint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringUint32V(rv2i(rv).(map[string]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapStringUint32X(vp *map[string]uint32, d *Decoder) {
-	v, changed := f.DecMapStringUint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringUint32V(v map[string]uint32, canChange bool,
-	d *Decoder) (_ map[string]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[string]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uint64)
-		v, changed := fastpathTV.DecMapStringUint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringUint64V(rv2i(rv).(map[string]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapStringUint64X(vp *map[string]uint64, d *Decoder) {
-	v, changed := f.DecMapStringUint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringUint64V(v map[string]uint64, canChange bool,
-	d *Decoder) (_ map[string]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[string]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]uintptr)
-		v, changed := fastpathTV.DecMapStringUintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringUintptrV(rv2i(rv).(map[string]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapStringUintptrX(vp *map[string]uintptr, d *Decoder) {
-	v, changed := f.DecMapStringUintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringUintptrV(v map[string]uintptr, canChange bool,
-	d *Decoder) (_ map[string]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[string]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]int)
-		v, changed := fastpathTV.DecMapStringIntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringIntV(rv2i(rv).(map[string]int), false, d)
-	}
-}
-func (f fastpathT) DecMapStringIntX(vp *map[string]int, d *Decoder) {
-	v, changed := f.DecMapStringIntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringIntV(v map[string]int, canChange bool,
-	d *Decoder) (_ map[string]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[string]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]int8)
-		v, changed := fastpathTV.DecMapStringInt8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringInt8V(rv2i(rv).(map[string]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapStringInt8X(vp *map[string]int8, d *Decoder) {
-	v, changed := f.DecMapStringInt8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringInt8V(v map[string]int8, canChange bool,
-	d *Decoder) (_ map[string]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[string]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]int16)
-		v, changed := fastpathTV.DecMapStringInt16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringInt16V(rv2i(rv).(map[string]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapStringInt16X(vp *map[string]int16, d *Decoder) {
-	v, changed := f.DecMapStringInt16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringInt16V(v map[string]int16, canChange bool,
-	d *Decoder) (_ map[string]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
-		v = make(map[string]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]int32)
-		v, changed := fastpathTV.DecMapStringInt32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringInt32V(rv2i(rv).(map[string]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapStringInt32X(vp *map[string]int32, d *Decoder) {
-	v, changed := f.DecMapStringInt32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringInt32V(v map[string]int32, canChange bool,
-	d *Decoder) (_ map[string]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[string]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]int64)
-		v, changed := fastpathTV.DecMapStringInt64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringInt64V(rv2i(rv).(map[string]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapStringInt64X(vp *map[string]int64, d *Decoder) {
-	v, changed := f.DecMapStringInt64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringInt64V(v map[string]int64, canChange bool,
-	d *Decoder) (_ map[string]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[string]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]float32)
-		v, changed := fastpathTV.DecMapStringFloat32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringFloat32V(rv2i(rv).(map[string]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapStringFloat32X(vp *map[string]float32, d *Decoder) {
-	v, changed := f.DecMapStringFloat32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringFloat32V(v map[string]float32, canChange bool,
-	d *Decoder) (_ map[string]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[string]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]float64)
-		v, changed := fastpathTV.DecMapStringFloat64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringFloat64V(rv2i(rv).(map[string]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapStringFloat64X(vp *map[string]float64, d *Decoder) {
-	v, changed := f.DecMapStringFloat64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringFloat64V(v map[string]float64, canChange bool,
-	d *Decoder) (_ map[string]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[string]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapStringBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[string]bool)
-		v, changed := fastpathTV.DecMapStringBoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapStringBoolV(rv2i(rv).(map[string]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapStringBoolX(vp *map[string]bool, d *Decoder) {
-	v, changed := f.DecMapStringBoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapStringBoolV(v map[string]bool, canChange bool,
-	d *Decoder) (_ map[string]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[string]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk string
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeString()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]interface{})
-		v, changed := fastpathTV.DecMapFloat32IntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32IntfV(rv2i(rv).(map[float32]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32IntfX(vp *map[float32]interface{}, d *Decoder) {
-	v, changed := f.DecMapFloat32IntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32IntfV(v map[float32]interface{}, canChange bool,
-	d *Decoder) (_ map[float32]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[float32]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk float32
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]string)
-		v, changed := fastpathTV.DecMapFloat32StringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32StringV(rv2i(rv).(map[float32]string), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32StringX(vp *map[float32]string, d *Decoder) {
-	v, changed := f.DecMapFloat32StringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32StringV(v map[float32]string, canChange bool,
-	d *Decoder) (_ map[float32]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[float32]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uint)
-		v, changed := fastpathTV.DecMapFloat32UintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32UintV(rv2i(rv).(map[float32]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32UintX(vp *map[float32]uint, d *Decoder) {
-	v, changed := f.DecMapFloat32UintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32UintV(v map[float32]uint, canChange bool,
-	d *Decoder) (_ map[float32]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[float32]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uint8)
-		v, changed := fastpathTV.DecMapFloat32Uint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32Uint8V(rv2i(rv).(map[float32]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32Uint8X(vp *map[float32]uint8, d *Decoder) {
-	v, changed := f.DecMapFloat32Uint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32Uint8V(v map[float32]uint8, canChange bool,
-	d *Decoder) (_ map[float32]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[float32]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uint16)
-		v, changed := fastpathTV.DecMapFloat32Uint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32Uint16V(rv2i(rv).(map[float32]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32Uint16X(vp *map[float32]uint16, d *Decoder) {
-	v, changed := f.DecMapFloat32Uint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32Uint16V(v map[float32]uint16, canChange bool,
-	d *Decoder) (_ map[float32]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[float32]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uint32)
-		v, changed := fastpathTV.DecMapFloat32Uint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32Uint32V(rv2i(rv).(map[float32]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32Uint32X(vp *map[float32]uint32, d *Decoder) {
-	v, changed := f.DecMapFloat32Uint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32Uint32V(v map[float32]uint32, canChange bool,
-	d *Decoder) (_ map[float32]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
-		v = make(map[float32]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uint64)
-		v, changed := fastpathTV.DecMapFloat32Uint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32Uint64V(rv2i(rv).(map[float32]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32Uint64X(vp *map[float32]uint64, d *Decoder) {
-	v, changed := f.DecMapFloat32Uint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32Uint64V(v map[float32]uint64, canChange bool,
-	d *Decoder) (_ map[float32]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[float32]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]uintptr)
-		v, changed := fastpathTV.DecMapFloat32UintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32UintptrV(rv2i(rv).(map[float32]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32UintptrX(vp *map[float32]uintptr, d *Decoder) {
-	v, changed := f.DecMapFloat32UintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32UintptrV(v map[float32]uintptr, canChange bool,
-	d *Decoder) (_ map[float32]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[float32]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]int)
-		v, changed := fastpathTV.DecMapFloat32IntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32IntV(rv2i(rv).(map[float32]int), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32IntX(vp *map[float32]int, d *Decoder) {
-	v, changed := f.DecMapFloat32IntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32IntV(v map[float32]int, canChange bool,
-	d *Decoder) (_ map[float32]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[float32]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]int8)
-		v, changed := fastpathTV.DecMapFloat32Int8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32Int8V(rv2i(rv).(map[float32]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32Int8X(vp *map[float32]int8, d *Decoder) {
-	v, changed := f.DecMapFloat32Int8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32Int8V(v map[float32]int8, canChange bool,
-	d *Decoder) (_ map[float32]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[float32]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]int16)
-		v, changed := fastpathTV.DecMapFloat32Int16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32Int16V(rv2i(rv).(map[float32]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32Int16X(vp *map[float32]int16, d *Decoder) {
-	v, changed := f.DecMapFloat32Int16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32Int16V(v map[float32]int16, canChange bool,
-	d *Decoder) (_ map[float32]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[float32]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]int32)
-		v, changed := fastpathTV.DecMapFloat32Int32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32Int32V(rv2i(rv).(map[float32]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32Int32X(vp *map[float32]int32, d *Decoder) {
-	v, changed := f.DecMapFloat32Int32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32Int32V(v map[float32]int32, canChange bool,
-	d *Decoder) (_ map[float32]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
-		v = make(map[float32]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]int64)
-		v, changed := fastpathTV.DecMapFloat32Int64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32Int64V(rv2i(rv).(map[float32]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32Int64X(vp *map[float32]int64, d *Decoder) {
-	v, changed := f.DecMapFloat32Int64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32Int64V(v map[float32]int64, canChange bool,
-	d *Decoder) (_ map[float32]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[float32]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]float32)
-		v, changed := fastpathTV.DecMapFloat32Float32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32Float32V(rv2i(rv).(map[float32]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32Float32X(vp *map[float32]float32, d *Decoder) {
-	v, changed := f.DecMapFloat32Float32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32Float32V(v map[float32]float32, canChange bool,
-	d *Decoder) (_ map[float32]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
-		v = make(map[float32]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]float64)
-		v, changed := fastpathTV.DecMapFloat32Float64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32Float64V(rv2i(rv).(map[float32]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32Float64X(vp *map[float32]float64, d *Decoder) {
-	v, changed := f.DecMapFloat32Float64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32Float64V(v map[float32]float64, canChange bool,
-	d *Decoder) (_ map[float32]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[float32]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat32BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float32]bool)
-		v, changed := fastpathTV.DecMapFloat32BoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat32BoolV(rv2i(rv).(map[float32]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat32BoolX(vp *map[float32]bool, d *Decoder) {
-	v, changed := f.DecMapFloat32BoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat32BoolV(v map[float32]bool, canChange bool,
-	d *Decoder) (_ map[float32]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[float32]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float32
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]interface{})
-		v, changed := fastpathTV.DecMapFloat64IntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64IntfV(rv2i(rv).(map[float64]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64IntfX(vp *map[float64]interface{}, d *Decoder) {
-	v, changed := f.DecMapFloat64IntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64IntfV(v map[float64]interface{}, canChange bool,
-	d *Decoder) (_ map[float64]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[float64]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk float64
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]string)
-		v, changed := fastpathTV.DecMapFloat64StringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64StringV(rv2i(rv).(map[float64]string), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64StringX(vp *map[float64]string, d *Decoder) {
-	v, changed := f.DecMapFloat64StringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64StringV(v map[float64]string, canChange bool,
-	d *Decoder) (_ map[float64]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[float64]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uint)
-		v, changed := fastpathTV.DecMapFloat64UintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64UintV(rv2i(rv).(map[float64]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64UintX(vp *map[float64]uint, d *Decoder) {
-	v, changed := f.DecMapFloat64UintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64UintV(v map[float64]uint, canChange bool,
-	d *Decoder) (_ map[float64]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[float64]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uint8)
-		v, changed := fastpathTV.DecMapFloat64Uint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64Uint8V(rv2i(rv).(map[float64]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64Uint8X(vp *map[float64]uint8, d *Decoder) {
-	v, changed := f.DecMapFloat64Uint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64Uint8V(v map[float64]uint8, canChange bool,
-	d *Decoder) (_ map[float64]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[float64]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uint16)
-		v, changed := fastpathTV.DecMapFloat64Uint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64Uint16V(rv2i(rv).(map[float64]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64Uint16X(vp *map[float64]uint16, d *Decoder) {
-	v, changed := f.DecMapFloat64Uint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64Uint16V(v map[float64]uint16, canChange bool,
-	d *Decoder) (_ map[float64]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[float64]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uint32)
-		v, changed := fastpathTV.DecMapFloat64Uint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64Uint32V(rv2i(rv).(map[float64]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64Uint32X(vp *map[float64]uint32, d *Decoder) {
-	v, changed := f.DecMapFloat64Uint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64Uint32V(v map[float64]uint32, canChange bool,
-	d *Decoder) (_ map[float64]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[float64]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uint64)
-		v, changed := fastpathTV.DecMapFloat64Uint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64Uint64V(rv2i(rv).(map[float64]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64Uint64X(vp *map[float64]uint64, d *Decoder) {
-	v, changed := f.DecMapFloat64Uint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64Uint64V(v map[float64]uint64, canChange bool,
-	d *Decoder) (_ map[float64]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[float64]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]uintptr)
-		v, changed := fastpathTV.DecMapFloat64UintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64UintptrV(rv2i(rv).(map[float64]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64UintptrX(vp *map[float64]uintptr, d *Decoder) {
-	v, changed := f.DecMapFloat64UintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64UintptrV(v map[float64]uintptr, canChange bool,
-	d *Decoder) (_ map[float64]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[float64]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]int)
-		v, changed := fastpathTV.DecMapFloat64IntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64IntV(rv2i(rv).(map[float64]int), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64IntX(vp *map[float64]int, d *Decoder) {
-	v, changed := f.DecMapFloat64IntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64IntV(v map[float64]int, canChange bool,
-	d *Decoder) (_ map[float64]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[float64]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]int8)
-		v, changed := fastpathTV.DecMapFloat64Int8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64Int8V(rv2i(rv).(map[float64]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64Int8X(vp *map[float64]int8, d *Decoder) {
-	v, changed := f.DecMapFloat64Int8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64Int8V(v map[float64]int8, canChange bool,
-	d *Decoder) (_ map[float64]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[float64]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]int16)
-		v, changed := fastpathTV.DecMapFloat64Int16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64Int16V(rv2i(rv).(map[float64]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64Int16X(vp *map[float64]int16, d *Decoder) {
-	v, changed := f.DecMapFloat64Int16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64Int16V(v map[float64]int16, canChange bool,
-	d *Decoder) (_ map[float64]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[float64]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]int32)
-		v, changed := fastpathTV.DecMapFloat64Int32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64Int32V(rv2i(rv).(map[float64]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64Int32X(vp *map[float64]int32, d *Decoder) {
-	v, changed := f.DecMapFloat64Int32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64Int32V(v map[float64]int32, canChange bool,
-	d *Decoder) (_ map[float64]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[float64]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]int64)
-		v, changed := fastpathTV.DecMapFloat64Int64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64Int64V(rv2i(rv).(map[float64]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64Int64X(vp *map[float64]int64, d *Decoder) {
-	v, changed := f.DecMapFloat64Int64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64Int64V(v map[float64]int64, canChange bool,
-	d *Decoder) (_ map[float64]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[float64]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]float32)
-		v, changed := fastpathTV.DecMapFloat64Float32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64Float32V(rv2i(rv).(map[float64]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64Float32X(vp *map[float64]float32, d *Decoder) {
-	v, changed := f.DecMapFloat64Float32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64Float32V(v map[float64]float32, canChange bool,
-	d *Decoder) (_ map[float64]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[float64]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]float64)
-		v, changed := fastpathTV.DecMapFloat64Float64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64Float64V(rv2i(rv).(map[float64]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64Float64X(vp *map[float64]float64, d *Decoder) {
-	v, changed := f.DecMapFloat64Float64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64Float64V(v map[float64]float64, canChange bool,
-	d *Decoder) (_ map[float64]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[float64]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapFloat64BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[float64]bool)
-		v, changed := fastpathTV.DecMapFloat64BoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapFloat64BoolV(rv2i(rv).(map[float64]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapFloat64BoolX(vp *map[float64]bool, d *Decoder) {
-	v, changed := f.DecMapFloat64BoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapFloat64BoolV(v map[float64]bool, canChange bool,
-	d *Decoder) (_ map[float64]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[float64]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk float64
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeFloat64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]interface{})
-		v, changed := fastpathTV.DecMapUintIntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintIntfV(rv2i(rv).(map[uint]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapUintIntfX(vp *map[uint]interface{}, d *Decoder) {
-	v, changed := f.DecMapUintIntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintIntfV(v map[uint]interface{}, canChange bool,
-	d *Decoder) (_ map[uint]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[uint]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk uint
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]string)
-		v, changed := fastpathTV.DecMapUintStringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintStringV(rv2i(rv).(map[uint]string), false, d)
-	}
-}
-func (f fastpathT) DecMapUintStringX(vp *map[uint]string, d *Decoder) {
-	v, changed := f.DecMapUintStringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintStringV(v map[uint]string, canChange bool,
-	d *Decoder) (_ map[uint]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[uint]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uint)
-		v, changed := fastpathTV.DecMapUintUintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintUintV(rv2i(rv).(map[uint]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapUintUintX(vp *map[uint]uint, d *Decoder) {
-	v, changed := f.DecMapUintUintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintUintV(v map[uint]uint, canChange bool,
-	d *Decoder) (_ map[uint]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uint8)
-		v, changed := fastpathTV.DecMapUintUint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintUint8V(rv2i(rv).(map[uint]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapUintUint8X(vp *map[uint]uint8, d *Decoder) {
-	v, changed := f.DecMapUintUint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintUint8V(v map[uint]uint8, canChange bool,
-	d *Decoder) (_ map[uint]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uint16)
-		v, changed := fastpathTV.DecMapUintUint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintUint16V(rv2i(rv).(map[uint]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapUintUint16X(vp *map[uint]uint16, d *Decoder) {
-	v, changed := f.DecMapUintUint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintUint16V(v map[uint]uint16, canChange bool,
-	d *Decoder) (_ map[uint]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uint]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uint32)
-		v, changed := fastpathTV.DecMapUintUint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintUint32V(rv2i(rv).(map[uint]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapUintUint32X(vp *map[uint]uint32, d *Decoder) {
-	v, changed := f.DecMapUintUint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintUint32V(v map[uint]uint32, canChange bool,
-	d *Decoder) (_ map[uint]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uint64)
-		v, changed := fastpathTV.DecMapUintUint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintUint64V(rv2i(rv).(map[uint]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapUintUint64X(vp *map[uint]uint64, d *Decoder) {
-	v, changed := f.DecMapUintUint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintUint64V(v map[uint]uint64, canChange bool,
-	d *Decoder) (_ map[uint]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]uintptr)
-		v, changed := fastpathTV.DecMapUintUintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintUintptrV(rv2i(rv).(map[uint]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapUintUintptrX(vp *map[uint]uintptr, d *Decoder) {
-	v, changed := f.DecMapUintUintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintUintptrV(v map[uint]uintptr, canChange bool,
-	d *Decoder) (_ map[uint]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]int)
-		v, changed := fastpathTV.DecMapUintIntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintIntV(rv2i(rv).(map[uint]int), false, d)
-	}
-}
-func (f fastpathT) DecMapUintIntX(vp *map[uint]int, d *Decoder) {
-	v, changed := f.DecMapUintIntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintIntV(v map[uint]int, canChange bool,
-	d *Decoder) (_ map[uint]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]int8)
-		v, changed := fastpathTV.DecMapUintInt8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintInt8V(rv2i(rv).(map[uint]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapUintInt8X(vp *map[uint]int8, d *Decoder) {
-	v, changed := f.DecMapUintInt8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintInt8V(v map[uint]int8, canChange bool,
-	d *Decoder) (_ map[uint]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]int16)
-		v, changed := fastpathTV.DecMapUintInt16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintInt16V(rv2i(rv).(map[uint]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapUintInt16X(vp *map[uint]int16, d *Decoder) {
-	v, changed := f.DecMapUintInt16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintInt16V(v map[uint]int16, canChange bool,
-	d *Decoder) (_ map[uint]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uint]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]int32)
-		v, changed := fastpathTV.DecMapUintInt32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintInt32V(rv2i(rv).(map[uint]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapUintInt32X(vp *map[uint]int32, d *Decoder) {
-	v, changed := f.DecMapUintInt32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintInt32V(v map[uint]int32, canChange bool,
-	d *Decoder) (_ map[uint]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]int64)
-		v, changed := fastpathTV.DecMapUintInt64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintInt64V(rv2i(rv).(map[uint]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapUintInt64X(vp *map[uint]int64, d *Decoder) {
-	v, changed := f.DecMapUintInt64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintInt64V(v map[uint]int64, canChange bool,
-	d *Decoder) (_ map[uint]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]float32)
-		v, changed := fastpathTV.DecMapUintFloat32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintFloat32V(rv2i(rv).(map[uint]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapUintFloat32X(vp *map[uint]float32, d *Decoder) {
-	v, changed := f.DecMapUintFloat32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintFloat32V(v map[uint]float32, canChange bool,
-	d *Decoder) (_ map[uint]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]float64)
-		v, changed := fastpathTV.DecMapUintFloat64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintFloat64V(rv2i(rv).(map[uint]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapUintFloat64X(vp *map[uint]float64, d *Decoder) {
-	v, changed := f.DecMapUintFloat64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintFloat64V(v map[uint]float64, canChange bool,
-	d *Decoder) (_ map[uint]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint]bool)
-		v, changed := fastpathTV.DecMapUintBoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintBoolV(rv2i(rv).(map[uint]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapUintBoolX(vp *map[uint]bool, d *Decoder) {
-	v, changed := f.DecMapUintBoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintBoolV(v map[uint]bool, canChange bool,
-	d *Decoder) (_ map[uint]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]interface{})
-		v, changed := fastpathTV.DecMapUint8IntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8IntfV(rv2i(rv).(map[uint8]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8IntfX(vp *map[uint8]interface{}, d *Decoder) {
-	v, changed := f.DecMapUint8IntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8IntfV(v map[uint8]interface{}, canChange bool,
-	d *Decoder) (_ map[uint8]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[uint8]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk uint8
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]string)
-		v, changed := fastpathTV.DecMapUint8StringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8StringV(rv2i(rv).(map[uint8]string), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8StringX(vp *map[uint8]string, d *Decoder) {
-	v, changed := f.DecMapUint8StringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8StringV(v map[uint8]string, canChange bool,
-	d *Decoder) (_ map[uint8]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[uint8]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uint)
-		v, changed := fastpathTV.DecMapUint8UintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8UintV(rv2i(rv).(map[uint8]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8UintX(vp *map[uint8]uint, d *Decoder) {
-	v, changed := f.DecMapUint8UintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8UintV(v map[uint8]uint, canChange bool,
-	d *Decoder) (_ map[uint8]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint8]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uint8)
-		v, changed := fastpathTV.DecMapUint8Uint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8Uint8V(rv2i(rv).(map[uint8]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8Uint8X(vp *map[uint8]uint8, d *Decoder) {
-	v, changed := f.DecMapUint8Uint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8Uint8V(v map[uint8]uint8, canChange bool,
-	d *Decoder) (_ map[uint8]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
-		v = make(map[uint8]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uint16)
-		v, changed := fastpathTV.DecMapUint8Uint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8Uint16V(rv2i(rv).(map[uint8]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8Uint16X(vp *map[uint8]uint16, d *Decoder) {
-	v, changed := f.DecMapUint8Uint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8Uint16V(v map[uint8]uint16, canChange bool,
-	d *Decoder) (_ map[uint8]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[uint8]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uint32)
-		v, changed := fastpathTV.DecMapUint8Uint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8Uint32V(rv2i(rv).(map[uint8]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8Uint32X(vp *map[uint8]uint32, d *Decoder) {
-	v, changed := f.DecMapUint8Uint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8Uint32V(v map[uint8]uint32, canChange bool,
-	d *Decoder) (_ map[uint8]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[uint8]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uint64)
-		v, changed := fastpathTV.DecMapUint8Uint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8Uint64V(rv2i(rv).(map[uint8]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8Uint64X(vp *map[uint8]uint64, d *Decoder) {
-	v, changed := f.DecMapUint8Uint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8Uint64V(v map[uint8]uint64, canChange bool,
-	d *Decoder) (_ map[uint8]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint8]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]uintptr)
-		v, changed := fastpathTV.DecMapUint8UintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8UintptrV(rv2i(rv).(map[uint8]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8UintptrX(vp *map[uint8]uintptr, d *Decoder) {
-	v, changed := f.DecMapUint8UintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8UintptrV(v map[uint8]uintptr, canChange bool,
-	d *Decoder) (_ map[uint8]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint8]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]int)
-		v, changed := fastpathTV.DecMapUint8IntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8IntV(rv2i(rv).(map[uint8]int), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8IntX(vp *map[uint8]int, d *Decoder) {
-	v, changed := f.DecMapUint8IntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8IntV(v map[uint8]int, canChange bool,
-	d *Decoder) (_ map[uint8]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint8]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]int8)
-		v, changed := fastpathTV.DecMapUint8Int8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8Int8V(rv2i(rv).(map[uint8]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8Int8X(vp *map[uint8]int8, d *Decoder) {
-	v, changed := f.DecMapUint8Int8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8Int8V(v map[uint8]int8, canChange bool,
-	d *Decoder) (_ map[uint8]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
-		v = make(map[uint8]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]int16)
-		v, changed := fastpathTV.DecMapUint8Int16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8Int16V(rv2i(rv).(map[uint8]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8Int16X(vp *map[uint8]int16, d *Decoder) {
-	v, changed := f.DecMapUint8Int16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8Int16V(v map[uint8]int16, canChange bool,
-	d *Decoder) (_ map[uint8]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[uint8]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]int32)
-		v, changed := fastpathTV.DecMapUint8Int32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8Int32V(rv2i(rv).(map[uint8]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8Int32X(vp *map[uint8]int32, d *Decoder) {
-	v, changed := f.DecMapUint8Int32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8Int32V(v map[uint8]int32, canChange bool,
-	d *Decoder) (_ map[uint8]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[uint8]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]int64)
-		v, changed := fastpathTV.DecMapUint8Int64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8Int64V(rv2i(rv).(map[uint8]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8Int64X(vp *map[uint8]int64, d *Decoder) {
-	v, changed := f.DecMapUint8Int64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8Int64V(v map[uint8]int64, canChange bool,
-	d *Decoder) (_ map[uint8]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint8]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]float32)
-		v, changed := fastpathTV.DecMapUint8Float32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8Float32V(rv2i(rv).(map[uint8]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8Float32X(vp *map[uint8]float32, d *Decoder) {
-	v, changed := f.DecMapUint8Float32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8Float32V(v map[uint8]float32, canChange bool,
-	d *Decoder) (_ map[uint8]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[uint8]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]float64)
-		v, changed := fastpathTV.DecMapUint8Float64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8Float64V(rv2i(rv).(map[uint8]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8Float64X(vp *map[uint8]float64, d *Decoder) {
-	v, changed := f.DecMapUint8Float64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8Float64V(v map[uint8]float64, canChange bool,
-	d *Decoder) (_ map[uint8]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint8]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint8BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint8]bool)
-		v, changed := fastpathTV.DecMapUint8BoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint8BoolV(rv2i(rv).(map[uint8]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapUint8BoolX(vp *map[uint8]bool, d *Decoder) {
-	v, changed := f.DecMapUint8BoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint8BoolV(v map[uint8]bool, canChange bool,
-	d *Decoder) (_ map[uint8]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
-		v = make(map[uint8]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint8
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]interface{})
-		v, changed := fastpathTV.DecMapUint16IntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16IntfV(rv2i(rv).(map[uint16]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16IntfX(vp *map[uint16]interface{}, d *Decoder) {
-	v, changed := f.DecMapUint16IntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16IntfV(v map[uint16]interface{}, canChange bool,
-	d *Decoder) (_ map[uint16]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
-		v = make(map[uint16]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk uint16
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]string)
-		v, changed := fastpathTV.DecMapUint16StringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16StringV(rv2i(rv).(map[uint16]string), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16StringX(vp *map[uint16]string, d *Decoder) {
-	v, changed := f.DecMapUint16StringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16StringV(v map[uint16]string, canChange bool,
-	d *Decoder) (_ map[uint16]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
-		v = make(map[uint16]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uint)
-		v, changed := fastpathTV.DecMapUint16UintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16UintV(rv2i(rv).(map[uint16]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16UintX(vp *map[uint16]uint, d *Decoder) {
-	v, changed := f.DecMapUint16UintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16UintV(v map[uint16]uint, canChange bool,
-	d *Decoder) (_ map[uint16]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uint16]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uint8)
-		v, changed := fastpathTV.DecMapUint16Uint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16Uint8V(rv2i(rv).(map[uint16]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16Uint8X(vp *map[uint16]uint8, d *Decoder) {
-	v, changed := f.DecMapUint16Uint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16Uint8V(v map[uint16]uint8, canChange bool,
-	d *Decoder) (_ map[uint16]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[uint16]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uint16)
-		v, changed := fastpathTV.DecMapUint16Uint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16Uint16V(rv2i(rv).(map[uint16]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16Uint16X(vp *map[uint16]uint16, d *Decoder) {
-	v, changed := f.DecMapUint16Uint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16Uint16V(v map[uint16]uint16, canChange bool,
-	d *Decoder) (_ map[uint16]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
-		v = make(map[uint16]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uint32)
-		v, changed := fastpathTV.DecMapUint16Uint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16Uint32V(rv2i(rv).(map[uint16]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16Uint32X(vp *map[uint16]uint32, d *Decoder) {
-	v, changed := f.DecMapUint16Uint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16Uint32V(v map[uint16]uint32, canChange bool,
-	d *Decoder) (_ map[uint16]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[uint16]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uint64)
-		v, changed := fastpathTV.DecMapUint16Uint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16Uint64V(rv2i(rv).(map[uint16]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16Uint64X(vp *map[uint16]uint64, d *Decoder) {
-	v, changed := f.DecMapUint16Uint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16Uint64V(v map[uint16]uint64, canChange bool,
-	d *Decoder) (_ map[uint16]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uint16]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]uintptr)
-		v, changed := fastpathTV.DecMapUint16UintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16UintptrV(rv2i(rv).(map[uint16]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16UintptrX(vp *map[uint16]uintptr, d *Decoder) {
-	v, changed := f.DecMapUint16UintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16UintptrV(v map[uint16]uintptr, canChange bool,
-	d *Decoder) (_ map[uint16]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uint16]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]int)
-		v, changed := fastpathTV.DecMapUint16IntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16IntV(rv2i(rv).(map[uint16]int), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16IntX(vp *map[uint16]int, d *Decoder) {
-	v, changed := f.DecMapUint16IntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16IntV(v map[uint16]int, canChange bool,
-	d *Decoder) (_ map[uint16]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uint16]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]int8)
-		v, changed := fastpathTV.DecMapUint16Int8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16Int8V(rv2i(rv).(map[uint16]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16Int8X(vp *map[uint16]int8, d *Decoder) {
-	v, changed := f.DecMapUint16Int8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16Int8V(v map[uint16]int8, canChange bool,
-	d *Decoder) (_ map[uint16]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[uint16]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]int16)
-		v, changed := fastpathTV.DecMapUint16Int16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16Int16V(rv2i(rv).(map[uint16]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16Int16X(vp *map[uint16]int16, d *Decoder) {
-	v, changed := f.DecMapUint16Int16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16Int16V(v map[uint16]int16, canChange bool,
-	d *Decoder) (_ map[uint16]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
-		v = make(map[uint16]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]int32)
-		v, changed := fastpathTV.DecMapUint16Int32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16Int32V(rv2i(rv).(map[uint16]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16Int32X(vp *map[uint16]int32, d *Decoder) {
-	v, changed := f.DecMapUint16Int32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16Int32V(v map[uint16]int32, canChange bool,
-	d *Decoder) (_ map[uint16]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[uint16]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]int64)
-		v, changed := fastpathTV.DecMapUint16Int64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16Int64V(rv2i(rv).(map[uint16]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16Int64X(vp *map[uint16]int64, d *Decoder) {
-	v, changed := f.DecMapUint16Int64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16Int64V(v map[uint16]int64, canChange bool,
-	d *Decoder) (_ map[uint16]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uint16]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]float32)
-		v, changed := fastpathTV.DecMapUint16Float32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16Float32V(rv2i(rv).(map[uint16]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16Float32X(vp *map[uint16]float32, d *Decoder) {
-	v, changed := f.DecMapUint16Float32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16Float32V(v map[uint16]float32, canChange bool,
-	d *Decoder) (_ map[uint16]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[uint16]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]float64)
-		v, changed := fastpathTV.DecMapUint16Float64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16Float64V(rv2i(rv).(map[uint16]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16Float64X(vp *map[uint16]float64, d *Decoder) {
-	v, changed := f.DecMapUint16Float64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16Float64V(v map[uint16]float64, canChange bool,
-	d *Decoder) (_ map[uint16]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uint16]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint16BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint16]bool)
-		v, changed := fastpathTV.DecMapUint16BoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint16BoolV(rv2i(rv).(map[uint16]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapUint16BoolX(vp *map[uint16]bool, d *Decoder) {
-	v, changed := f.DecMapUint16BoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint16BoolV(v map[uint16]bool, canChange bool,
-	d *Decoder) (_ map[uint16]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[uint16]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint16
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]interface{})
-		v, changed := fastpathTV.DecMapUint32IntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32IntfV(rv2i(rv).(map[uint32]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32IntfX(vp *map[uint32]interface{}, d *Decoder) {
-	v, changed := f.DecMapUint32IntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32IntfV(v map[uint32]interface{}, canChange bool,
-	d *Decoder) (_ map[uint32]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[uint32]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk uint32
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]string)
-		v, changed := fastpathTV.DecMapUint32StringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32StringV(rv2i(rv).(map[uint32]string), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32StringX(vp *map[uint32]string, d *Decoder) {
-	v, changed := f.DecMapUint32StringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32StringV(v map[uint32]string, canChange bool,
-	d *Decoder) (_ map[uint32]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[uint32]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uint)
-		v, changed := fastpathTV.DecMapUint32UintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32UintV(rv2i(rv).(map[uint32]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32UintX(vp *map[uint32]uint, d *Decoder) {
-	v, changed := f.DecMapUint32UintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32UintV(v map[uint32]uint, canChange bool,
-	d *Decoder) (_ map[uint32]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint32]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uint8)
-		v, changed := fastpathTV.DecMapUint32Uint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32Uint8V(rv2i(rv).(map[uint32]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32Uint8X(vp *map[uint32]uint8, d *Decoder) {
-	v, changed := f.DecMapUint32Uint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32Uint8V(v map[uint32]uint8, canChange bool,
-	d *Decoder) (_ map[uint32]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[uint32]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uint16)
-		v, changed := fastpathTV.DecMapUint32Uint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32Uint16V(rv2i(rv).(map[uint32]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32Uint16X(vp *map[uint32]uint16, d *Decoder) {
-	v, changed := f.DecMapUint32Uint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32Uint16V(v map[uint32]uint16, canChange bool,
-	d *Decoder) (_ map[uint32]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[uint32]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uint32)
-		v, changed := fastpathTV.DecMapUint32Uint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32Uint32V(rv2i(rv).(map[uint32]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32Uint32X(vp *map[uint32]uint32, d *Decoder) {
-	v, changed := f.DecMapUint32Uint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32Uint32V(v map[uint32]uint32, canChange bool,
-	d *Decoder) (_ map[uint32]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
-		v = make(map[uint32]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uint64)
-		v, changed := fastpathTV.DecMapUint32Uint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32Uint64V(rv2i(rv).(map[uint32]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32Uint64X(vp *map[uint32]uint64, d *Decoder) {
-	v, changed := f.DecMapUint32Uint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32Uint64V(v map[uint32]uint64, canChange bool,
-	d *Decoder) (_ map[uint32]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint32]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]uintptr)
-		v, changed := fastpathTV.DecMapUint32UintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32UintptrV(rv2i(rv).(map[uint32]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32UintptrX(vp *map[uint32]uintptr, d *Decoder) {
-	v, changed := f.DecMapUint32UintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32UintptrV(v map[uint32]uintptr, canChange bool,
-	d *Decoder) (_ map[uint32]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint32]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]int)
-		v, changed := fastpathTV.DecMapUint32IntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32IntV(rv2i(rv).(map[uint32]int), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32IntX(vp *map[uint32]int, d *Decoder) {
-	v, changed := f.DecMapUint32IntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32IntV(v map[uint32]int, canChange bool,
-	d *Decoder) (_ map[uint32]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint32]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]int8)
-		v, changed := fastpathTV.DecMapUint32Int8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32Int8V(rv2i(rv).(map[uint32]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32Int8X(vp *map[uint32]int8, d *Decoder) {
-	v, changed := f.DecMapUint32Int8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32Int8V(v map[uint32]int8, canChange bool,
-	d *Decoder) (_ map[uint32]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[uint32]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]int16)
-		v, changed := fastpathTV.DecMapUint32Int16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32Int16V(rv2i(rv).(map[uint32]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32Int16X(vp *map[uint32]int16, d *Decoder) {
-	v, changed := f.DecMapUint32Int16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32Int16V(v map[uint32]int16, canChange bool,
-	d *Decoder) (_ map[uint32]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[uint32]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]int32)
-		v, changed := fastpathTV.DecMapUint32Int32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32Int32V(rv2i(rv).(map[uint32]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32Int32X(vp *map[uint32]int32, d *Decoder) {
-	v, changed := f.DecMapUint32Int32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32Int32V(v map[uint32]int32, canChange bool,
-	d *Decoder) (_ map[uint32]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
-		v = make(map[uint32]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]int64)
-		v, changed := fastpathTV.DecMapUint32Int64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32Int64V(rv2i(rv).(map[uint32]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32Int64X(vp *map[uint32]int64, d *Decoder) {
-	v, changed := f.DecMapUint32Int64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32Int64V(v map[uint32]int64, canChange bool,
-	d *Decoder) (_ map[uint32]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint32]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]float32)
-		v, changed := fastpathTV.DecMapUint32Float32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32Float32V(rv2i(rv).(map[uint32]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32Float32X(vp *map[uint32]float32, d *Decoder) {
-	v, changed := f.DecMapUint32Float32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32Float32V(v map[uint32]float32, canChange bool,
-	d *Decoder) (_ map[uint32]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
-		v = make(map[uint32]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]float64)
-		v, changed := fastpathTV.DecMapUint32Float64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32Float64V(rv2i(rv).(map[uint32]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32Float64X(vp *map[uint32]float64, d *Decoder) {
-	v, changed := f.DecMapUint32Float64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32Float64V(v map[uint32]float64, canChange bool,
-	d *Decoder) (_ map[uint32]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint32]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint32BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint32]bool)
-		v, changed := fastpathTV.DecMapUint32BoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint32BoolV(rv2i(rv).(map[uint32]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapUint32BoolX(vp *map[uint32]bool, d *Decoder) {
-	v, changed := f.DecMapUint32BoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint32BoolV(v map[uint32]bool, canChange bool,
-	d *Decoder) (_ map[uint32]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[uint32]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint32
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]interface{})
-		v, changed := fastpathTV.DecMapUint64IntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64IntfV(rv2i(rv).(map[uint64]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64IntfX(vp *map[uint64]interface{}, d *Decoder) {
-	v, changed := f.DecMapUint64IntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64IntfV(v map[uint64]interface{}, canChange bool,
-	d *Decoder) (_ map[uint64]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[uint64]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk uint64
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]string)
-		v, changed := fastpathTV.DecMapUint64StringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64StringV(rv2i(rv).(map[uint64]string), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64StringX(vp *map[uint64]string, d *Decoder) {
-	v, changed := f.DecMapUint64StringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64StringV(v map[uint64]string, canChange bool,
-	d *Decoder) (_ map[uint64]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[uint64]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uint)
-		v, changed := fastpathTV.DecMapUint64UintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64UintV(rv2i(rv).(map[uint64]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64UintX(vp *map[uint64]uint, d *Decoder) {
-	v, changed := f.DecMapUint64UintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64UintV(v map[uint64]uint, canChange bool,
-	d *Decoder) (_ map[uint64]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint64]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uint8)
-		v, changed := fastpathTV.DecMapUint64Uint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64Uint8V(rv2i(rv).(map[uint64]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64Uint8X(vp *map[uint64]uint8, d *Decoder) {
-	v, changed := f.DecMapUint64Uint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64Uint8V(v map[uint64]uint8, canChange bool,
-	d *Decoder) (_ map[uint64]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint64]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uint16)
-		v, changed := fastpathTV.DecMapUint64Uint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64Uint16V(rv2i(rv).(map[uint64]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64Uint16X(vp *map[uint64]uint16, d *Decoder) {
-	v, changed := f.DecMapUint64Uint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64Uint16V(v map[uint64]uint16, canChange bool,
-	d *Decoder) (_ map[uint64]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uint64]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uint32)
-		v, changed := fastpathTV.DecMapUint64Uint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64Uint32V(rv2i(rv).(map[uint64]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64Uint32X(vp *map[uint64]uint32, d *Decoder) {
-	v, changed := f.DecMapUint64Uint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64Uint32V(v map[uint64]uint32, canChange bool,
-	d *Decoder) (_ map[uint64]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint64]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uint64)
-		v, changed := fastpathTV.DecMapUint64Uint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64Uint64V(rv2i(rv).(map[uint64]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64Uint64X(vp *map[uint64]uint64, d *Decoder) {
-	v, changed := f.DecMapUint64Uint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64Uint64V(v map[uint64]uint64, canChange bool,
-	d *Decoder) (_ map[uint64]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint64]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]uintptr)
-		v, changed := fastpathTV.DecMapUint64UintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64UintptrV(rv2i(rv).(map[uint64]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64UintptrX(vp *map[uint64]uintptr, d *Decoder) {
-	v, changed := f.DecMapUint64UintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64UintptrV(v map[uint64]uintptr, canChange bool,
-	d *Decoder) (_ map[uint64]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint64]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]int)
-		v, changed := fastpathTV.DecMapUint64IntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64IntV(rv2i(rv).(map[uint64]int), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64IntX(vp *map[uint64]int, d *Decoder) {
-	v, changed := f.DecMapUint64IntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64IntV(v map[uint64]int, canChange bool,
-	d *Decoder) (_ map[uint64]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint64]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]int8)
-		v, changed := fastpathTV.DecMapUint64Int8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64Int8V(rv2i(rv).(map[uint64]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64Int8X(vp *map[uint64]int8, d *Decoder) {
-	v, changed := f.DecMapUint64Int8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64Int8V(v map[uint64]int8, canChange bool,
-	d *Decoder) (_ map[uint64]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint64]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]int16)
-		v, changed := fastpathTV.DecMapUint64Int16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64Int16V(rv2i(rv).(map[uint64]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64Int16X(vp *map[uint64]int16, d *Decoder) {
-	v, changed := f.DecMapUint64Int16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64Int16V(v map[uint64]int16, canChange bool,
-	d *Decoder) (_ map[uint64]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uint64]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]int32)
-		v, changed := fastpathTV.DecMapUint64Int32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64Int32V(rv2i(rv).(map[uint64]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64Int32X(vp *map[uint64]int32, d *Decoder) {
-	v, changed := f.DecMapUint64Int32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64Int32V(v map[uint64]int32, canChange bool,
-	d *Decoder) (_ map[uint64]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint64]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]int64)
-		v, changed := fastpathTV.DecMapUint64Int64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64Int64V(rv2i(rv).(map[uint64]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64Int64X(vp *map[uint64]int64, d *Decoder) {
-	v, changed := f.DecMapUint64Int64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64Int64V(v map[uint64]int64, canChange bool,
-	d *Decoder) (_ map[uint64]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint64]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]float32)
-		v, changed := fastpathTV.DecMapUint64Float32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64Float32V(rv2i(rv).(map[uint64]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64Float32X(vp *map[uint64]float32, d *Decoder) {
-	v, changed := f.DecMapUint64Float32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64Float32V(v map[uint64]float32, canChange bool,
-	d *Decoder) (_ map[uint64]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uint64]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]float64)
-		v, changed := fastpathTV.DecMapUint64Float64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64Float64V(rv2i(rv).(map[uint64]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64Float64X(vp *map[uint64]float64, d *Decoder) {
-	v, changed := f.DecMapUint64Float64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64Float64V(v map[uint64]float64, canChange bool,
-	d *Decoder) (_ map[uint64]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uint64]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUint64BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uint64]bool)
-		v, changed := fastpathTV.DecMapUint64BoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUint64BoolV(rv2i(rv).(map[uint64]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapUint64BoolX(vp *map[uint64]bool, d *Decoder) {
-	v, changed := f.DecMapUint64BoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUint64BoolV(v map[uint64]bool, canChange bool,
-	d *Decoder) (_ map[uint64]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uint64]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uint64
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeUint64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]interface{})
-		v, changed := fastpathTV.DecMapUintptrIntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrIntfV(rv2i(rv).(map[uintptr]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrIntfX(vp *map[uintptr]interface{}, d *Decoder) {
-	v, changed := f.DecMapUintptrIntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrIntfV(v map[uintptr]interface{}, canChange bool,
-	d *Decoder) (_ map[uintptr]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[uintptr]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk uintptr
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]string)
-		v, changed := fastpathTV.DecMapUintptrStringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrStringV(rv2i(rv).(map[uintptr]string), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrStringX(vp *map[uintptr]string, d *Decoder) {
-	v, changed := f.DecMapUintptrStringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrStringV(v map[uintptr]string, canChange bool,
-	d *Decoder) (_ map[uintptr]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[uintptr]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uint)
-		v, changed := fastpathTV.DecMapUintptrUintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrUintV(rv2i(rv).(map[uintptr]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrUintX(vp *map[uintptr]uint, d *Decoder) {
-	v, changed := f.DecMapUintptrUintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrUintV(v map[uintptr]uint, canChange bool,
-	d *Decoder) (_ map[uintptr]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uintptr]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uint8)
-		v, changed := fastpathTV.DecMapUintptrUint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrUint8V(rv2i(rv).(map[uintptr]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrUint8X(vp *map[uintptr]uint8, d *Decoder) {
-	v, changed := f.DecMapUintptrUint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrUint8V(v map[uintptr]uint8, canChange bool,
-	d *Decoder) (_ map[uintptr]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uintptr]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uint16)
-		v, changed := fastpathTV.DecMapUintptrUint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrUint16V(rv2i(rv).(map[uintptr]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrUint16X(vp *map[uintptr]uint16, d *Decoder) {
-	v, changed := f.DecMapUintptrUint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrUint16V(v map[uintptr]uint16, canChange bool,
-	d *Decoder) (_ map[uintptr]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uintptr]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uint32)
-		v, changed := fastpathTV.DecMapUintptrUint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrUint32V(rv2i(rv).(map[uintptr]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrUint32X(vp *map[uintptr]uint32, d *Decoder) {
-	v, changed := f.DecMapUintptrUint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrUint32V(v map[uintptr]uint32, canChange bool,
-	d *Decoder) (_ map[uintptr]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uintptr]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uint64)
-		v, changed := fastpathTV.DecMapUintptrUint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrUint64V(rv2i(rv).(map[uintptr]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrUint64X(vp *map[uintptr]uint64, d *Decoder) {
-	v, changed := f.DecMapUintptrUint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrUint64V(v map[uintptr]uint64, canChange bool,
-	d *Decoder) (_ map[uintptr]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uintptr]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]uintptr)
-		v, changed := fastpathTV.DecMapUintptrUintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrUintptrV(rv2i(rv).(map[uintptr]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrUintptrX(vp *map[uintptr]uintptr, d *Decoder) {
-	v, changed := f.DecMapUintptrUintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrUintptrV(v map[uintptr]uintptr, canChange bool,
-	d *Decoder) (_ map[uintptr]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uintptr]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]int)
-		v, changed := fastpathTV.DecMapUintptrIntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrIntV(rv2i(rv).(map[uintptr]int), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrIntX(vp *map[uintptr]int, d *Decoder) {
-	v, changed := f.DecMapUintptrIntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrIntV(v map[uintptr]int, canChange bool,
-	d *Decoder) (_ map[uintptr]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uintptr]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]int8)
-		v, changed := fastpathTV.DecMapUintptrInt8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrInt8V(rv2i(rv).(map[uintptr]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrInt8X(vp *map[uintptr]int8, d *Decoder) {
-	v, changed := f.DecMapUintptrInt8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrInt8V(v map[uintptr]int8, canChange bool,
-	d *Decoder) (_ map[uintptr]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uintptr]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]int16)
-		v, changed := fastpathTV.DecMapUintptrInt16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrInt16V(rv2i(rv).(map[uintptr]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrInt16X(vp *map[uintptr]int16, d *Decoder) {
-	v, changed := f.DecMapUintptrInt16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrInt16V(v map[uintptr]int16, canChange bool,
-	d *Decoder) (_ map[uintptr]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[uintptr]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]int32)
-		v, changed := fastpathTV.DecMapUintptrInt32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrInt32V(rv2i(rv).(map[uintptr]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrInt32X(vp *map[uintptr]int32, d *Decoder) {
-	v, changed := f.DecMapUintptrInt32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrInt32V(v map[uintptr]int32, canChange bool,
-	d *Decoder) (_ map[uintptr]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uintptr]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]int64)
-		v, changed := fastpathTV.DecMapUintptrInt64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrInt64V(rv2i(rv).(map[uintptr]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrInt64X(vp *map[uintptr]int64, d *Decoder) {
-	v, changed := f.DecMapUintptrInt64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrInt64V(v map[uintptr]int64, canChange bool,
-	d *Decoder) (_ map[uintptr]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uintptr]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]float32)
-		v, changed := fastpathTV.DecMapUintptrFloat32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrFloat32V(rv2i(rv).(map[uintptr]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrFloat32X(vp *map[uintptr]float32, d *Decoder) {
-	v, changed := f.DecMapUintptrFloat32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrFloat32V(v map[uintptr]float32, canChange bool,
-	d *Decoder) (_ map[uintptr]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[uintptr]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]float64)
-		v, changed := fastpathTV.DecMapUintptrFloat64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrFloat64V(rv2i(rv).(map[uintptr]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrFloat64X(vp *map[uintptr]float64, d *Decoder) {
-	v, changed := f.DecMapUintptrFloat64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrFloat64V(v map[uintptr]float64, canChange bool,
-	d *Decoder) (_ map[uintptr]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[uintptr]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapUintptrBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[uintptr]bool)
-		v, changed := fastpathTV.DecMapUintptrBoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapUintptrBoolV(rv2i(rv).(map[uintptr]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapUintptrBoolX(vp *map[uintptr]bool, d *Decoder) {
-	v, changed := f.DecMapUintptrBoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapUintptrBoolV(v map[uintptr]bool, canChange bool,
-	d *Decoder) (_ map[uintptr]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[uintptr]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk uintptr
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]interface{})
-		v, changed := fastpathTV.DecMapIntIntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntIntfV(rv2i(rv).(map[int]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapIntIntfX(vp *map[int]interface{}, d *Decoder) {
-	v, changed := f.DecMapIntIntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntIntfV(v map[int]interface{}, canChange bool,
-	d *Decoder) (_ map[int]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[int]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk int
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]string)
-		v, changed := fastpathTV.DecMapIntStringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntStringV(rv2i(rv).(map[int]string), false, d)
-	}
-}
-func (f fastpathT) DecMapIntStringX(vp *map[int]string, d *Decoder) {
-	v, changed := f.DecMapIntStringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntStringV(v map[int]string, canChange bool,
-	d *Decoder) (_ map[int]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[int]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uint)
-		v, changed := fastpathTV.DecMapIntUintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntUintV(rv2i(rv).(map[int]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapIntUintX(vp *map[int]uint, d *Decoder) {
-	v, changed := f.DecMapIntUintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntUintV(v map[int]uint, canChange bool,
-	d *Decoder) (_ map[int]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uint8)
-		v, changed := fastpathTV.DecMapIntUint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntUint8V(rv2i(rv).(map[int]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapIntUint8X(vp *map[int]uint8, d *Decoder) {
-	v, changed := f.DecMapIntUint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntUint8V(v map[int]uint8, canChange bool,
-	d *Decoder) (_ map[int]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uint16)
-		v, changed := fastpathTV.DecMapIntUint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntUint16V(rv2i(rv).(map[int]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapIntUint16X(vp *map[int]uint16, d *Decoder) {
-	v, changed := f.DecMapIntUint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntUint16V(v map[int]uint16, canChange bool,
-	d *Decoder) (_ map[int]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[int]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uint32)
-		v, changed := fastpathTV.DecMapIntUint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntUint32V(rv2i(rv).(map[int]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapIntUint32X(vp *map[int]uint32, d *Decoder) {
-	v, changed := f.DecMapIntUint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntUint32V(v map[int]uint32, canChange bool,
-	d *Decoder) (_ map[int]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uint64)
-		v, changed := fastpathTV.DecMapIntUint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntUint64V(rv2i(rv).(map[int]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapIntUint64X(vp *map[int]uint64, d *Decoder) {
-	v, changed := f.DecMapIntUint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntUint64V(v map[int]uint64, canChange bool,
-	d *Decoder) (_ map[int]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]uintptr)
-		v, changed := fastpathTV.DecMapIntUintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntUintptrV(rv2i(rv).(map[int]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapIntUintptrX(vp *map[int]uintptr, d *Decoder) {
-	v, changed := f.DecMapIntUintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntUintptrV(v map[int]uintptr, canChange bool,
-	d *Decoder) (_ map[int]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]int)
-		v, changed := fastpathTV.DecMapIntIntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntIntV(rv2i(rv).(map[int]int), false, d)
-	}
-}
-func (f fastpathT) DecMapIntIntX(vp *map[int]int, d *Decoder) {
-	v, changed := f.DecMapIntIntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntIntV(v map[int]int, canChange bool,
-	d *Decoder) (_ map[int]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]int8)
-		v, changed := fastpathTV.DecMapIntInt8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntInt8V(rv2i(rv).(map[int]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapIntInt8X(vp *map[int]int8, d *Decoder) {
-	v, changed := f.DecMapIntInt8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntInt8V(v map[int]int8, canChange bool,
-	d *Decoder) (_ map[int]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]int16)
-		v, changed := fastpathTV.DecMapIntInt16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntInt16V(rv2i(rv).(map[int]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapIntInt16X(vp *map[int]int16, d *Decoder) {
-	v, changed := f.DecMapIntInt16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntInt16V(v map[int]int16, canChange bool,
-	d *Decoder) (_ map[int]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[int]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]int32)
-		v, changed := fastpathTV.DecMapIntInt32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntInt32V(rv2i(rv).(map[int]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapIntInt32X(vp *map[int]int32, d *Decoder) {
-	v, changed := f.DecMapIntInt32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntInt32V(v map[int]int32, canChange bool,
-	d *Decoder) (_ map[int]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]int64)
-		v, changed := fastpathTV.DecMapIntInt64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntInt64V(rv2i(rv).(map[int]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapIntInt64X(vp *map[int]int64, d *Decoder) {
-	v, changed := f.DecMapIntInt64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntInt64V(v map[int]int64, canChange bool,
-	d *Decoder) (_ map[int]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]float32)
-		v, changed := fastpathTV.DecMapIntFloat32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntFloat32V(rv2i(rv).(map[int]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapIntFloat32X(vp *map[int]float32, d *Decoder) {
-	v, changed := f.DecMapIntFloat32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntFloat32V(v map[int]float32, canChange bool,
-	d *Decoder) (_ map[int]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]float64)
-		v, changed := fastpathTV.DecMapIntFloat64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntFloat64V(rv2i(rv).(map[int]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapIntFloat64X(vp *map[int]float64, d *Decoder) {
-	v, changed := f.DecMapIntFloat64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntFloat64V(v map[int]float64, canChange bool,
-	d *Decoder) (_ map[int]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapIntBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int]bool)
-		v, changed := fastpathTV.DecMapIntBoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapIntBoolV(rv2i(rv).(map[int]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapIntBoolX(vp *map[int]bool, d *Decoder) {
-	v, changed := f.DecMapIntBoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapIntBoolV(v map[int]bool, canChange bool,
-	d *Decoder) (_ map[int]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]interface{})
-		v, changed := fastpathTV.DecMapInt8IntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8IntfV(rv2i(rv).(map[int8]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8IntfX(vp *map[int8]interface{}, d *Decoder) {
-	v, changed := f.DecMapInt8IntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8IntfV(v map[int8]interface{}, canChange bool,
-	d *Decoder) (_ map[int8]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[int8]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk int8
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]string)
-		v, changed := fastpathTV.DecMapInt8StringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8StringV(rv2i(rv).(map[int8]string), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8StringX(vp *map[int8]string, d *Decoder) {
-	v, changed := f.DecMapInt8StringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8StringV(v map[int8]string, canChange bool,
-	d *Decoder) (_ map[int8]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[int8]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uint)
-		v, changed := fastpathTV.DecMapInt8UintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8UintV(rv2i(rv).(map[int8]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8UintX(vp *map[int8]uint, d *Decoder) {
-	v, changed := f.DecMapInt8UintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8UintV(v map[int8]uint, canChange bool,
-	d *Decoder) (_ map[int8]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int8]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uint8)
-		v, changed := fastpathTV.DecMapInt8Uint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8Uint8V(rv2i(rv).(map[int8]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8Uint8X(vp *map[int8]uint8, d *Decoder) {
-	v, changed := f.DecMapInt8Uint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8Uint8V(v map[int8]uint8, canChange bool,
-	d *Decoder) (_ map[int8]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
-		v = make(map[int8]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uint16)
-		v, changed := fastpathTV.DecMapInt8Uint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8Uint16V(rv2i(rv).(map[int8]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8Uint16X(vp *map[int8]uint16, d *Decoder) {
-	v, changed := f.DecMapInt8Uint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8Uint16V(v map[int8]uint16, canChange bool,
-	d *Decoder) (_ map[int8]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[int8]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uint32)
-		v, changed := fastpathTV.DecMapInt8Uint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8Uint32V(rv2i(rv).(map[int8]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8Uint32X(vp *map[int8]uint32, d *Decoder) {
-	v, changed := f.DecMapInt8Uint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8Uint32V(v map[int8]uint32, canChange bool,
-	d *Decoder) (_ map[int8]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[int8]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uint64)
-		v, changed := fastpathTV.DecMapInt8Uint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8Uint64V(rv2i(rv).(map[int8]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8Uint64X(vp *map[int8]uint64, d *Decoder) {
-	v, changed := f.DecMapInt8Uint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8Uint64V(v map[int8]uint64, canChange bool,
-	d *Decoder) (_ map[int8]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int8]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]uintptr)
-		v, changed := fastpathTV.DecMapInt8UintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8UintptrV(rv2i(rv).(map[int8]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8UintptrX(vp *map[int8]uintptr, d *Decoder) {
-	v, changed := f.DecMapInt8UintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8UintptrV(v map[int8]uintptr, canChange bool,
-	d *Decoder) (_ map[int8]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int8]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]int)
-		v, changed := fastpathTV.DecMapInt8IntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8IntV(rv2i(rv).(map[int8]int), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8IntX(vp *map[int8]int, d *Decoder) {
-	v, changed := f.DecMapInt8IntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8IntV(v map[int8]int, canChange bool,
-	d *Decoder) (_ map[int8]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int8]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]int8)
-		v, changed := fastpathTV.DecMapInt8Int8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8Int8V(rv2i(rv).(map[int8]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8Int8X(vp *map[int8]int8, d *Decoder) {
-	v, changed := f.DecMapInt8Int8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8Int8V(v map[int8]int8, canChange bool,
-	d *Decoder) (_ map[int8]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
-		v = make(map[int8]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]int16)
-		v, changed := fastpathTV.DecMapInt8Int16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8Int16V(rv2i(rv).(map[int8]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8Int16X(vp *map[int8]int16, d *Decoder) {
-	v, changed := f.DecMapInt8Int16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8Int16V(v map[int8]int16, canChange bool,
-	d *Decoder) (_ map[int8]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[int8]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]int32)
-		v, changed := fastpathTV.DecMapInt8Int32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8Int32V(rv2i(rv).(map[int8]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8Int32X(vp *map[int8]int32, d *Decoder) {
-	v, changed := f.DecMapInt8Int32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8Int32V(v map[int8]int32, canChange bool,
-	d *Decoder) (_ map[int8]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[int8]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]int64)
-		v, changed := fastpathTV.DecMapInt8Int64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8Int64V(rv2i(rv).(map[int8]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8Int64X(vp *map[int8]int64, d *Decoder) {
-	v, changed := f.DecMapInt8Int64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8Int64V(v map[int8]int64, canChange bool,
-	d *Decoder) (_ map[int8]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int8]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]float32)
-		v, changed := fastpathTV.DecMapInt8Float32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8Float32V(rv2i(rv).(map[int8]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8Float32X(vp *map[int8]float32, d *Decoder) {
-	v, changed := f.DecMapInt8Float32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8Float32V(v map[int8]float32, canChange bool,
-	d *Decoder) (_ map[int8]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[int8]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]float64)
-		v, changed := fastpathTV.DecMapInt8Float64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8Float64V(rv2i(rv).(map[int8]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8Float64X(vp *map[int8]float64, d *Decoder) {
-	v, changed := f.DecMapInt8Float64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8Float64V(v map[int8]float64, canChange bool,
-	d *Decoder) (_ map[int8]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int8]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt8BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int8]bool)
-		v, changed := fastpathTV.DecMapInt8BoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt8BoolV(rv2i(rv).(map[int8]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapInt8BoolX(vp *map[int8]bool, d *Decoder) {
-	v, changed := f.DecMapInt8BoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt8BoolV(v map[int8]bool, canChange bool,
-	d *Decoder) (_ map[int8]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
-		v = make(map[int8]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int8
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]interface{})
-		v, changed := fastpathTV.DecMapInt16IntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16IntfV(rv2i(rv).(map[int16]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16IntfX(vp *map[int16]interface{}, d *Decoder) {
-	v, changed := f.DecMapInt16IntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16IntfV(v map[int16]interface{}, canChange bool,
-	d *Decoder) (_ map[int16]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
-		v = make(map[int16]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk int16
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]string)
-		v, changed := fastpathTV.DecMapInt16StringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16StringV(rv2i(rv).(map[int16]string), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16StringX(vp *map[int16]string, d *Decoder) {
-	v, changed := f.DecMapInt16StringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16StringV(v map[int16]string, canChange bool,
-	d *Decoder) (_ map[int16]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
-		v = make(map[int16]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uint)
-		v, changed := fastpathTV.DecMapInt16UintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16UintV(rv2i(rv).(map[int16]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16UintX(vp *map[int16]uint, d *Decoder) {
-	v, changed := f.DecMapInt16UintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16UintV(v map[int16]uint, canChange bool,
-	d *Decoder) (_ map[int16]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[int16]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uint8)
-		v, changed := fastpathTV.DecMapInt16Uint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16Uint8V(rv2i(rv).(map[int16]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16Uint8X(vp *map[int16]uint8, d *Decoder) {
-	v, changed := f.DecMapInt16Uint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16Uint8V(v map[int16]uint8, canChange bool,
-	d *Decoder) (_ map[int16]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[int16]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uint16)
-		v, changed := fastpathTV.DecMapInt16Uint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16Uint16V(rv2i(rv).(map[int16]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16Uint16X(vp *map[int16]uint16, d *Decoder) {
-	v, changed := f.DecMapInt16Uint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16Uint16V(v map[int16]uint16, canChange bool,
-	d *Decoder) (_ map[int16]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
-		v = make(map[int16]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uint32)
-		v, changed := fastpathTV.DecMapInt16Uint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16Uint32V(rv2i(rv).(map[int16]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16Uint32X(vp *map[int16]uint32, d *Decoder) {
-	v, changed := f.DecMapInt16Uint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16Uint32V(v map[int16]uint32, canChange bool,
-	d *Decoder) (_ map[int16]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[int16]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uint64)
-		v, changed := fastpathTV.DecMapInt16Uint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16Uint64V(rv2i(rv).(map[int16]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16Uint64X(vp *map[int16]uint64, d *Decoder) {
-	v, changed := f.DecMapInt16Uint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16Uint64V(v map[int16]uint64, canChange bool,
-	d *Decoder) (_ map[int16]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[int16]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]uintptr)
-		v, changed := fastpathTV.DecMapInt16UintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16UintptrV(rv2i(rv).(map[int16]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16UintptrX(vp *map[int16]uintptr, d *Decoder) {
-	v, changed := f.DecMapInt16UintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16UintptrV(v map[int16]uintptr, canChange bool,
-	d *Decoder) (_ map[int16]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[int16]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]int)
-		v, changed := fastpathTV.DecMapInt16IntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16IntV(rv2i(rv).(map[int16]int), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16IntX(vp *map[int16]int, d *Decoder) {
-	v, changed := f.DecMapInt16IntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16IntV(v map[int16]int, canChange bool,
-	d *Decoder) (_ map[int16]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[int16]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]int8)
-		v, changed := fastpathTV.DecMapInt16Int8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16Int8V(rv2i(rv).(map[int16]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16Int8X(vp *map[int16]int8, d *Decoder) {
-	v, changed := f.DecMapInt16Int8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16Int8V(v map[int16]int8, canChange bool,
-	d *Decoder) (_ map[int16]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[int16]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]int16)
-		v, changed := fastpathTV.DecMapInt16Int16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16Int16V(rv2i(rv).(map[int16]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16Int16X(vp *map[int16]int16, d *Decoder) {
-	v, changed := f.DecMapInt16Int16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16Int16V(v map[int16]int16, canChange bool,
-	d *Decoder) (_ map[int16]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
-		v = make(map[int16]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]int32)
-		v, changed := fastpathTV.DecMapInt16Int32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16Int32V(rv2i(rv).(map[int16]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16Int32X(vp *map[int16]int32, d *Decoder) {
-	v, changed := f.DecMapInt16Int32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16Int32V(v map[int16]int32, canChange bool,
-	d *Decoder) (_ map[int16]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[int16]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]int64)
-		v, changed := fastpathTV.DecMapInt16Int64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16Int64V(rv2i(rv).(map[int16]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16Int64X(vp *map[int16]int64, d *Decoder) {
-	v, changed := f.DecMapInt16Int64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16Int64V(v map[int16]int64, canChange bool,
-	d *Decoder) (_ map[int16]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[int16]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]float32)
-		v, changed := fastpathTV.DecMapInt16Float32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16Float32V(rv2i(rv).(map[int16]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16Float32X(vp *map[int16]float32, d *Decoder) {
-	v, changed := f.DecMapInt16Float32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16Float32V(v map[int16]float32, canChange bool,
-	d *Decoder) (_ map[int16]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[int16]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]float64)
-		v, changed := fastpathTV.DecMapInt16Float64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16Float64V(rv2i(rv).(map[int16]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16Float64X(vp *map[int16]float64, d *Decoder) {
-	v, changed := f.DecMapInt16Float64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16Float64V(v map[int16]float64, canChange bool,
-	d *Decoder) (_ map[int16]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[int16]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt16BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int16]bool)
-		v, changed := fastpathTV.DecMapInt16BoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt16BoolV(rv2i(rv).(map[int16]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapInt16BoolX(vp *map[int16]bool, d *Decoder) {
-	v, changed := f.DecMapInt16BoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt16BoolV(v map[int16]bool, canChange bool,
-	d *Decoder) (_ map[int16]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[int16]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int16
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]interface{})
-		v, changed := fastpathTV.DecMapInt32IntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32IntfV(rv2i(rv).(map[int32]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32IntfX(vp *map[int32]interface{}, d *Decoder) {
-	v, changed := f.DecMapInt32IntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32IntfV(v map[int32]interface{}, canChange bool,
-	d *Decoder) (_ map[int32]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[int32]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk int32
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]string)
-		v, changed := fastpathTV.DecMapInt32StringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32StringV(rv2i(rv).(map[int32]string), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32StringX(vp *map[int32]string, d *Decoder) {
-	v, changed := f.DecMapInt32StringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32StringV(v map[int32]string, canChange bool,
-	d *Decoder) (_ map[int32]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
-		v = make(map[int32]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uint)
-		v, changed := fastpathTV.DecMapInt32UintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32UintV(rv2i(rv).(map[int32]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32UintX(vp *map[int32]uint, d *Decoder) {
-	v, changed := f.DecMapInt32UintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32UintV(v map[int32]uint, canChange bool,
-	d *Decoder) (_ map[int32]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int32]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uint8)
-		v, changed := fastpathTV.DecMapInt32Uint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32Uint8V(rv2i(rv).(map[int32]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32Uint8X(vp *map[int32]uint8, d *Decoder) {
-	v, changed := f.DecMapInt32Uint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32Uint8V(v map[int32]uint8, canChange bool,
-	d *Decoder) (_ map[int32]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[int32]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uint16)
-		v, changed := fastpathTV.DecMapInt32Uint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32Uint16V(rv2i(rv).(map[int32]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32Uint16X(vp *map[int32]uint16, d *Decoder) {
-	v, changed := f.DecMapInt32Uint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32Uint16V(v map[int32]uint16, canChange bool,
-	d *Decoder) (_ map[int32]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[int32]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uint32)
-		v, changed := fastpathTV.DecMapInt32Uint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32Uint32V(rv2i(rv).(map[int32]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32Uint32X(vp *map[int32]uint32, d *Decoder) {
-	v, changed := f.DecMapInt32Uint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32Uint32V(v map[int32]uint32, canChange bool,
-	d *Decoder) (_ map[int32]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
-		v = make(map[int32]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uint64)
-		v, changed := fastpathTV.DecMapInt32Uint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32Uint64V(rv2i(rv).(map[int32]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32Uint64X(vp *map[int32]uint64, d *Decoder) {
-	v, changed := f.DecMapInt32Uint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32Uint64V(v map[int32]uint64, canChange bool,
-	d *Decoder) (_ map[int32]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int32]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]uintptr)
-		v, changed := fastpathTV.DecMapInt32UintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32UintptrV(rv2i(rv).(map[int32]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32UintptrX(vp *map[int32]uintptr, d *Decoder) {
-	v, changed := f.DecMapInt32UintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32UintptrV(v map[int32]uintptr, canChange bool,
-	d *Decoder) (_ map[int32]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int32]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]int)
-		v, changed := fastpathTV.DecMapInt32IntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32IntV(rv2i(rv).(map[int32]int), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32IntX(vp *map[int32]int, d *Decoder) {
-	v, changed := f.DecMapInt32IntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32IntV(v map[int32]int, canChange bool,
-	d *Decoder) (_ map[int32]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int32]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]int8)
-		v, changed := fastpathTV.DecMapInt32Int8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32Int8V(rv2i(rv).(map[int32]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32Int8X(vp *map[int32]int8, d *Decoder) {
-	v, changed := f.DecMapInt32Int8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32Int8V(v map[int32]int8, canChange bool,
-	d *Decoder) (_ map[int32]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[int32]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]int16)
-		v, changed := fastpathTV.DecMapInt32Int16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32Int16V(rv2i(rv).(map[int32]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32Int16X(vp *map[int32]int16, d *Decoder) {
-	v, changed := f.DecMapInt32Int16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32Int16V(v map[int32]int16, canChange bool,
-	d *Decoder) (_ map[int32]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
-		v = make(map[int32]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]int32)
-		v, changed := fastpathTV.DecMapInt32Int32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32Int32V(rv2i(rv).(map[int32]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32Int32X(vp *map[int32]int32, d *Decoder) {
-	v, changed := f.DecMapInt32Int32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32Int32V(v map[int32]int32, canChange bool,
-	d *Decoder) (_ map[int32]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
-		v = make(map[int32]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]int64)
-		v, changed := fastpathTV.DecMapInt32Int64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32Int64V(rv2i(rv).(map[int32]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32Int64X(vp *map[int32]int64, d *Decoder) {
-	v, changed := f.DecMapInt32Int64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32Int64V(v map[int32]int64, canChange bool,
-	d *Decoder) (_ map[int32]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int32]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]float32)
-		v, changed := fastpathTV.DecMapInt32Float32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32Float32V(rv2i(rv).(map[int32]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32Float32X(vp *map[int32]float32, d *Decoder) {
-	v, changed := f.DecMapInt32Float32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32Float32V(v map[int32]float32, canChange bool,
-	d *Decoder) (_ map[int32]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
-		v = make(map[int32]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]float64)
-		v, changed := fastpathTV.DecMapInt32Float64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32Float64V(rv2i(rv).(map[int32]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32Float64X(vp *map[int32]float64, d *Decoder) {
-	v, changed := f.DecMapInt32Float64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32Float64V(v map[int32]float64, canChange bool,
-	d *Decoder) (_ map[int32]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int32]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt32BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int32]bool)
-		v, changed := fastpathTV.DecMapInt32BoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt32BoolV(rv2i(rv).(map[int32]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapInt32BoolX(vp *map[int32]bool, d *Decoder) {
-	v, changed := f.DecMapInt32BoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt32BoolV(v map[int32]bool, canChange bool,
-	d *Decoder) (_ map[int32]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[int32]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int32
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64IntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]interface{})
-		v, changed := fastpathTV.DecMapInt64IntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64IntfV(rv2i(rv).(map[int64]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64IntfX(vp *map[int64]interface{}, d *Decoder) {
-	v, changed := f.DecMapInt64IntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64IntfV(v map[int64]interface{}, canChange bool,
-	d *Decoder) (_ map[int64]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[int64]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk int64
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64StringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]string)
-		v, changed := fastpathTV.DecMapInt64StringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64StringV(rv2i(rv).(map[int64]string), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64StringX(vp *map[int64]string, d *Decoder) {
-	v, changed := f.DecMapInt64StringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64StringV(v map[int64]string, canChange bool,
-	d *Decoder) (_ map[int64]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
-		v = make(map[int64]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64UintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uint)
-		v, changed := fastpathTV.DecMapInt64UintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64UintV(rv2i(rv).(map[int64]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64UintX(vp *map[int64]uint, d *Decoder) {
-	v, changed := f.DecMapInt64UintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64UintV(v map[int64]uint, canChange bool,
-	d *Decoder) (_ map[int64]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int64]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64Uint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uint8)
-		v, changed := fastpathTV.DecMapInt64Uint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64Uint8V(rv2i(rv).(map[int64]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64Uint8X(vp *map[int64]uint8, d *Decoder) {
-	v, changed := f.DecMapInt64Uint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64Uint8V(v map[int64]uint8, canChange bool,
-	d *Decoder) (_ map[int64]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int64]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64Uint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uint16)
-		v, changed := fastpathTV.DecMapInt64Uint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64Uint16V(rv2i(rv).(map[int64]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64Uint16X(vp *map[int64]uint16, d *Decoder) {
-	v, changed := f.DecMapInt64Uint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64Uint16V(v map[int64]uint16, canChange bool,
-	d *Decoder) (_ map[int64]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[int64]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64Uint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uint32)
-		v, changed := fastpathTV.DecMapInt64Uint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64Uint32V(rv2i(rv).(map[int64]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64Uint32X(vp *map[int64]uint32, d *Decoder) {
-	v, changed := f.DecMapInt64Uint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64Uint32V(v map[int64]uint32, canChange bool,
-	d *Decoder) (_ map[int64]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int64]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64Uint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uint64)
-		v, changed := fastpathTV.DecMapInt64Uint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64Uint64V(rv2i(rv).(map[int64]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64Uint64X(vp *map[int64]uint64, d *Decoder) {
-	v, changed := f.DecMapInt64Uint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64Uint64V(v map[int64]uint64, canChange bool,
-	d *Decoder) (_ map[int64]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int64]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64UintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]uintptr)
-		v, changed := fastpathTV.DecMapInt64UintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64UintptrV(rv2i(rv).(map[int64]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64UintptrX(vp *map[int64]uintptr, d *Decoder) {
-	v, changed := f.DecMapInt64UintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64UintptrV(v map[int64]uintptr, canChange bool,
-	d *Decoder) (_ map[int64]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int64]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64IntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]int)
-		v, changed := fastpathTV.DecMapInt64IntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64IntV(rv2i(rv).(map[int64]int), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64IntX(vp *map[int64]int, d *Decoder) {
-	v, changed := f.DecMapInt64IntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64IntV(v map[int64]int, canChange bool,
-	d *Decoder) (_ map[int64]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int64]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64Int8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]int8)
-		v, changed := fastpathTV.DecMapInt64Int8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64Int8V(rv2i(rv).(map[int64]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64Int8X(vp *map[int64]int8, d *Decoder) {
-	v, changed := f.DecMapInt64Int8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64Int8V(v map[int64]int8, canChange bool,
-	d *Decoder) (_ map[int64]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int64]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64Int16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]int16)
-		v, changed := fastpathTV.DecMapInt64Int16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64Int16V(rv2i(rv).(map[int64]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64Int16X(vp *map[int64]int16, d *Decoder) {
-	v, changed := f.DecMapInt64Int16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64Int16V(v map[int64]int16, canChange bool,
-	d *Decoder) (_ map[int64]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
-		v = make(map[int64]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64Int32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]int32)
-		v, changed := fastpathTV.DecMapInt64Int32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64Int32V(rv2i(rv).(map[int64]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64Int32X(vp *map[int64]int32, d *Decoder) {
-	v, changed := f.DecMapInt64Int32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64Int32V(v map[int64]int32, canChange bool,
-	d *Decoder) (_ map[int64]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int64]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64Int64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]int64)
-		v, changed := fastpathTV.DecMapInt64Int64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64Int64V(rv2i(rv).(map[int64]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64Int64X(vp *map[int64]int64, d *Decoder) {
-	v, changed := f.DecMapInt64Int64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64Int64V(v map[int64]int64, canChange bool,
-	d *Decoder) (_ map[int64]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int64]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64Float32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]float32)
-		v, changed := fastpathTV.DecMapInt64Float32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64Float32V(rv2i(rv).(map[int64]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64Float32X(vp *map[int64]float32, d *Decoder) {
-	v, changed := f.DecMapInt64Float32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64Float32V(v map[int64]float32, canChange bool,
-	d *Decoder) (_ map[int64]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
-		v = make(map[int64]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64Float64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]float64)
-		v, changed := fastpathTV.DecMapInt64Float64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64Float64V(rv2i(rv).(map[int64]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64Float64X(vp *map[int64]float64, d *Decoder) {
-	v, changed := f.DecMapInt64Float64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64Float64V(v map[int64]float64, canChange bool,
-	d *Decoder) (_ map[int64]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
-		v = make(map[int64]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapInt64BoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[int64]bool)
-		v, changed := fastpathTV.DecMapInt64BoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapInt64BoolV(rv2i(rv).(map[int64]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapInt64BoolX(vp *map[int64]bool, d *Decoder) {
-	v, changed := f.DecMapInt64BoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapInt64BoolV(v map[int64]bool, canChange bool,
-	d *Decoder) (_ map[int64]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[int64]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk int64
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeInt64()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolIntfR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]interface{})
-		v, changed := fastpathTV.DecMapBoolIntfV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolIntfV(rv2i(rv).(map[bool]interface{}), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolIntfX(vp *map[bool]interface{}, d *Decoder) {
-	v, changed := f.DecMapBoolIntfV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolIntfV(v map[bool]interface{}, canChange bool,
-	d *Decoder) (_ map[bool]interface{}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[bool]interface{}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-	var mk bool
-	var mv interface{}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = nil
-			}
-			continue
-		}
-		if mapGet {
-			mv = v[mk]
-		} else {
-			mv = nil
-		}
-		d.decode(&mv)
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolStringR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]string)
-		v, changed := fastpathTV.DecMapBoolStringV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolStringV(rv2i(rv).(map[bool]string), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolStringX(vp *map[bool]string, d *Decoder) {
-	v, changed := f.DecMapBoolStringV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolStringV(v map[bool]string, canChange bool,
-	d *Decoder) (_ map[bool]string, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
-		v = make(map[bool]string, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv string
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = ""
-			}
-			continue
-		}
-		mv = dd.DecodeString()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolUintR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uint)
-		v, changed := fastpathTV.DecMapBoolUintV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolUintV(rv2i(rv).(map[bool]uint), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolUintX(vp *map[bool]uint, d *Decoder) {
-	v, changed := f.DecMapBoolUintV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolUintV(v map[bool]uint, canChange bool,
-	d *Decoder) (_ map[bool]uint, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[bool]uint, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv uint
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolUint8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uint8)
-		v, changed := fastpathTV.DecMapBoolUint8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolUint8V(rv2i(rv).(map[bool]uint8), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolUint8X(vp *map[bool]uint8, d *Decoder) {
-	v, changed := f.DecMapBoolUint8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolUint8V(v map[bool]uint8, canChange bool,
-	d *Decoder) (_ map[bool]uint8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
-		v = make(map[bool]uint8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv uint8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolUint16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uint16)
-		v, changed := fastpathTV.DecMapBoolUint16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolUint16V(rv2i(rv).(map[bool]uint16), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolUint16X(vp *map[bool]uint16, d *Decoder) {
-	v, changed := f.DecMapBoolUint16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolUint16V(v map[bool]uint16, canChange bool,
-	d *Decoder) (_ map[bool]uint16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[bool]uint16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv uint16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolUint32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uint32)
-		v, changed := fastpathTV.DecMapBoolUint32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolUint32V(rv2i(rv).(map[bool]uint32), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolUint32X(vp *map[bool]uint32, d *Decoder) {
-	v, changed := f.DecMapBoolUint32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolUint32V(v map[bool]uint32, canChange bool,
-	d *Decoder) (_ map[bool]uint32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[bool]uint32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv uint32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolUint64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uint64)
-		v, changed := fastpathTV.DecMapBoolUint64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolUint64V(rv2i(rv).(map[bool]uint64), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolUint64X(vp *map[bool]uint64, d *Decoder) {
-	v, changed := f.DecMapBoolUint64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolUint64V(v map[bool]uint64, canChange bool,
-	d *Decoder) (_ map[bool]uint64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[bool]uint64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv uint64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeUint64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolUintptrR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]uintptr)
-		v, changed := fastpathTV.DecMapBoolUintptrV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolUintptrV(rv2i(rv).(map[bool]uintptr), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolUintptrX(vp *map[bool]uintptr, d *Decoder) {
-	v, changed := f.DecMapBoolUintptrV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolUintptrV(v map[bool]uintptr, canChange bool,
-	d *Decoder) (_ map[bool]uintptr, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[bool]uintptr, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv uintptr
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolIntR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]int)
-		v, changed := fastpathTV.DecMapBoolIntV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolIntV(rv2i(rv).(map[bool]int), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolIntX(vp *map[bool]int, d *Decoder) {
-	v, changed := f.DecMapBoolIntV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolIntV(v map[bool]int, canChange bool,
-	d *Decoder) (_ map[bool]int, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[bool]int, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv int
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolInt8R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]int8)
-		v, changed := fastpathTV.DecMapBoolInt8V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolInt8V(rv2i(rv).(map[bool]int8), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolInt8X(vp *map[bool]int8, d *Decoder) {
-	v, changed := f.DecMapBoolInt8V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolInt8V(v map[bool]int8, canChange bool,
-	d *Decoder) (_ map[bool]int8, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
-		v = make(map[bool]int8, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv int8
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolInt16R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]int16)
-		v, changed := fastpathTV.DecMapBoolInt16V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolInt16V(rv2i(rv).(map[bool]int16), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolInt16X(vp *map[bool]int16, d *Decoder) {
-	v, changed := f.DecMapBoolInt16V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolInt16V(v map[bool]int16, canChange bool,
-	d *Decoder) (_ map[bool]int16, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
-		v = make(map[bool]int16, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv int16
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolInt32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]int32)
-		v, changed := fastpathTV.DecMapBoolInt32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolInt32V(rv2i(rv).(map[bool]int32), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolInt32X(vp *map[bool]int32, d *Decoder) {
-	v, changed := f.DecMapBoolInt32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolInt32V(v map[bool]int32, canChange bool,
-	d *Decoder) (_ map[bool]int32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[bool]int32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv int32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolInt64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]int64)
-		v, changed := fastpathTV.DecMapBoolInt64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolInt64V(rv2i(rv).(map[bool]int64), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolInt64X(vp *map[bool]int64, d *Decoder) {
-	v, changed := f.DecMapBoolInt64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolInt64V(v map[bool]int64, canChange bool,
-	d *Decoder) (_ map[bool]int64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[bool]int64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv int64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeInt64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolFloat32R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]float32)
-		v, changed := fastpathTV.DecMapBoolFloat32V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolFloat32V(rv2i(rv).(map[bool]float32), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolFloat32X(vp *map[bool]float32, d *Decoder) {
-	v, changed := f.DecMapBoolFloat32V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolFloat32V(v map[bool]float32, canChange bool,
-	d *Decoder) (_ map[bool]float32, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
-		v = make(map[bool]float32, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv float32
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolFloat64R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]float64)
-		v, changed := fastpathTV.DecMapBoolFloat64V(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolFloat64V(rv2i(rv).(map[bool]float64), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolFloat64X(vp *map[bool]float64, d *Decoder) {
-	v, changed := f.DecMapBoolFloat64V(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolFloat64V(v map[bool]float64, canChange bool,
-	d *Decoder) (_ map[bool]float64, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
-		v = make(map[bool]float64, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv float64
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = 0
-			}
-			continue
-		}
-		mv = dd.DecodeFloat64()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-
-func (d *Decoder) fastpathDecMapBoolBoolR(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[bool]bool)
-		v, changed := fastpathTV.DecMapBoolBoolV(*vp, true, d)
-		if changed {
-			*vp = v
-		}
-	} else {
-		fastpathTV.DecMapBoolBoolV(rv2i(rv).(map[bool]bool), false, d)
-	}
-}
-func (f fastpathT) DecMapBoolBoolX(vp *map[bool]bool, d *Decoder) {
-	v, changed := f.DecMapBoolBoolV(*vp, true, d)
-	if changed {
-		*vp = v
-	}
-}
-func (_ fastpathT) DecMapBoolBoolV(v map[bool]bool, canChange bool,
-	d *Decoder) (_ map[bool]bool, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators()
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
-		v = make(map[bool]bool, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	var mk bool
-	var mv bool
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep {
-			dd.ReadMapElemKey()
-		}
-		mk = dd.DecodeBool()
-		if esep {
-			dd.ReadMapElemValue()
-		}
-		if dd.TryDecodeAsNil() {
-			if v == nil {
-			} else if d.h.DeleteOnNilMapValue {
-				delete(v, mk)
-			} else {
-				v[mk] = false
-			}
-			continue
-		}
-		mv = dd.DecodeBool()
-		if v != nil {
-			v[mk] = mv
-		}
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
diff --git a/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl b/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
deleted file mode 100644
index 2023e05..0000000
--- a/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
+++ /dev/null
@@ -1,544 +0,0 @@
-// +build !notfastpath
-
-// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// Code generated from fast-path.go.tmpl - DO NOT EDIT.
-
-package codec
-
-// Fast path functions try to create a fast path encode or decode implementation
-// for common maps and slices.
-//
-// We define the functions and register then in this single file
-// so as not to pollute the encode.go and decode.go, and create a dependency in there.
-// This file can be omitted without causing a build failure.
-//
-// The advantage of fast paths is:
-//	  - Many calls bypass reflection altogether
-// 
-// Currently support
-//	  - slice of all builtin types,
-//	  - map of all builtin types to string or interface value
-//	  - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
-// This should provide adequate "typical" implementations.
-// 
-// Note that fast track decode functions must handle values for which an address cannot be obtained.
-// For example: 
-//	 m2 := map[string]int{}
-//	 p2 := []interface{}{m2}
-//	 // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
-// 
-
-import (
-	"reflect"
-	"sort"
-)
-
-const fastpathEnabled = true
-
-type fastpathT struct {}
-
-var fastpathTV fastpathT
-
-type fastpathE struct {
-	rtid uintptr
-	rt reflect.Type 
-	encfn func(*Encoder, *codecFnInfo, reflect.Value)
-	decfn func(*Decoder, *codecFnInfo, reflect.Value)
-}
-
-type fastpathA [{{ .FastpathLen }}]fastpathE
-
-func (x *fastpathA) index(rtid uintptr) int {
-	// use binary search to grab the index (adapted from sort/search.go)
-	h, i, j := 0, 0, {{ .FastpathLen }} // len(x)
-	for i < j {
-		h = i + (j-i)/2
-		if x[h].rtid < rtid {
-			i = h + 1
-		} else {
-			j = h
-		}
-	}
-	if i < {{ .FastpathLen }} && x[i].rtid == rtid {
-		return i
-	}
-	return -1
-}
-
-type fastpathAslice []fastpathE
-
-func (x fastpathAslice) Len() int { return len(x) }
-func (x fastpathAslice) Less(i, j int) bool { return x[i].rtid < x[j].rtid }
-func (x fastpathAslice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-var fastpathAV fastpathA
-
-// due to possible initialization loop error, make fastpath in an init()
-func init() {
-	i := 0
-	fn := func(v interface{},
-		fe func(*Encoder, *codecFnInfo, reflect.Value),
-		fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
-		xrt := reflect.TypeOf(v)
-		xptr := rt2id(xrt)
-		fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
-		i++
-		return
-	}
-	{{/* do not register []uint8 in fast-path */}}
-	{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
-	fn([]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}{{end}}
-	
-	{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
-	fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
-	
-	sort.Sort(fastpathAslice(fastpathAV[:]))
-}
-
-// -- encode
-
-// -- -- fast path type switch
-func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
-	switch v := iv.(type) {
-
-{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
-	case []{{ .Elem }}:
-		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
-	case *[]{{ .Elem }}:
-		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
-*/}}{{end}}{{end}}{{end}}{{end}}
-
-{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
-	case map[{{ .MapKey }}]{{ .Elem }}:
-		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
-	case *map[{{ .MapKey }}]{{ .Elem }}:
-		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
-*/}}{{end}}{{end}}{{end}}
-
-	default:
-        _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
-		return false
-	}
-	return true
-}
-
-{{/*
-**** removing this block, as they are never called directly ****
-
-
-
-**** removing this block, as they are never called directly ****
-
-
-
-func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
-	switch v := iv.(type) {
-{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
-	case []{{ .Elem }}:
-		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
-	case *[]{{ .Elem }}:
-		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
-{{end}}{{end}}{{end}}
-	default:
-        _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
-		return false
-	}
-	return true
-}
-
-func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
-	switch v := iv.(type) {
-{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
-	case map[{{ .MapKey }}]{{ .Elem }}:
-		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
-	case *map[{{ .MapKey }}]{{ .Elem }}:
-		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
-{{end}}{{end}}{{end}}
-	default:
-        _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
-		return false
-	}
-	return true
-}
-
-
-
-**** removing this block, as they are never called directly ****
-
-
-
-**** removing this block, as they are never called directly ****
-*/}}
-
-// -- -- fast path functions
-{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} 
-func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
-	if f.ti.mbs {
-		fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv2i(rv).([]{{ .Elem }}), e)
-	} else {
-		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).([]{{ .Elem }}), e)
-	}
-}
-func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, e *Encoder) {
-	if v == nil { e.e.EncodeNil(); return }
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	ee.WriteArrayStart(len(v))
-	if esep {
-		for _, v2 := range v {
-			ee.WriteArrayElem()
-			{{ encmd .Elem "v2"}}
-		}
-	} else {
-		for _, v2 := range v {
-			{{ encmd .Elem "v2"}}
-		}
-	} {{/*
-	for _, v2 := range v {
-		if esep { ee.WriteArrayElem() }
-		{{ encmd .Elem "v2"}}
-	} */}}
-	ee.WriteArrayEnd()
-}
-func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Encoder) {
-	ee, esep := e.e, e.hh.hasElemSeparators()
-	if len(v)%2 == 1 {
-		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
-		return
-	}
-	ee.WriteMapStart(len(v) / 2)
-	if esep {
-		for j, v2 := range v {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-			{{ encmd .Elem "v2"}}
-		}
-	} else {
-		for _, v2 := range v {
-			{{ encmd .Elem "v2"}}
-		}
-	} {{/*
-	for j, v2 := range v {
-		if esep {
-			if j%2 == 0 {
-				ee.WriteMapElemKey()
-			} else {
-				ee.WriteMapElemValue()
-			}
-		}
-		{{ encmd .Elem "v2"}}
-	} */}}
-	ee.WriteMapEnd()
-}
-{{end}}{{end}}{{end}}
-
-{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
-func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
-	fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), e)
-}
-func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, e *Encoder) {
-	if v == nil { e.e.EncodeNil(); return }
-	ee, esep := e.e, e.hh.hasElemSeparators() 
-	ee.WriteMapStart(len(v))
-	if e.h.Canonical {
-		{{if eq .MapKey "interface{}"}}{{/* out of band 
-		*/}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
-		e2 := NewEncoderBytes(&mksv, e.hh)
-		v2 := make([]bytesI, len(v))
-		var i, l int
-		var vp *bytesI {{/* put loop variables outside. seems currently needed for better perf */}}
-		for k2, _ := range v {
-			l = len(mksv)
-			e2.MustEncode(k2)
-			vp = &v2[i]
-			vp.v = mksv[l:]
-			vp.i = k2 
-			i++
-		}
-		sort.Sort(bytesISlice(v2))
-		if esep {
-			for j := range v2 {
-				ee.WriteMapElemKey()
-				e.asis(v2[j].v)
-				ee.WriteMapElemValue()
-				e.encode(v[v2[j].i])
-			}
-		} else {
-			for j := range v2 {
-				e.asis(v2[j].v)
-				e.encode(v[v2[j].i])
-			}
-		} {{/*
-		for j := range v2 {
-			if esep { ee.WriteMapElemKey() }
-			e.asis(v2[j].v)
-			if esep { ee.WriteMapElemValue() }
-			e.encode(v[v2[j].i])
-		} */}} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
-		var i int 
-		for k, _ := range v {
-			v2[i] = {{ $x }}(k)
-			i++
-		}
-		sort.Sort({{ sorttype .MapKey false}}(v2))
-		if esep {
-			for _, k2 := range v2 {
-				ee.WriteMapElemKey()
-				{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
-				ee.WriteMapElemValue()
-				{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
-			} 
-		} else {
-			for _, k2 := range v2 {
-				{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
-				{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
-			} 
-		} {{/*
-		for _, k2 := range v2 {
-			if esep { ee.WriteMapElemKey() }
-			{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
-			if esep { ee.WriteMapElemValue() }
-			{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
-		} */}} {{end}}
-	} else {
-		if esep {
-			for k2, v2 := range v {
-				ee.WriteMapElemKey()
-				{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
-				ee.WriteMapElemValue()
-				{{ encmd .Elem "v2"}}
-			}
-		} else {
-			for k2, v2 := range v {
-				{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
-				{{ encmd .Elem "v2"}}
-			}
-		} {{/*
-		for k2, v2 := range v {
-			if esep { ee.WriteMapElemKey() }
-			{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
-			if esep { ee.WriteMapElemValue() }
-			{{ encmd .Elem "v2"}}
-		} */}}
-	}
-	ee.WriteMapEnd()
-}
-{{end}}{{end}}{{end}}
-
-// -- decode
-
-// -- -- fast path type switch
-func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
-     var changed bool
-	switch v := iv.(type) {
-{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
-	case []{{ .Elem }}:
-        var v2 []{{ .Elem }}
-		v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
-        if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-			copy(v, v2)
-		}
-	case *[]{{ .Elem }}:
-        var v2 []{{ .Elem }}
-		v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
-        if changed {
-			*v = v2 
-		}{{/*
-*/}}{{end}}{{end}}{{end}}{{end}}
-{{range .Values}}{{if not .Primitive}}{{if .MapKey }}{{/*
-// maps only change if nil, and in that case, there's no point copying
-*/}}
-	case map[{{ .MapKey }}]{{ .Elem }}:
-		fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
-	case *map[{{ .MapKey }}]{{ .Elem }}:
-         var v2 map[{{ .MapKey }}]{{ .Elem }}
-		v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
-        if changed {
-			*v = v2 
-		}{{/*
-*/}}{{end}}{{end}}{{end}}
-	default:
-        _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
-		return false
-	}
-	return true
-}
-
-func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
-	switch v := iv.(type) {
-{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
-	case *[]{{ .Elem }}: 
-		*v = nil {{/*
-*/}}{{end}}{{end}}{{end}}
-{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
-	case *map[{{ .MapKey }}]{{ .Elem }}: 
-		*v = nil {{/*
-*/}}{{end}}{{end}}{{end}}
-	default:
-        _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
-		return false
-	}
-	return true
-}
-
-// -- -- fast path functions
-{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
-{{/*
-Slices can change if they 
-- did not come from an array
-- are addressable (from a ptr)
-- are settable (e.g. contained in an interface{})
-*/}}
-func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
-	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*[]{{ .Elem }})
-		v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, !array, d)
-        if changed { *vp = v }
-	} else {
-		v := rv2i(rv).([]{{ .Elem }})
-        v2, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, !array, d)
-        if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
-           copy(v, v2)
-        }
-	}
-}
-func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, d *Decoder) {
-	v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
-    if changed { *vp = v }
-}
-func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) {
-	dd := d.d{{/*
-	    // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil()
-    */}}
-	slh, containerLenS := d.decSliceHelperStart()
-	if containerLenS == 0 {
-		if canChange {
-			if v == nil { v = []{{ .Elem }}{} } else if len(v) != 0 { v = v[:0] }
-			changed = true
-		}
-		slh.End()
-		return v, changed
-	}
-	hasLen := containerLenS > 0
-	var xlen int 
-	if hasLen && canChange {
-		if containerLenS > cap(v) {
-			xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
-			if xlen <= cap(v) {
-				v = v[:xlen]
-			} else {
-				v = make([]{{ .Elem }}, xlen)
-			}
-			changed = true 
-		} else if containerLenS != len(v) {
-			v = v[:containerLenS]
-			changed = true
-		}
-	}
-	j := 0
-	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
-		if j == 0 && len(v) == 0 && canChange {
-			if hasLen {
-				xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
-			} else {
-				xlen = 8
-			}
-			v = make([]{{ .Elem }}, xlen)
-			changed = true 
-		}
-		// if indefinite, etc, then expand the slice if necessary
-		var decodeIntoBlank bool
-		if j >= len(v) {
-			if canChange {
-				v = append(v, {{ zerocmd .Elem }})
-				changed = true
-			} else {
-				d.arrayCannotExpand(len(v), j+1)
-				decodeIntoBlank = true
-			}
-		} 
-		slh.ElemContainerState(j)
-		if decodeIntoBlank {
-			d.swallow()
-		} else if dd.TryDecodeAsNil() {
-			v[j] = {{ zerocmd .Elem }}
-		} else {
-			{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
-		}
-	}
-	if canChange {
-		if j < len(v) {
-			v = v[:j]
-			changed = true
-		} else if j == 0 && v == nil {
-			v = make([]{{ .Elem }}, 0)
-			changed = true
-		}
-	}
-	slh.End()
-	return v, changed 
-}
-{{end}}{{end}}{{end}}
-
-{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
-{{/*
-Maps can change if they are
-- addressable (from a ptr)
-- settable (e.g. contained in an interface{})
-*/}}
-func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
-	if rv.Kind() == reflect.Ptr {
-		vp := rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }})
-		v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d);
-		if changed { *vp = v }
-	} else {
-	    fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), false, d)
-    }
-}
-func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
-	v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
-	if changed { *vp = v }
-}
-func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, canChange bool, 
-	d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
-	dd, esep := d.d, d.hh.hasElemSeparators(){{/*
-	    // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil()
-    */}}
-	containerLen := dd.ReadMapStart()
-	if canChange && v == nil {
-		xlen := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }})
-		v = make(map[{{ .MapKey }}]{{ .Elem }}, xlen)
-		changed = true
-	}
-	if containerLen == 0 {
-		dd.ReadMapEnd()
-		return v, changed
-	}
-	{{ if eq .Elem "interface{}" }}mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
-    {{end}}var mk {{ .MapKey }}
-	var mv {{ .Elem }}
-	hasLen := containerLen > 0
-	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
-		if esep { dd.ReadMapElemKey() }
-		{{ if eq .MapKey "interface{}" }}mk = nil 
-		d.decode(&mk)
-		if bv, bok := mk.([]byte); bok {
-			mk = d.string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
-		}{{ else }}mk = {{ decmd .MapKey }}{{ end }}
-		if esep { dd.ReadMapElemValue() }
-		if dd.TryDecodeAsNil() {
-			if v == nil {} else if d.h.DeleteOnNilMapValue { delete(v, mk) } else { v[mk] = {{ zerocmd .Elem }} }
-			continue 
-		}
-		{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
-		d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
-		if v != nil { v[mk] = mv }
-	}
-	dd.ReadMapEnd()
-	return v, changed
-}
-{{end}}{{end}}{{end}}
diff --git a/vendor/github.com/ugorji/go/codec/fast-path.not.go b/vendor/github.com/ugorji/go/codec/fast-path.not.go
deleted file mode 100644
index f11b467..0000000
--- a/vendor/github.com/ugorji/go/codec/fast-path.not.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build notfastpath
-
-package codec
-
-import "reflect"
-
-const fastpathEnabled = false
-
-// The generated fast-path code is very large, and adds a few seconds to the build time.
-// This causes test execution, execution of small tools which use codec, etc
-// to take a long time.
-//
-// To mitigate, we now support the notfastpath tag.
-// This tag disables fastpath during build, allowing for faster build, test execution,
-// short-program runs, etc.
-
-func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool      { return false }
-func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool      { return false }
-func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { return false }
-func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool   { return false }
-func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool           { return false }
-
-type fastpathT struct{}
-type fastpathE struct {
-	rtid  uintptr
-	rt    reflect.Type
-	encfn func(*Encoder, *codecFnInfo, reflect.Value)
-	decfn func(*Decoder, *codecFnInfo, reflect.Value)
-}
-type fastpathA [0]fastpathE
-
-func (x fastpathA) index(rtid uintptr) int { return -1 }
-
-func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
-	fn := d.cfer().get(uint8SliceTyp, true, true)
-	d.kSlice(&fn.i, reflect.ValueOf(&v).Elem())
-	return v, true
-}
-
-var fastpathAV fastpathA
-var fastpathTV fastpathT
-
-// ----
-type TestMammoth2Wrapper struct{} // to allow testMammoth work in notfastpath mode
diff --git a/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
deleted file mode 100644
index 59c5983..0000000
--- a/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
+++ /dev/null
@@ -1,78 +0,0 @@
-{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
-{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
-var {{var "c"}} bool {{/* // changed */}}
-_ = {{var "c"}}{{end}}
-if {{var "l"}} == 0 {
-	{{if isSlice }}if {{var "v"}} == nil {
-		{{var "v"}} = []{{ .Typ }}{}
-		{{var "c"}} = true
-	} else if len({{var "v"}}) != 0 {
-		{{var "v"}} = {{var "v"}}[:0]
-		{{var "c"}} = true
-	} {{else if isChan }}if {{var "v"}} == nil {
-		{{var "v"}} = make({{ .CTyp }}, 0)
-		{{var "c"}} = true
-	} {{end}}
-} else {
-	{{var "hl"}} := {{var "l"}} > 0
-	var {{var "rl"}} int
-	_ =  {{var "rl"}}
-	{{if isSlice }} if {{var "hl"}} {
-	if {{var "l"}} > cap({{var "v"}}) {
-		{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
-		if {{var "rl"}} <= cap({{var "v"}}) {
-			{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
-		} else {
-			{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
-		}
-		{{var "c"}} = true
-	} else if {{var "l"}} != len({{var "v"}}) {
-		{{var "v"}} = {{var "v"}}[:{{var "l"}}]
-		{{var "c"}} = true
-	}
-	} {{end}}
-	var {{var "j"}} int 
-    // var {{var "dn"}} bool 
-	for ; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
-		{{if not isArray}} if {{var "j"}} == 0 && {{var "v"}} == nil {
-			if {{var "hl"}} {
-				{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
-			} else {
-				{{var "rl"}} = {{if isSlice}}8{{else if isChan}}64{{end}}
-			}
-			{{var "v"}} = make({{if isSlice}}[]{{ .Typ }}{{else if isChan}}{{.CTyp}}{{end}}, {{var "rl"}})
-			{{var "c"}} = true 
-		}{{end}}
-		{{var "h"}}.ElemContainerState({{var "j"}})
-        {{/* {{var "dn"}} = r.TryDecodeAsNil() */}}{{/* commented out, as decLineVar handles this already each time */}}
-        {{if isChan}}{{ $x := printf "%[1]vvcx%[2]v" .TempVar .Rand }}var {{$x}} {{ .Typ }}
-		{{ decLineVar $x }}
-		{{var "v"}} <- {{ $x }}
-        // println(">>>> sending ", {{ $x }}, " into ", {{var "v"}}) // TODO: remove this
-        {{else}}{{/* // if indefinite, etc, then expand the slice if necessary */}}
-		var {{var "db"}} bool
-		if {{var "j"}} >= len({{var "v"}}) {
-			{{if isSlice }} {{var "v"}} = append({{var "v"}}, {{ zero }})
-			{{var "c"}} = true
-			{{else}} z.DecArrayCannotExpand(len(v), {{var "j"}}+1); {{var "db"}} = true
-			{{end}}
-		}
-		if {{var "db"}} {
-			z.DecSwallow()
-		} else {
-			{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
-		}
-        {{end}}
-	}
-	{{if isSlice}} if {{var "j"}} < len({{var "v"}}) {
-		{{var "v"}} = {{var "v"}}[:{{var "j"}}]
-		{{var "c"}} = true
-	} else if {{var "j"}} == 0 && {{var "v"}} == nil {
-		{{var "v"}} = make([]{{ .Typ }}, 0)
-		{{var "c"}} = true
-	} {{end}}
-}
-{{var "h"}}.End()
-{{if not isArray }}if {{var "c"}} { 
-	*{{ .Varname }} = {{var "v"}}
-}{{end}}
diff --git a/vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl
deleted file mode 100644
index 8323b54..0000000
--- a/vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl
+++ /dev/null
@@ -1,42 +0,0 @@
-{{var "v"}} := *{{ .Varname }}
-{{var "l"}} := r.ReadMapStart()
-{{var "bh"}} := z.DecBasicHandle()
-if {{var "v"}} == nil {
-	{{var "rl"}} := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
-	{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
-	*{{ .Varname }} = {{var "v"}}
-}
-var {{var "mk"}} {{ .KTyp }}
-var {{var "mv"}} {{ .Typ }}
-var {{var "mg"}}, {{var "mdn"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
-if {{var "bh"}}.MapValueReset {
-	{{if decElemKindPtr}}{{var "mg"}} = true
-	{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true }
-	{{else if not decElemKindImmutable}}{{var "mg"}} = true
-	{{end}} }
-if {{var "l"}} != 0 {
-{{var "hl"}} := {{var "l"}} > 0 
-	for {{var "j"}} := 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
-	r.ReadMapElemKey() {{/* z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }}) */}}
-	{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
-{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
-		{{var "mk"}} = string({{var "bv"}})
-	}{{ end }}{{if decElemKindPtr}}
-	{{var "ms"}} = true{{end}}
-	if {{var "mg"}} {
-		{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}] 
-		if {{var "mok"}} {
-			{{var "ms"}} = false
-		} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}}
-	} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
-	r.ReadMapElemValue() {{/* z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }}) */}}
-	{{var "mdn"}} = false
-	{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ $y := printf "%vmdn%v" .TempVar .Rand }}{{ decLineVar $x $y }}
-	if {{var "mdn"}} {
-		if {{ var "bh" }}.DeleteOnNilMapValue { delete({{var "v"}}, {{var "mk"}}) } else { {{var "v"}}[{{var "mk"}}] = {{decElemZero}} }
-	} else if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
-		{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
-	}
-}
-} // else len==0: TODO: Should we clear map entries?
-r.ReadMapEnd() {{/* z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) */}}
diff --git a/vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl
deleted file mode 100644
index 4249588..0000000
--- a/vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl
+++ /dev/null
@@ -1,27 +0,0 @@
-{{.Label}}:
-switch timeout{{.Sfx}} :=  z.EncBasicHandle().ChanRecvTimeout; {
-case timeout{{.Sfx}} == 0: // only consume available
-	for {
-		select {
-		case b{{.Sfx}} := <-{{.Chan}}:
-			{{ .Slice }} = append({{.Slice}}, b{{.Sfx}})
-		default:
-			break {{.Label}}
-		}
-	}
-case timeout{{.Sfx}} > 0: // consume until timeout
-	tt{{.Sfx}} := time.NewTimer(timeout{{.Sfx}})
-	for {
-		select {
-		case b{{.Sfx}} := <-{{.Chan}}:
-			{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
-		case <-tt{{.Sfx}}.C:
-			// close(tt.C)
-			break {{.Label}}
-		}
-	}
-default: // consume until close
-	for b{{.Sfx}} := range {{.Chan}} {
-		{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
-	}
-}
diff --git a/vendor/github.com/ugorji/go/codec/gen-helper.generated.go b/vendor/github.com/ugorji/go/codec/gen-helper.generated.go
deleted file mode 100644
index 917d282..0000000
--- a/vendor/github.com/ugorji/go/codec/gen-helper.generated.go
+++ /dev/null
@@ -1,335 +0,0 @@
-/* // +build ignore */
-
-// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// Code generated from gen-helper.go.tmpl - DO NOT EDIT.
-
-package codec
-
-import (
-	"encoding"
-	"reflect"
-)
-
-// GenVersion is the current version of codecgen.
-const GenVersion = 8
-
-// This file is used to generate helper code for codecgen.
-// The values here i.e. genHelper(En|De)coder are not to be used directly by
-// library users. They WILL change continuously and without notice.
-//
-// To help enforce this, we create an unexported type with exported members.
-// The only way to get the type is via the one exported type that we control (somewhat).
-//
-// When static codecs are created for types, they will use this value
-// to perform encoding or decoding of primitives or known slice or map types.
-
-// GenHelperEncoder is exported so that it can be used externally by codecgen.
-//
-// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
-func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
-	ge = genHelperEncoder{e: e}
-	ee = genHelperEncDriver{encDriver: e.e}
-	return
-}
-
-// GenHelperDecoder is exported so that it can be used externally by codecgen.
-//
-// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
-func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
-	gd = genHelperDecoder{d: d}
-	dd = genHelperDecDriver{decDriver: d.d}
-	return
-}
-
-type genHelperEncDriver struct {
-	encDriver
-}
-
-func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
-func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
-	encStructFieldKey(x.encDriver, keyType, s)
-}
-func (x genHelperEncDriver) EncodeSymbol(s string) {
-	x.encDriver.EncodeString(cUTF8, s)
-}
-
-type genHelperDecDriver struct {
-	decDriver
-	C checkOverflow
-}
-
-func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
-func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
-	return decStructFieldKey(x.decDriver, keyType, buf)
-}
-func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
-	return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
-}
-func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
-	return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
-}
-func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
-	f = x.DecodeFloat64()
-	if chkOverflow32 && chkOvf.Float32(f) {
-		panicv.errorf("float32 overflow: %v", f)
-	}
-	return
-}
-func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
-	f = x.DecodeFloat64()
-	if chkOvf.Float32(f) {
-		panicv.errorf("float32 overflow: %v", f)
-	}
-	return
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-type genHelperEncoder struct {
-	M must
-	e *Encoder
-	F fastpathT
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-type genHelperDecoder struct {
-	C checkOverflow
-	d *Decoder
-	F fastpathT
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
-	return f.e.h
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncBinary() bool {
-	return f.e.be // f.e.hh.isBinaryEncoding()
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) IsJSONHandle() bool {
-	return f.e.js
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncFallback(iv interface{}) {
-	// println(">>>>>>>>> EncFallback")
-	// f.e.encodeI(iv, false, false)
-	f.e.encodeValue(reflect.ValueOf(iv), nil, false)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
-	bs, fnerr := iv.MarshalText()
-	f.e.marshal(bs, fnerr, false, cUTF8)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
-	bs, fnerr := iv.MarshalJSON()
-	f.e.marshal(bs, fnerr, true, cUTF8)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
-	bs, fnerr := iv.MarshalBinary()
-	f.e.marshal(bs, fnerr, false, cRAW)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: builtin no longer supported - so we make this method a no-op,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
-
-// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
-// 	if _, ok := f.e.hh.(*BincHandle); ok {
-// 		return timeTypId
-// 	}
-// }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
-	return i2rtid(v)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
-	return f.e.h.getExt(rtid)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
-	f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperEncoder) HasExtensions() bool {
-	return len(f.e.h.extHandle) != 0
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
-	if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
-		f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
-		return true
-	}
-	return false
-}
-
-// ---------------- DECODER FOLLOWS -----------------
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecBasicHandle() *BasicHandle {
-	return f.d.h
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecBinary() bool {
-	return f.d.be // f.d.hh.isBinaryEncoding()
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecScratchBuffer() []byte {
-	return f.d.b[:]
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
-	return &f.d.b
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
-	// println(">>>>>>>>> DecFallback")
-	rv := reflect.ValueOf(iv)
-	if chkPtr {
-		rv = f.d.ensureDecodeable(rv)
-	}
-	f.d.decodeValue(rv, nil, false)
-	// f.d.decodeValueFallback(rv)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecSliceHelperStart() (decSliceHelper, int) {
-	return f.d.decSliceHelperStart()
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) {
-	f.d.structFieldNotFound(index, name)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) {
-	f.d.arrayCannotExpand(sliceLen, streamLen)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
-	fnerr := tm.UnmarshalText(f.d.d.DecodeStringAsBytes())
-	if fnerr != nil {
-		panic(fnerr)
-	}
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
-	// bs := f.dd.DecodeStringAsBytes()
-	// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
-	fnerr := tm.UnmarshalJSON(f.d.nextValueBytes())
-	if fnerr != nil {
-		panic(fnerr)
-	}
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
-	fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, true))
-	if fnerr != nil {
-		panic(fnerr)
-	}
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: builtin no longer supported - so we make this method a no-op,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
-
-// func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
-// 	// Note: builtin is no longer supported - so make this a no-op
-// 	if _, ok := f.d.hh.(*BincHandle); ok {
-// 		return timeTypId
-// 	}
-// 	return 0
-// }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) IsJSONHandle() bool {
-	return f.d.js
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
-	return i2rtid(v)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
-	return f.d.h.getExt(rtid)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
-	f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperDecoder) HasExtensions() bool {
-	return len(f.d.h.extHandle) != 0
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
-	if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
-		f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
-		return true
-	}
-	return false
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
-	return decInferLen(clen, maxlen, unit)
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: no longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }
diff --git a/vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
deleted file mode 100644
index 6aeb856..0000000
--- a/vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
+++ /dev/null
@@ -1,302 +0,0 @@
-/* // +build ignore */
-
-// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// Code generated from gen-helper.go.tmpl - DO NOT EDIT.
-
-package codec
-
-import (
-	"encoding"
-	"reflect"
-)
-
-// GenVersion is the current version of codecgen.
-const GenVersion = {{ .Version }} 
-
-// This file is used to generate helper code for codecgen. 
-// The values here i.e. genHelper(En|De)coder are not to be used directly by 
-// library users. They WILL change continuously and without notice.
-//
-// To help enforce this, we create an unexported type with exported members.
-// The only way to get the type is via the one exported type that we control (somewhat).
-//
-// When static codecs are created for types, they will use this value
-// to perform encoding or decoding of primitives or known slice or map types.
-
-// GenHelperEncoder is exported so that it can be used externally by codecgen.
-//
-// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
-func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
-	ge = genHelperEncoder{e: e}
-	ee = genHelperEncDriver{encDriver: e.e}
-	return 
-}
-
-// GenHelperDecoder is exported so that it can be used externally by codecgen.
-//
-// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
-func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
-	gd = genHelperDecoder{d: d}
-	dd = genHelperDecDriver{decDriver: d.d}
-	return
-}
-
-type genHelperEncDriver struct {
-	encDriver
-}
-
-func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
-func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
-	encStructFieldKey(x.encDriver, keyType, s)
-}
-func (x genHelperEncDriver) EncodeSymbol(s string) {
-	x.encDriver.EncodeString(cUTF8, s)
-}
-
-type genHelperDecDriver struct {
-	decDriver
-	C checkOverflow
-}
-
-func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
-func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
-	return decStructFieldKey(x.decDriver, keyType, buf)
-}
-func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
-	return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
-}
-func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
-	return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
-}
-func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
-	f = x.DecodeFloat64()
-	if chkOverflow32 && chkOvf.Float32(f) {
-		panicv.errorf("float32 overflow: %v", f)
-	}
-	return
-}
-func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
-	f = x.DecodeFloat64()
-	if chkOvf.Float32(f) {
-		panicv.errorf("float32 overflow: %v", f)
-	}
-	return
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-type genHelperEncoder struct {
-	M must
-	e *Encoder
-	F fastpathT 
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-type genHelperDecoder struct {
-	C checkOverflow
-	d *Decoder
-	F fastpathT 
-}
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
-	return f.e.h
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncBinary() bool {
-	return f.e.be // f.e.hh.isBinaryEncoding()
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) IsJSONHandle() bool {
-	return f.e.js
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncFallback(iv interface{}) {
-	// println(">>>>>>>>> EncFallback")
-	// f.e.encodeI(iv, false, false)
-	f.e.encodeValue(reflect.ValueOf(iv), nil, false)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
-	bs, fnerr := iv.MarshalText()
-	f.e.marshal(bs, fnerr, false, cUTF8)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
-	bs, fnerr := iv.MarshalJSON()
-	f.e.marshal(bs, fnerr, true, cUTF8)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
-	bs, fnerr := iv.MarshalBinary()
-	f.e.marshal(bs, fnerr, false, cRAW)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: builtin no longer supported - so we make this method a no-op, 
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
-// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
-// 	if _, ok := f.e.hh.(*BincHandle); ok {
-// 		return timeTypId
-// 	}
-// }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
-	return i2rtid(v)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
-	return f.e.h.getExt(rtid)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
-	f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperEncoder) HasExtensions() bool {
-	return len(f.e.h.extHandle) != 0
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
-	if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
-		f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
-		return true
-	}
-	return false 
-}
-
-// ---------------- DECODER FOLLOWS -----------------
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecBasicHandle() *BasicHandle {
-	return f.d.h
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecBinary() bool {
-     return f.d.be // f.d.hh.isBinaryEncoding()
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecScratchBuffer() []byte {
-	return f.d.b[:]
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
-	return &f.d.b
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
-	// println(">>>>>>>>> DecFallback")
-	rv := reflect.ValueOf(iv)
-	if chkPtr {
-		rv = f.d.ensureDecodeable(rv)
-	}
-	f.d.decodeValue(rv, nil, false)
-	// f.d.decodeValueFallback(rv)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecSliceHelperStart() (decSliceHelper, int) {
-	return f.d.decSliceHelperStart()
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) {
-	f.d.structFieldNotFound(index, name)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) {
-	f.d.arrayCannotExpand(sliceLen, streamLen)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
-	fnerr := tm.UnmarshalText(f.d.d.DecodeStringAsBytes())
-	if fnerr != nil {
-		panic(fnerr)
-	}
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
-	// bs := f.dd.DecodeStringAsBytes()
-	// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
-	fnerr := tm.UnmarshalJSON(f.d.nextValueBytes())
-	if fnerr != nil {
-		panic(fnerr)
-	}
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
-	fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, true))
-	if fnerr != nil {
-		panic(fnerr)
-	}
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecRaw() []byte {	return f.d.rawBytes() }
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: builtin no longer supported - so we make this method a no-op, 
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
-// func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
-// 	// Note: builtin is no longer supported - so make this a no-op
-// 	if _, ok := f.d.hh.(*BincHandle); ok {
-// 		return timeTypId
-// 	}
-// 	return 0
-// }
-
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) IsJSONHandle() bool {
-	return f.d.js 
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
-	return i2rtid(v)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
-	return f.d.h.getExt(rtid)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
-	f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperDecoder) HasExtensions() bool {
-	return len(f.d.h.extHandle) != 0
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: No longer used,
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
-	if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
-		f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
-		return true
-	}
-	return false 
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
-	return decInferLen(clen, maxlen, unit)
-}
-// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
-//
-// Deprecated: no longer used, 
-// but leave in-place so that old generated files continue to work without regeneration.
-func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }
-
diff --git a/vendor/github.com/ugorji/go/codec/gen.generated.go b/vendor/github.com/ugorji/go/codec/gen.generated.go
deleted file mode 100644
index 240ba9f..0000000
--- a/vendor/github.com/ugorji/go/codec/gen.generated.go
+++ /dev/null
@@ -1,164 +0,0 @@
-// +build codecgen.exec
-
-// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-// DO NOT EDIT. THIS FILE IS AUTO-GENERATED FROM gen-dec-(map|array).go.tmpl
-
-const genDecMapTmpl = `
-{{var "v"}} := *{{ .Varname }}
-{{var "l"}} := r.ReadMapStart()
-{{var "bh"}} := z.DecBasicHandle()
-if {{var "v"}} == nil {
-	{{var "rl"}} := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
-	{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
-	*{{ .Varname }} = {{var "v"}}
-}
-var {{var "mk"}} {{ .KTyp }}
-var {{var "mv"}} {{ .Typ }}
-var {{var "mg"}}, {{var "mdn"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
-if {{var "bh"}}.MapValueReset {
-	{{if decElemKindPtr}}{{var "mg"}} = true
-	{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true }
-	{{else if not decElemKindImmutable}}{{var "mg"}} = true
-	{{end}} }
-if {{var "l"}} != 0 {
-{{var "hl"}} := {{var "l"}} > 0 
-	for {{var "j"}} := 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
-	r.ReadMapElemKey() {{/* z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }}) */}}
-	{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
-{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
-		{{var "mk"}} = string({{var "bv"}})
-	}{{ end }}{{if decElemKindPtr}}
-	{{var "ms"}} = true{{end}}
-	if {{var "mg"}} {
-		{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}] 
-		if {{var "mok"}} {
-			{{var "ms"}} = false
-		} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}}
-	} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
-	r.ReadMapElemValue() {{/* z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }}) */}}
-	{{var "mdn"}} = false
-	{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ $y := printf "%vmdn%v" .TempVar .Rand }}{{ decLineVar $x $y }}
-	if {{var "mdn"}} {
-		if {{ var "bh" }}.DeleteOnNilMapValue { delete({{var "v"}}, {{var "mk"}}) } else { {{var "v"}}[{{var "mk"}}] = {{decElemZero}} }
-	} else if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
-		{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
-	}
-}
-} // else len==0: TODO: Should we clear map entries?
-r.ReadMapEnd() {{/* z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) */}}
-`
-
-const genDecListTmpl = `
-{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
-{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
-var {{var "c"}} bool {{/* // changed */}}
-_ = {{var "c"}}{{end}}
-if {{var "l"}} == 0 {
-	{{if isSlice }}if {{var "v"}} == nil {
-		{{var "v"}} = []{{ .Typ }}{}
-		{{var "c"}} = true
-	} else if len({{var "v"}}) != 0 {
-		{{var "v"}} = {{var "v"}}[:0]
-		{{var "c"}} = true
-	} {{else if isChan }}if {{var "v"}} == nil {
-		{{var "v"}} = make({{ .CTyp }}, 0)
-		{{var "c"}} = true
-	} {{end}}
-} else {
-	{{var "hl"}} := {{var "l"}} > 0
-	var {{var "rl"}} int
-	_ =  {{var "rl"}}
-	{{if isSlice }} if {{var "hl"}} {
-	if {{var "l"}} > cap({{var "v"}}) {
-		{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
-		if {{var "rl"}} <= cap({{var "v"}}) {
-			{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
-		} else {
-			{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
-		}
-		{{var "c"}} = true
-	} else if {{var "l"}} != len({{var "v"}}) {
-		{{var "v"}} = {{var "v"}}[:{{var "l"}}]
-		{{var "c"}} = true
-	}
-	} {{end}}
-	var {{var "j"}} int 
-    // var {{var "dn"}} bool 
-	for ; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
-		{{if not isArray}} if {{var "j"}} == 0 && {{var "v"}} == nil {
-			if {{var "hl"}} {
-				{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
-			} else {
-				{{var "rl"}} = {{if isSlice}}8{{else if isChan}}64{{end}}
-			}
-			{{var "v"}} = make({{if isSlice}}[]{{ .Typ }}{{else if isChan}}{{.CTyp}}{{end}}, {{var "rl"}})
-			{{var "c"}} = true 
-		}{{end}}
-		{{var "h"}}.ElemContainerState({{var "j"}})
-        {{/* {{var "dn"}} = r.TryDecodeAsNil() */}}{{/* commented out, as decLineVar handles this already each time */}}
-        {{if isChan}}{{ $x := printf "%[1]vvcx%[2]v" .TempVar .Rand }}var {{$x}} {{ .Typ }}
-		{{ decLineVar $x }}
-		{{var "v"}} <- {{ $x }}
-        // println(">>>> sending ", {{ $x }}, " into ", {{var "v"}}) // TODO: remove this
-        {{else}}{{/* // if indefinite, etc, then expand the slice if necessary */}}
-		var {{var "db"}} bool
-		if {{var "j"}} >= len({{var "v"}}) {
-			{{if isSlice }} {{var "v"}} = append({{var "v"}}, {{ zero }})
-			{{var "c"}} = true
-			{{else}} z.DecArrayCannotExpand(len(v), {{var "j"}}+1); {{var "db"}} = true
-			{{end}}
-		}
-		if {{var "db"}} {
-			z.DecSwallow()
-		} else {
-			{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
-		}
-        {{end}}
-	}
-	{{if isSlice}} if {{var "j"}} < len({{var "v"}}) {
-		{{var "v"}} = {{var "v"}}[:{{var "j"}}]
-		{{var "c"}} = true
-	} else if {{var "j"}} == 0 && {{var "v"}} == nil {
-		{{var "v"}} = make([]{{ .Typ }}, 0)
-		{{var "c"}} = true
-	} {{end}}
-}
-{{var "h"}}.End()
-{{if not isArray }}if {{var "c"}} { 
-	*{{ .Varname }} = {{var "v"}}
-}{{end}}
-`
-
-const genEncChanTmpl = `
-{{.Label}}:
-switch timeout{{.Sfx}} :=  z.EncBasicHandle().ChanRecvTimeout; {
-case timeout{{.Sfx}} == 0: // only consume available
-	for {
-		select {
-		case b{{.Sfx}} := <-{{.Chan}}:
-			{{ .Slice }} = append({{.Slice}}, b{{.Sfx}})
-		default:
-			break {{.Label}}
-		}
-	}
-case timeout{{.Sfx}} > 0: // consume until timeout
-	tt{{.Sfx}} := time.NewTimer(timeout{{.Sfx}})
-	for {
-		select {
-		case b{{.Sfx}} := <-{{.Chan}}:
-			{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
-		case <-tt{{.Sfx}}.C:
-			// close(tt.C)
-			break {{.Label}}
-		}
-	}
-default: // consume until close
-	for b{{.Sfx}} := range {{.Chan}} {
-		{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
-	}
-}
-`
diff --git a/vendor/github.com/ugorji/go/codec/gen.go b/vendor/github.com/ugorji/go/codec/gen.go
deleted file mode 100644
index b4c4031..0000000
--- a/vendor/github.com/ugorji/go/codec/gen.go
+++ /dev/null
@@ -1,2139 +0,0 @@
-// +build codecgen.exec
-
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"bytes"
-	"encoding/base64"
-	"errors"
-	"fmt"
-	"go/format"
-	"io"
-	"io/ioutil"
-	"math/rand"
-	"reflect"
-	"regexp"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-	"text/template"
-	"time"
-	"unicode"
-	"unicode/utf8"
-)
-
-// ---------------------------------------------------
-// codecgen supports the full cycle of reflection-based codec:
-//    - RawExt
-//    - Raw
-//    - Extensions
-//    - (Binary|Text|JSON)(Unm|M)arshal
-//    - generic by-kind
-//
-// This means that, for dynamic things, we MUST use reflection to at least get the reflect.Type.
-// In those areas, we try to only do reflection or interface-conversion when NECESSARY:
-//    - Extensions, only if Extensions are configured.
-//
-// However, codecgen doesn't support the following:
-//   - Canonical option. (codecgen IGNORES it currently)
-//     This is just because it has not been implemented.
-//
-// During encode/decode, Selfer takes precedence.
-// A type implementing Selfer will know how to encode/decode itself statically.
-//
-// The following field types are supported:
-//     array: [n]T
-//     slice: []T
-//     map: map[K]V
-//     primitive: [u]int[n], float(32|64), bool, string
-//     struct
-//
-// ---------------------------------------------------
-// Note that a Selfer cannot call (e|d).(En|De)code on itself,
-// as this will cause a circular reference, as (En|De)code will call Selfer methods.
-// Any type that implements Selfer must implement completely and not fallback to (En|De)code.
-//
-// In addition, code in this file manages the generation of fast-path implementations of
-// encode/decode of slices/maps of primitive keys/values.
-//
-// Users MUST re-generate their implementations whenever the code shape changes.
-// The generated code will panic if it was generated with a version older than the supporting library.
-// ---------------------------------------------------
-//
-// codec framework is very feature rich.
-// When encoding or decoding into an interface, it depends on the runtime type of the interface.
-// The type of the interface may be a named type, an extension, etc.
-// Consequently, we fallback to runtime codec for encoding/decoding interfaces.
-// In addition, we fallback for any value which cannot be guaranteed at runtime.
-// This allows us support ANY value, including any named types, specifically those which
-// do not implement our interfaces (e.g. Selfer).
-//
-// This explains some slowness compared to other code generation codecs (e.g. msgp).
-// This reduction in speed is only seen when your refers to interfaces,
-// e.g. type T struct { A interface{}; B []interface{}; C map[string]interface{} }
-//
-// codecgen will panic if the file was generated with an old version of the library in use.
-//
-// Note:
-//   It was a conscious decision to have gen.go always explicitly call EncodeNil or TryDecodeAsNil.
-//   This way, there isn't a function call overhead just to see that we should not enter a block of code.
-//
-// Note:
-//   codecgen-generated code depends on the variables defined by fast-path.generated.go.
-//   consequently, you cannot run with tags "codecgen notfastpath".
-
-// GenVersion is the current version of codecgen.
-//
-// NOTE: Increment this value each time codecgen changes fundamentally.
-// Fundamental changes are:
-//   - helper methods change (signature change, new ones added, some removed, etc)
-//   - codecgen command line changes
-//
-// v1: Initial Version
-// v2:
-// v3: Changes for Kubernetes:
-//     changes in signature of some unpublished helper methods and codecgen cmdline arguments.
-// v4: Removed separator support from (en|de)cDriver, and refactored codec(gen)
-// v5: changes to support faster json decoding. Let encoder/decoder maintain state of collections.
-// v6: removed unsafe from gen, and now uses codecgen.exec tag
-// v7:
-// v8: current - we now maintain compatibility with old generated code.
-const genVersion = 8
-
-const (
-	genCodecPkg        = "codec1978"
-	genTempVarPfx      = "yy"
-	genTopLevelVarName = "x"
-
-	// ignore canBeNil parameter, and always set to true.
-	// This is because nil can appear anywhere, so we should always check.
-	genAnythingCanBeNil = true
-
-	// if genUseOneFunctionForDecStructMap, make a single codecDecodeSelferFromMap function;
-	// else make codecDecodeSelferFromMap{LenPrefix,CheckBreak} so that conditionals
-	// are not executed a lot.
-	//
-	// From testing, it didn't make much difference in runtime, so keep as true (one function only)
-	genUseOneFunctionForDecStructMap = true
-)
-
-type genStructMapStyle uint8
-
-const (
-	genStructMapStyleConsolidated genStructMapStyle = iota
-	genStructMapStyleLenPrefix
-	genStructMapStyleCheckBreak
-)
-
-var (
-	errGenAllTypesSamePkg  = errors.New("All types must be in the same package")
-	errGenExpectArrayOrMap = errors.New("unexpected type. Expecting array/map/slice")
-
-	genBase64enc  = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789__")
-	genQNameRegex = regexp.MustCompile(`[A-Za-z_.]+`)
-)
-
-type genBuf struct {
-	buf []byte
-}
-
-func (x *genBuf) s(s string) *genBuf              { x.buf = append(x.buf, s...); return x }
-func (x *genBuf) b(s []byte) *genBuf              { x.buf = append(x.buf, s...); return x }
-func (x *genBuf) v() string                       { return string(x.buf) }
-func (x *genBuf) f(s string, args ...interface{}) { x.s(fmt.Sprintf(s, args...)) }
-func (x *genBuf) reset() {
-	if x.buf != nil {
-		x.buf = x.buf[:0]
-	}
-}
-
-// genRunner holds some state used during a Gen run.
-type genRunner struct {
-	w io.Writer      // output
-	c uint64         // counter used for generating varsfx
-	t []reflect.Type // list of types to run selfer on
-
-	tc reflect.Type     // currently running selfer on this type
-	te map[uintptr]bool // types for which the encoder has been created
-	td map[uintptr]bool // types for which the decoder has been created
-	cp string           // codec import path
-
-	im  map[string]reflect.Type // imports to add
-	imn map[string]string       // package names of imports to add
-	imc uint64                  // counter for import numbers
-
-	is map[reflect.Type]struct{} // types seen during import search
-	bp string                    // base PkgPath, for which we are generating for
-
-	cpfx string // codec package prefix
-
-	tm map[reflect.Type]struct{} // types for which enc/dec must be generated
-	ts []reflect.Type            // types for which enc/dec must be generated
-
-	xs string // top level variable/constant suffix
-	hn string // fn helper type name
-
-	ti *TypeInfos
-	// rr *rand.Rand // random generator for file-specific types
-
-	nx bool // no extensions
-}
-
-// Gen will write a complete go file containing Selfer implementations for each
-// type passed. All the types must be in the same package.
-//
-// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINUOUSLY WITHOUT NOTICE.
-func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
-	ti *TypeInfos, typ ...reflect.Type) {
-	// All types passed to this method do not have a codec.Selfer method implemented directly.
-	// codecgen already checks the AST and skips any types that define the codec.Selfer methods.
-	// Consequently, there's no need to check and trim them if they implement codec.Selfer
-
-	if len(typ) == 0 {
-		return
-	}
-	x := genRunner{
-		w:   w,
-		t:   typ,
-		te:  make(map[uintptr]bool),
-		td:  make(map[uintptr]bool),
-		im:  make(map[string]reflect.Type),
-		imn: make(map[string]string),
-		is:  make(map[reflect.Type]struct{}),
-		tm:  make(map[reflect.Type]struct{}),
-		ts:  []reflect.Type{},
-		bp:  genImportPath(typ[0]),
-		xs:  uid,
-		ti:  ti,
-		nx:  noExtensions,
-	}
-	if x.ti == nil {
-		x.ti = defTypeInfos
-	}
-	if x.xs == "" {
-		rr := rand.New(rand.NewSource(time.Now().UnixNano()))
-		x.xs = strconv.FormatInt(rr.Int63n(9999), 10)
-	}
-
-	// gather imports first:
-	x.cp = genImportPath(reflect.TypeOf(x))
-	x.imn[x.cp] = genCodecPkg
-	for _, t := range typ {
-		// fmt.Printf("###########: PkgPath: '%v', Name: '%s'\n", genImportPath(t), t.Name())
-		if genImportPath(t) != x.bp {
-			panic(errGenAllTypesSamePkg)
-		}
-		x.genRefPkgs(t)
-	}
-	if buildTags != "" {
-		x.line("// +build " + buildTags)
-		x.line("")
-	}
-	x.line(`
-
-// Code generated by codecgen - DO NOT EDIT.
-
-`)
-	x.line("package " + pkgName)
-	x.line("")
-	x.line("import (")
-	if x.cp != x.bp {
-		x.cpfx = genCodecPkg + "."
-		x.linef("%s \"%s\"", genCodecPkg, x.cp)
-	}
-	// use a sorted set of im keys, so that we can get consistent output
-	imKeys := make([]string, 0, len(x.im))
-	for k := range x.im {
-		imKeys = append(imKeys, k)
-	}
-	sort.Strings(imKeys)
-	for _, k := range imKeys { // for k, _ := range x.im {
-		if k == x.imn[k] {
-			x.linef("\"%s\"", k)
-		} else {
-			x.linef("%s \"%s\"", x.imn[k], k)
-		}
-	}
-	// add required packages
-	for _, k := range [...]string{"runtime", "errors", "strconv"} { // "reflect", "fmt"
-		if _, ok := x.im[k]; !ok {
-			x.line("\"" + k + "\"")
-		}
-	}
-	x.line(")")
-	x.line("")
-
-	x.line("const (")
-	x.linef("// ----- content types ----")
-	x.linef("codecSelferCcUTF8%s = %v", x.xs, int64(cUTF8))
-	x.linef("codecSelferCcRAW%s = %v", x.xs, int64(cRAW))
-	x.linef("// ----- value types used ----")
-	for _, vt := range [...]valueType{
-		valueTypeArray, valueTypeMap, valueTypeString,
-		valueTypeInt, valueTypeUint, valueTypeFloat} {
-		x.linef("codecSelferValueType%s%s = %v", vt.String(), x.xs, int64(vt))
-	}
-
-	x.linef("codecSelferBitsize%s = uint8(32 << (^uint(0) >> 63))", x.xs)
-	x.line(")")
-	x.line("var (")
-	x.line("errCodecSelferOnlyMapOrArrayEncodeToStruct" + x.xs + " = errors.New(`only encoded map or array can be decoded into a struct`)")
-	x.line(")")
-	x.line("")
-
-	x.hn = "codecSelfer" + x.xs
-	x.line("type " + x.hn + " struct{}")
-	x.line("")
-
-	x.varsfxreset()
-	x.line("func init() {")
-	x.linef("if %sGenVersion != %v {", x.cpfx, genVersion)
-	x.line("_, file, _, _ := runtime.Caller(0)")
-	x.outf(`panic("codecgen version mismatch: current: %v, need " + strconv.FormatInt(int64(%sGenVersion), 10) + ". Re-generate file: " + file)`, genVersion, x.cpfx)
-	// x.out(`panic(fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v", `)
-	// x.linef(`%v, %sGenVersion, file))`, genVersion, x.cpfx)
-	x.linef("}")
-	x.line("if false { // reference the types, but skip this branch at build/run time")
-	// x.line("_ = strconv.ParseInt")
-	var n int
-	// for k, t := range x.im {
-	for _, k := range imKeys {
-		t := x.im[k]
-		x.linef("var v%v %s.%s", n, x.imn[k], t.Name())
-		n++
-	}
-	if n > 0 {
-		x.out("_")
-		for i := 1; i < n; i++ {
-			x.out(", _")
-		}
-		x.out(" = v0")
-		for i := 1; i < n; i++ {
-			x.outf(", v%v", i)
-		}
-	}
-	x.line("} ") // close if false
-	x.line("}")  // close init
-	x.line("")
-
-	// generate rest of type info
-	for _, t := range typ {
-		x.tc = t
-		x.selfer(true)
-		x.selfer(false)
-	}
-
-	for _, t := range x.ts {
-		rtid := rt2id(t)
-		// generate enc functions for all these slice/map types.
-		x.varsfxreset()
-		x.linef("func (x %s) enc%s(v %s%s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), x.cpfx)
-		x.genRequiredMethodVars(true)
-		switch t.Kind() {
-		case reflect.Array, reflect.Slice, reflect.Chan:
-			x.encListFallback("v", t)
-		case reflect.Map:
-			x.encMapFallback("v", t)
-		default:
-			panic(errGenExpectArrayOrMap)
-		}
-		x.line("}")
-		x.line("")
-
-		// generate dec functions for all these slice/map types.
-		x.varsfxreset()
-		x.linef("func (x %s) dec%s(v *%s, d *%sDecoder) {", x.hn, x.genMethodNameT(t), x.genTypeName(t), x.cpfx)
-		x.genRequiredMethodVars(false)
-		switch t.Kind() {
-		case reflect.Array, reflect.Slice, reflect.Chan:
-			x.decListFallback("v", rtid, t)
-		case reflect.Map:
-			x.decMapFallback("v", rtid, t)
-		default:
-			panic(errGenExpectArrayOrMap)
-		}
-		x.line("}")
-		x.line("")
-	}
-
-	x.line("")
-}
-
-func (x *genRunner) checkForSelfer(t reflect.Type, varname string) bool {
-	// return varname != genTopLevelVarName && t != x.tc
-	// the only time we checkForSelfer is if we are not at the TOP of the generated code.
-	return varname != genTopLevelVarName
-}
-
-func (x *genRunner) arr2str(t reflect.Type, s string) string {
-	if t.Kind() == reflect.Array {
-		return s
-	}
-	return ""
-}
-
-func (x *genRunner) genRequiredMethodVars(encode bool) {
-	x.line("var h " + x.hn)
-	if encode {
-		x.line("z, r := " + x.cpfx + "GenHelperEncoder(e)")
-	} else {
-		x.line("z, r := " + x.cpfx + "GenHelperDecoder(d)")
-	}
-	x.line("_, _, _ = h, z, r")
-}
-
-func (x *genRunner) genRefPkgs(t reflect.Type) {
-	if _, ok := x.is[t]; ok {
-		return
-	}
-	x.is[t] = struct{}{}
-	tpkg, tname := genImportPath(t), t.Name()
-	if tpkg != "" && tpkg != x.bp && tpkg != x.cp && tname != "" && tname[0] >= 'A' && tname[0] <= 'Z' {
-		if _, ok := x.im[tpkg]; !ok {
-			x.im[tpkg] = t
-			if idx := strings.LastIndex(tpkg, "/"); idx < 0 {
-				x.imn[tpkg] = tpkg
-			} else {
-				x.imc++
-				x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + genGoIdentifier(tpkg[idx+1:], false)
-			}
-		}
-	}
-	switch t.Kind() {
-	case reflect.Array, reflect.Slice, reflect.Ptr, reflect.Chan:
-		x.genRefPkgs(t.Elem())
-	case reflect.Map:
-		x.genRefPkgs(t.Elem())
-		x.genRefPkgs(t.Key())
-	case reflect.Struct:
-		for i := 0; i < t.NumField(); i++ {
-			if fname := t.Field(i).Name; fname != "" && fname[0] >= 'A' && fname[0] <= 'Z' {
-				x.genRefPkgs(t.Field(i).Type)
-			}
-		}
-	}
-}
-
-func (x *genRunner) varsfx() string {
-	x.c++
-	return strconv.FormatUint(x.c, 10)
-}
-
-func (x *genRunner) varsfxreset() {
-	x.c = 0
-}
-
-func (x *genRunner) out(s string) {
-	_, err := io.WriteString(x.w, s)
-	if err != nil {
-		panic(err)
-	}
-}
-
-func (x *genRunner) outf(s string, params ...interface{}) {
-	_, err := fmt.Fprintf(x.w, s, params...)
-	if err != nil {
-		panic(err)
-	}
-}
-
-func (x *genRunner) line(s string) {
-	x.out(s)
-	if len(s) == 0 || s[len(s)-1] != '\n' {
-		x.out("\n")
-	}
-}
-
-func (x *genRunner) linef(s string, params ...interface{}) {
-	x.outf(s, params...)
-	if len(s) == 0 || s[len(s)-1] != '\n' {
-		x.out("\n")
-	}
-}
-
-func (x *genRunner) genTypeName(t reflect.Type) (n string) {
-	// defer func() { fmt.Printf(">>>> ####: genTypeName: t: %v, name: '%s'\n", t, n) }()
-
-	// if the type has a PkgPath, which doesn't match the current package,
-	// then include it.
-	// We cannot depend on t.String() because it includes current package,
-	// or t.PkgPath because it includes full import path,
-	//
-	var ptrPfx string
-	for t.Kind() == reflect.Ptr {
-		ptrPfx += "*"
-		t = t.Elem()
-	}
-	if tn := t.Name(); tn != "" {
-		return ptrPfx + x.genTypeNamePrim(t)
-	}
-	switch t.Kind() {
-	case reflect.Map:
-		return ptrPfx + "map[" + x.genTypeName(t.Key()) + "]" + x.genTypeName(t.Elem())
-	case reflect.Slice:
-		return ptrPfx + "[]" + x.genTypeName(t.Elem())
-	case reflect.Array:
-		return ptrPfx + "[" + strconv.FormatInt(int64(t.Len()), 10) + "]" + x.genTypeName(t.Elem())
-	case reflect.Chan:
-		return ptrPfx + t.ChanDir().String() + " " + x.genTypeName(t.Elem())
-	default:
-		if t == intfTyp {
-			return ptrPfx + "interface{}"
-		} else {
-			return ptrPfx + x.genTypeNamePrim(t)
-		}
-	}
-}
-
-func (x *genRunner) genTypeNamePrim(t reflect.Type) (n string) {
-	if t.Name() == "" {
-		return t.String()
-	} else if genImportPath(t) == "" || genImportPath(t) == genImportPath(x.tc) {
-		return t.Name()
-	} else {
-		return x.imn[genImportPath(t)] + "." + t.Name()
-		// return t.String() // best way to get the package name inclusive
-	}
-}
-
-func (x *genRunner) genZeroValueR(t reflect.Type) string {
-	// if t is a named type, w
-	switch t.Kind() {
-	case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func,
-		reflect.Slice, reflect.Map, reflect.Invalid:
-		return "nil"
-	case reflect.Bool:
-		return "false"
-	case reflect.String:
-		return `""`
-	case reflect.Struct, reflect.Array:
-		return x.genTypeName(t) + "{}"
-	default: // all numbers
-		return "0"
-	}
-}
-
-func (x *genRunner) genMethodNameT(t reflect.Type) (s string) {
-	return genMethodNameT(t, x.tc)
-}
-
-func (x *genRunner) selfer(encode bool) {
-	t := x.tc
-	t0 := t
-	// always make decode use a pointer receiver,
-	// and structs/arrays always use a ptr receiver (encode|decode)
-	isptr := !encode || t.Kind() == reflect.Array || (t.Kind() == reflect.Struct && t != timeTyp)
-	x.varsfxreset()
-
-	fnSigPfx := "func (" + genTopLevelVarName + " "
-	if isptr {
-		fnSigPfx += "*"
-	}
-	fnSigPfx += x.genTypeName(t)
-	x.out(fnSigPfx)
-
-	if isptr {
-		t = reflect.PtrTo(t)
-	}
-	if encode {
-		x.line(") CodecEncodeSelf(e *" + x.cpfx + "Encoder) {")
-		x.genRequiredMethodVars(true)
-		x.encVar(genTopLevelVarName, t)
-	} else {
-		x.line(") CodecDecodeSelf(d *" + x.cpfx + "Decoder) {")
-		x.genRequiredMethodVars(false)
-		// do not use decVar, as there is no need to check TryDecodeAsNil
-		// or way to elegantly handle that, and also setting it to a
-		// non-nil value doesn't affect the pointer passed.
-		// x.decVar(genTopLevelVarName, t, false)
-		x.dec(genTopLevelVarName, t0, true)
-	}
-	x.line("}")
-	x.line("")
-
-	if encode || t0.Kind() != reflect.Struct {
-		return
-	}
-
-	// write is containerMap
-	if genUseOneFunctionForDecStructMap {
-		x.out(fnSigPfx)
-		x.line(") codecDecodeSelfFromMap(l int, d *" + x.cpfx + "Decoder) {")
-		x.genRequiredMethodVars(false)
-		x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleConsolidated)
-		x.line("}")
-		x.line("")
-	} else {
-		x.out(fnSigPfx)
-		x.line(") codecDecodeSelfFromMapLenPrefix(l int, d *" + x.cpfx + "Decoder) {")
-		x.genRequiredMethodVars(false)
-		x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleLenPrefix)
-		x.line("}")
-		x.line("")
-
-		x.out(fnSigPfx)
-		x.line(") codecDecodeSelfFromMapCheckBreak(l int, d *" + x.cpfx + "Decoder) {")
-		x.genRequiredMethodVars(false)
-		x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleCheckBreak)
-		x.line("}")
-		x.line("")
-	}
-
-	// write containerArray
-	x.out(fnSigPfx)
-	x.line(") codecDecodeSelfFromArray(l int, d *" + x.cpfx + "Decoder) {")
-	x.genRequiredMethodVars(false)
-	x.decStructArray(genTopLevelVarName, "l", "return", rt2id(t0), t0)
-	x.line("}")
-	x.line("")
-
-}
-
-// used for chan, array, slice, map
-func (x *genRunner) xtraSM(varname string, t reflect.Type, encode, isptr bool) {
-	var ptrPfx, addrPfx string
-	if isptr {
-		ptrPfx = "*"
-	} else {
-		addrPfx = "&"
-	}
-	if encode {
-		x.linef("h.enc%s((%s%s)(%s), e)", x.genMethodNameT(t), ptrPfx, x.genTypeName(t), varname)
-	} else {
-		x.linef("h.dec%s((*%s)(%s%s), d)", x.genMethodNameT(t), x.genTypeName(t), addrPfx, varname)
-	}
-	x.registerXtraT(t)
-}
-
-func (x *genRunner) registerXtraT(t reflect.Type) {
-	// recursively register the types
-	if _, ok := x.tm[t]; ok {
-		return
-	}
-	var tkey reflect.Type
-	switch t.Kind() {
-	case reflect.Chan, reflect.Slice, reflect.Array:
-	case reflect.Map:
-		tkey = t.Key()
-	default:
-		return
-	}
-	x.tm[t] = struct{}{}
-	x.ts = append(x.ts, t)
-	// check if this refers to any xtra types eg. a slice of array: add the array
-	x.registerXtraT(t.Elem())
-	if tkey != nil {
-		x.registerXtraT(tkey)
-	}
-}
-
-// encVar will encode a variable.
-// The parameter, t, is the reflect.Type of the variable itself
-func (x *genRunner) encVar(varname string, t reflect.Type) {
-	// fmt.Printf(">>>>>> varname: %s, t: %v\n", varname, t)
-	var checkNil bool
-	switch t.Kind() {
-	case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Chan:
-		checkNil = true
-	}
-	if checkNil {
-		x.linef("if %s == nil { r.EncodeNil() } else { ", varname)
-	}
-
-	switch t.Kind() {
-	case reflect.Ptr:
-		telem := t.Elem()
-		tek := telem.Kind()
-		if tek == reflect.Array || (tek == reflect.Struct && telem != timeTyp) {
-			x.enc(varname, genNonPtr(t))
-			break
-		}
-		i := x.varsfx()
-		x.line(genTempVarPfx + i + " := *" + varname)
-		x.enc(genTempVarPfx+i, genNonPtr(t))
-	case reflect.Struct, reflect.Array:
-		if t == timeTyp {
-			x.enc(varname, t)
-			break
-		}
-		i := x.varsfx()
-		x.line(genTempVarPfx + i + " := &" + varname)
-		x.enc(genTempVarPfx+i, t)
-	default:
-		x.enc(varname, t)
-	}
-
-	if checkNil {
-		x.line("}")
-	}
-
-}
-
-// enc will encode a variable (varname) of type t, where t represents T.
-// if t is !time.Time and t is of kind reflect.Struct or reflect.Array, varname is of type *T
-// (to prevent copying),
-// else t is of type T
-func (x *genRunner) enc(varname string, t reflect.Type) {
-	rtid := rt2id(t)
-	ti2 := x.ti.get(rtid, t)
-	// We call CodecEncodeSelf if one of the following are honored:
-	//   - the type already implements Selfer, call that
-	//   - the type has a Selfer implementation just created, use that
-	//   - the type is in the list of the ones we will generate for, but it is not currently being generated
-
-	mi := x.varsfx()
-	// tptr := reflect.PtrTo(t)
-	tk := t.Kind()
-	if x.checkForSelfer(t, varname) {
-		if tk == reflect.Array || (tk == reflect.Struct && rtid != timeTypId) { // varname is of type *T
-			// if tptr.Implements(selferTyp) || t.Implements(selferTyp) {
-			if ti2.isFlag(typeInfoFlagIsZeroerPtr) || ti2.isFlag(typeInfoFlagIsZeroer) {
-				x.line(varname + ".CodecEncodeSelf(e)")
-				return
-			}
-		} else { // varname is of type T
-			if ti2.cs { // t.Implements(selferTyp) {
-				x.line(varname + ".CodecEncodeSelf(e)")
-				return
-			} else if ti2.csp { // tptr.Implements(selferTyp) {
-				x.linef("%ssf%s := &%s", genTempVarPfx, mi, varname)
-				x.linef("%ssf%s.CodecEncodeSelf(e)", genTempVarPfx, mi)
-				return
-			}
-		}
-
-		if _, ok := x.te[rtid]; ok {
-			x.line(varname + ".CodecEncodeSelf(e)")
-			return
-		}
-	}
-
-	inlist := false
-	for _, t0 := range x.t {
-		if t == t0 {
-			inlist = true
-			if x.checkForSelfer(t, varname) {
-				x.line(varname + ".CodecEncodeSelf(e)")
-				return
-			}
-			break
-		}
-	}
-
-	var rtidAdded bool
-	if t == x.tc {
-		x.te[rtid] = true
-		rtidAdded = true
-	}
-
-	// check if
-	//   - type is time.Time, RawExt, Raw
-	//   - the type implements (Text|JSON|Binary)(Unm|M)arshal
-
-	x.line("if false {")           //start if block
-	defer func() { x.line("}") }() //end if block
-
-	if t == timeTyp {
-		x.linef("} else { r.EncodeTime(%s)", varname)
-		return
-	}
-	if t == rawTyp {
-		x.linef("} else { z.EncRaw(%s)", varname)
-		return
-	}
-	if t == rawExtTyp {
-		x.linef("} else { r.EncodeRawExt(%s, e)", varname)
-		return
-	}
-	// only check for extensions if the type is named, and has a packagePath.
-	var arrayOrStruct = tk == reflect.Array || tk == reflect.Struct // meaning varname if of type *T
-	if !x.nx && genImportPath(t) != "" && t.Name() != "" {
-		yy := fmt.Sprintf("%sxt%s", genTempVarPfx, mi)
-		x.linef("} else if %s := z.Extension(z.I2Rtid(%s)); %s != nil { z.EncExtension(%s, %s) ", yy, varname, yy, varname, yy)
-	}
-	if arrayOrStruct { // varname is of type *T
-		if ti2.bm || ti2.bmp { // t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) {
-			x.linef("} else if z.EncBinary() { z.EncBinaryMarshal(%v) ", varname)
-		}
-		if ti2.jm || ti2.jmp { // t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", varname)
-		} else if ti2.tm || ti2.tmp { // t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() { z.EncTextMarshal(%v) ", varname)
-		}
-	} else { // varname is of type T
-		if ti2.bm { // t.Implements(binaryMarshalerTyp) {
-			x.linef("} else if z.EncBinary() { z.EncBinaryMarshal(%v) ", varname)
-		} else if ti2.bmp { // tptr.Implements(binaryMarshalerTyp) {
-			x.linef("} else if z.EncBinary() { z.EncBinaryMarshal(&%v) ", varname)
-		}
-		if ti2.jm { // t.Implements(jsonMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", varname)
-		} else if ti2.jmp { // tptr.Implements(jsonMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(&%v) ", varname)
-		} else if ti2.tm { // t.Implements(textMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() { z.EncTextMarshal(%v) ", varname)
-		} else if ti2.tmp { // tptr.Implements(textMarshalerTyp) {
-			x.linef("} else if !z.EncBinary() { z.EncTextMarshal(&%v) ", varname)
-		}
-	}
-	x.line("} else {")
-
-	switch t.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		x.line("r.EncodeInt(int64(" + varname + "))")
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		x.line("r.EncodeUint(uint64(" + varname + "))")
-	case reflect.Float32:
-		x.line("r.EncodeFloat32(float32(" + varname + "))")
-	case reflect.Float64:
-		x.line("r.EncodeFloat64(float64(" + varname + "))")
-	case reflect.Bool:
-		x.line("r.EncodeBool(bool(" + varname + "))")
-	case reflect.String:
-		x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + ", string(" + varname + "))")
-	case reflect.Chan:
-		x.xtraSM(varname, t, true, false)
-		// x.encListFallback(varname, rtid, t)
-	case reflect.Array:
-		x.xtraSM(varname, t, true, true)
-	case reflect.Slice:
-		// if nil, call dedicated function
-		// if a []uint8, call dedicated function
-		// if a known fastpath slice, call dedicated function
-		// else write encode function in-line.
-		// - if elements are primitives or Selfers, call dedicated function on each member.
-		// - else call Encoder.encode(XXX) on it.
-		if rtid == uint8SliceTypId {
-			x.line("r.EncodeStringBytes(codecSelferCcRAW" + x.xs + ", []byte(" + varname + "))")
-		} else if fastpathAV.index(rtid) != -1 {
-			g := x.newGenV(t)
-			x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", e)")
-		} else {
-			x.xtraSM(varname, t, true, false)
-			// x.encListFallback(varname, rtid, t)
-		}
-	case reflect.Map:
-		// if nil, call dedicated function
-		// if a known fastpath map, call dedicated function
-		// else write encode function in-line.
-		// - if elements are primitives or Selfers, call dedicated function on each member.
-		// - else call Encoder.encode(XXX) on it.
-		// x.line("if " + varname + " == nil { \nr.EncodeNil()\n } else { ")
-		if fastpathAV.index(rtid) != -1 {
-			g := x.newGenV(t)
-			x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", e)")
-		} else {
-			x.xtraSM(varname, t, true, false)
-			// x.encMapFallback(varname, rtid, t)
-		}
-	case reflect.Struct:
-		if !inlist {
-			delete(x.te, rtid)
-			x.line("z.EncFallback(" + varname + ")")
-			break
-		}
-		x.encStruct(varname, rtid, t)
-	default:
-		if rtidAdded {
-			delete(x.te, rtid)
-		}
-		x.line("z.EncFallback(" + varname + ")")
-	}
-}
-
-func (x *genRunner) encZero(t reflect.Type) {
-	switch t.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		x.line("r.EncodeInt(0)")
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		x.line("r.EncodeUint(0)")
-	case reflect.Float32:
-		x.line("r.EncodeFloat32(0)")
-	case reflect.Float64:
-		x.line("r.EncodeFloat64(0)")
-	case reflect.Bool:
-		x.line("r.EncodeBool(false)")
-	case reflect.String:
-		x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + `, "")`)
-	default:
-		x.line("r.EncodeNil()")
-	}
-}
-
-func (x *genRunner) encOmitEmptyLine(t2 reflect.StructField, varname string, buf *genBuf) {
-	// smartly check omitEmpty on a struct type, as it may contain uncomparable map/slice/etc.
-	// also, for maps/slices/arrays, check if len ! 0 (not if == zero value)
-	varname2 := varname + "." + t2.Name
-	switch t2.Type.Kind() {
-	case reflect.Struct:
-		rtid2 := rt2id(t2.Type)
-		ti2 := x.ti.get(rtid2, t2.Type)
-		// fmt.Printf(">>>> structfield: omitempty: type: %s, field: %s\n", t2.Type.Name(), t2.Name)
-		if ti2.rtid == timeTypId {
-			buf.s("!(").s(varname2).s(".IsZero())")
-			break
-		}
-		if ti2.isFlag(typeInfoFlagIsZeroerPtr) || ti2.isFlag(typeInfoFlagIsZeroer) {
-			buf.s("!(").s(varname2).s(".IsZero())")
-			break
-		}
-		if ti2.isFlag(typeInfoFlagComparable) {
-			buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
-			break
-		}
-		// buf.s("(")
-		buf.s("false")
-		for i, n := 0, t2.Type.NumField(); i < n; i++ {
-			f := t2.Type.Field(i)
-			if f.PkgPath != "" { // unexported
-				continue
-			}
-			buf.s(" || ")
-			x.encOmitEmptyLine(f, varname2, buf)
-		}
-		//buf.s(")")
-	case reflect.Bool:
-		buf.s(varname2)
-	case reflect.Map, reflect.Slice, reflect.Array, reflect.Chan:
-		buf.s("len(").s(varname2).s(") != 0")
-	default:
-		buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
-	}
-}
-
-func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
-	// Use knowledge from structfieldinfo (mbs, encodable fields. Ignore omitempty. )
-	// replicate code in kStruct i.e. for each field, deref type to non-pointer, and call x.enc on it
-
-	// if t === type currently running selfer on, do for all
-	ti := x.ti.get(rtid, t)
-	i := x.varsfx()
-	sepVarname := genTempVarPfx + "sep" + i
-	numfieldsvar := genTempVarPfx + "q" + i
-	ti2arrayvar := genTempVarPfx + "r" + i
-	struct2arrvar := genTempVarPfx + "2arr" + i
-
-	x.line(sepVarname + " := !z.EncBinary()")
-	x.linef("%s := z.EncBasicHandle().StructToArray", struct2arrvar)
-	x.linef("_, _ = %s, %s", sepVarname, struct2arrvar)
-	x.linef("const %s bool = %v // struct tag has 'toArray'", ti2arrayvar, ti.toArray)
-
-	tisfi := ti.sfiSrc // always use sequence from file. decStruct expects same thing.
-
-	// var nn int
-	// due to omitEmpty, we need to calculate the
-	// number of non-empty things we write out first.
-	// This is required as we need to pre-determine the size of the container,
-	// to support length-prefixing.
-	if ti.anyOmitEmpty {
-		x.linef("var %s = [%v]bool{ // should field at this index be written?", numfieldsvar, len(tisfi))
-
-		for j, si := range tisfi {
-			_ = j
-			if !si.omitEmpty() {
-				// x.linef("%s[%v] = true // %s", numfieldsvar, j, si.fieldName)
-				x.linef("true, // %s", si.fieldName)
-				// nn++
-				continue
-			}
-			var t2 reflect.StructField
-			var omitline genBuf
-			{
-				t2typ := t
-				varname3 := varname
-				// go through the loop, record the t2 field explicitly,
-				// and gather the omit line if embedded in pointers.
-				for ij, ix := range si.is {
-					if uint8(ij) == si.nis {
-						break
-					}
-					for t2typ.Kind() == reflect.Ptr {
-						t2typ = t2typ.Elem()
-					}
-					t2 = t2typ.Field(int(ix))
-					t2typ = t2.Type
-					varname3 = varname3 + "." + t2.Name
-					// do not include actual field in the omit line.
-					// that is done subsequently (right after - below).
-					if uint8(ij+1) < si.nis && t2typ.Kind() == reflect.Ptr {
-						omitline.s(varname3).s(" != nil && ")
-					}
-				}
-			}
-			x.encOmitEmptyLine(t2, varname, &omitline)
-			x.linef("%s, // %s", omitline.v(), si.fieldName)
-		}
-		x.line("}")
-		x.linef("_ = %s", numfieldsvar)
-	}
-	// x.linef("var %snn%s int", genTempVarPfx, i)
-	x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray {
-	x.linef("r.WriteArrayStart(%d)", len(tisfi))
-	x.linef("} else {") // if not ti.toArray
-	if ti.anyOmitEmpty {
-		// nn = 0
-		// x.linef("var %snn%s = %v", genTempVarPfx, i, nn)
-		x.linef("var %snn%s int", genTempVarPfx, i)
-		x.linef("for _, b := range %s { if b { %snn%s++ } }", numfieldsvar, genTempVarPfx, i)
-		x.linef("r.WriteMapStart(%snn%s)", genTempVarPfx, i)
-		x.linef("%snn%s = %v", genTempVarPfx, i, 0)
-	} else {
-		x.linef("r.WriteMapStart(%d)", len(tisfi))
-	}
-	x.line("}") // close if not StructToArray
-
-	for j, si := range tisfi {
-		i := x.varsfx()
-		isNilVarName := genTempVarPfx + "n" + i
-		var labelUsed bool
-		var t2 reflect.StructField
-		{
-			t2typ := t
-			varname3 := varname
-			for ij, ix := range si.is {
-				if uint8(ij) == si.nis {
-					break
-				}
-				for t2typ.Kind() == reflect.Ptr {
-					t2typ = t2typ.Elem()
-				}
-				t2 = t2typ.Field(int(ix))
-				t2typ = t2.Type
-				varname3 = varname3 + "." + t2.Name
-				if t2typ.Kind() == reflect.Ptr {
-					if !labelUsed {
-						x.line("var " + isNilVarName + " bool")
-					}
-					x.line("if " + varname3 + " == nil { " + isNilVarName + " = true ")
-					x.line("goto LABEL" + i)
-					x.line("}")
-					labelUsed = true
-					// "varname3 = new(" + x.genTypeName(t3.Elem()) + ") }")
-				}
-			}
-			// t2 = t.FieldByIndex(si.is)
-		}
-		if labelUsed {
-			x.line("LABEL" + i + ":")
-		}
-		// if the type of the field is a Selfer, or one of the ones
-
-		x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray
-		if labelUsed {
-			x.linef("if %s { r.WriteArrayElem(); r.EncodeNil() } else { ", isNilVarName)
-		}
-		x.line("r.WriteArrayElem()")
-		if si.omitEmpty() {
-			x.linef("if %s[%v] {", numfieldsvar, j)
-		}
-		x.encVar(varname+"."+t2.Name, t2.Type)
-		if si.omitEmpty() {
-			x.linef("} else {")
-			x.encZero(t2.Type)
-			x.linef("}")
-		}
-		if labelUsed {
-			x.line("}")
-		}
-
-		x.linef("} else {") // if not ti.toArray
-
-		if si.omitEmpty() {
-			x.linef("if %s[%v] {", numfieldsvar, j)
-		}
-		x.line("r.WriteMapElemKey()")
-
-		// x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + ", `" + si.encName + "`)")
-		// emulate EncStructFieldKey
-		switch ti.keyType {
-		case valueTypeInt:
-			x.linef("r.EncodeInt(z.M.Int(strconv.ParseInt(`%s`, 10, 64)))", si.encName)
-		case valueTypeUint:
-			x.linef("r.EncodeUint(z.M.Uint(strconv.ParseUint(`%s`, 10, 64)))", si.encName)
-		case valueTypeFloat:
-			x.linef("r.EncodeFloat64(z.M.Float(strconv.ParseFloat(`%s`, 64)))", si.encName)
-		default: // string
-			x.linef("r.EncodeString(codecSelferCcUTF8%s, `%s`)", x.xs, si.encName)
-		}
-		// x.linef("r.EncStructFieldKey(codecSelferValueType%s%s, `%s`)", ti.keyType.String(), x.xs, si.encName)
-		x.line("r.WriteMapElemValue()")
-		if labelUsed {
-			x.line("if " + isNilVarName + " { r.EncodeNil() } else { ")
-			x.encVar(varname+"."+t2.Name, t2.Type)
-			x.line("}")
-		} else {
-			x.encVar(varname+"."+t2.Name, t2.Type)
-		}
-		if si.omitEmpty() {
-			x.line("}")
-		}
-		x.linef("} ") // end if/else ti.toArray
-	}
-	x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray {
-	x.line("r.WriteArrayEnd()")
-	x.line("} else {")
-	x.line("r.WriteMapEnd()")
-	x.line("}")
-
-}
-
-func (x *genRunner) encListFallback(varname string, t reflect.Type) {
-	elemBytes := t.Elem().Kind() == reflect.Uint8
-	if t.AssignableTo(uint8SliceTyp) {
-		x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, []byte(%s))", x.xs, varname)
-		return
-	}
-	if t.Kind() == reflect.Array && elemBytes {
-		x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, ((*[%d]byte)(%s))[:])", x.xs, t.Len(), varname)
-		return
-	}
-	i := x.varsfx()
-	if t.Kind() == reflect.Chan {
-		type ts struct {
-			Label, Chan, Slice, Sfx string
-		}
-		tm, err := template.New("").Parse(genEncChanTmpl)
-		if err != nil {
-			panic(err)
-		}
-		x.linef("if %s == nil { r.EncodeNil() } else { ", varname)
-		x.linef("var sch%s []%s", i, x.genTypeName(t.Elem()))
-		err = tm.Execute(x.w, &ts{"Lsch" + i, varname, "sch" + i, i})
-		if err != nil {
-			panic(err)
-		}
-		// x.linef("%s = sch%s", varname, i)
-		if elemBytes {
-			x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, []byte(%s))", x.xs, "sch"+i)
-			x.line("}")
-			return
-		}
-		varname = "sch" + i
-	}
-
-	x.line("r.WriteArrayStart(len(" + varname + "))")
-	x.linef("for _, %sv%s := range %s {", genTempVarPfx, i, varname)
-	x.line("r.WriteArrayElem()")
-
-	x.encVar(genTempVarPfx+"v"+i, t.Elem())
-	x.line("}")
-	x.line("r.WriteArrayEnd()")
-	if t.Kind() == reflect.Chan {
-		x.line("}")
-	}
-}
-
-func (x *genRunner) encMapFallback(varname string, t reflect.Type) {
-	// TODO: expand this to handle canonical.
-	i := x.varsfx()
-	x.line("r.WriteMapStart(len(" + varname + "))")
-	x.linef("for %sk%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname)
-	x.line("r.WriteMapElemKey()")
-	x.encVar(genTempVarPfx+"k"+i, t.Key())
-	x.line("r.WriteMapElemValue()")
-	x.encVar(genTempVarPfx+"v"+i, t.Elem())
-	x.line("}")
-	x.line("r.WriteMapEnd()")
-}
-
-func (x *genRunner) decVarInitPtr(varname, nilvar string, t reflect.Type, si *structFieldInfo,
-	newbuf, nilbuf *genBuf) (t2 reflect.StructField) {
-	//we must accommodate anonymous fields, where the embedded field is a nil pointer in the value.
-	// t2 = t.FieldByIndex(si.is)
-	t2typ := t
-	varname3 := varname
-	t2kind := t2typ.Kind()
-	var nilbufed bool
-	if si != nil {
-		for ij, ix := range si.is {
-			if uint8(ij) == si.nis {
-				break
-			}
-			for t2typ.Kind() == reflect.Ptr {
-				t2typ = t2typ.Elem()
-			}
-			t2 = t2typ.Field(int(ix))
-			t2typ = t2.Type
-			varname3 = varname3 + "." + t2.Name
-			t2kind = t2typ.Kind()
-			if t2kind != reflect.Ptr {
-				continue
-			}
-			if newbuf != nil {
-				newbuf.f("if %s == nil { %s = new(%s) }\n", varname3, varname3, x.genTypeName(t2typ.Elem()))
-			}
-			if nilbuf != nil {
-				if !nilbufed {
-					nilbuf.s("if true")
-					nilbufed = true
-				}
-				nilbuf.s(" && ").s(varname3).s(" != nil")
-			}
-		}
-	}
-	// if t2typ.Kind() == reflect.Ptr {
-	// 	varname3 = varname3 + t2.Name
-	// }
-	if nilbuf != nil {
-		if nilbufed {
-			nilbuf.s(" { ")
-		}
-		if nilvar != "" {
-			nilbuf.s(nilvar).s(" = true")
-		} else if tk := t2typ.Kind(); tk == reflect.Ptr {
-			if strings.IndexByte(varname3, '.') != -1 || strings.IndexByte(varname3, '[') != -1 {
-				nilbuf.s(varname3).s(" = nil")
-			} else {
-				nilbuf.s("*").s(varname3).s(" = ").s(x.genZeroValueR(t2typ.Elem()))
-			}
-		} else {
-			nilbuf.s(varname3).s(" = ").s(x.genZeroValueR(t2typ))
-		}
-		if nilbufed {
-			nilbuf.s("}")
-		}
-	}
-	return t2
-}
-
-// decVar takes a variable called varname, of type t
-func (x *genRunner) decVarMain(varname, rand string, t reflect.Type, checkNotNil bool) {
-	// We only encode as nil if a nillable value.
-	// This removes some of the wasted checks for TryDecodeAsNil.
-	// We need to think about this more, to see what happens if omitempty, etc
-	// cause a nil value to be stored when something is expected.
-	// This could happen when decoding from a struct encoded as an array.
-	// For that, decVar should be called with canNil=true, to force true as its value.
-	var varname2 string
-	if t.Kind() != reflect.Ptr {
-		if t.PkgPath() != "" || !x.decTryAssignPrimitive(varname, t, false) {
-			x.dec(varname, t, false)
-		}
-	} else {
-		if checkNotNil {
-			x.linef("if %s == nil { %s = new(%s) }", varname, varname, x.genTypeName(t.Elem()))
-		}
-		// Ensure we set underlying ptr to a non-nil value (so we can deref to it later).
-		// There's a chance of a **T in here which is nil.
-		var ptrPfx string
-		for t = t.Elem(); t.Kind() == reflect.Ptr; t = t.Elem() {
-			ptrPfx += "*"
-			if checkNotNil {
-				x.linef("if %s%s == nil { %s%s = new(%s)}",
-					ptrPfx, varname, ptrPfx, varname, x.genTypeName(t))
-			}
-		}
-		// Should we create temp var if a slice/map indexing? No. dec(...) can now handle it.
-
-		if ptrPfx == "" {
-			x.dec(varname, t, true)
-		} else {
-			varname2 = genTempVarPfx + "z" + rand
-			x.line(varname2 + " := " + ptrPfx + varname)
-			x.dec(varname2, t, true)
-		}
-	}
-}
-
-// decVar takes a variable called varname, of type t
-func (x *genRunner) decVar(varname, nilvar string, t reflect.Type, canBeNil, checkNotNil bool) {
-	i := x.varsfx()
-
-	// We only encode as nil if a nillable value.
-	// This removes some of the wasted checks for TryDecodeAsNil.
-	// We need to think about this more, to see what happens if omitempty, etc
-	// cause a nil value to be stored when something is expected.
-	// This could happen when decoding from a struct encoded as an array.
-	// For that, decVar should be called with canNil=true, to force true as its value.
-
-	if !canBeNil {
-		canBeNil = genAnythingCanBeNil || !genIsImmutable(t)
-	}
-
-	if canBeNil {
-		var buf genBuf
-		x.decVarInitPtr(varname, nilvar, t, nil, nil, &buf)
-		x.linef("if r.TryDecodeAsNil() { %s } else {", buf.buf)
-	} else {
-		x.line("// cannot be nil")
-	}
-
-	x.decVarMain(varname, i, t, checkNotNil)
-
-	if canBeNil {
-		x.line("} ")
-	}
-}
-
-// dec will decode a variable (varname) of type t or ptrTo(t) if isptr==true.
-// t is always a basetype (i.e. not of kind reflect.Ptr).
-func (x *genRunner) dec(varname string, t reflect.Type, isptr bool) {
-	// assumptions:
-	//   - the varname is to a pointer already. No need to take address of it
-	//   - t is always a baseType T (not a *T, etc).
-	rtid := rt2id(t)
-	ti2 := x.ti.get(rtid, t)
-	// tptr := reflect.PtrTo(t)
-	if x.checkForSelfer(t, varname) {
-		if ti2.cs || ti2.csp { // t.Implements(selferTyp) || tptr.Implements(selferTyp) {
-			x.line(varname + ".CodecDecodeSelf(d)")
-			return
-		}
-		if _, ok := x.td[rtid]; ok {
-			x.line(varname + ".CodecDecodeSelf(d)")
-			return
-		}
-	}
-
-	inlist := false
-	for _, t0 := range x.t {
-		if t == t0 {
-			inlist = true
-			if x.checkForSelfer(t, varname) {
-				x.line(varname + ".CodecDecodeSelf(d)")
-				return
-			}
-			break
-		}
-	}
-
-	var rtidAdded bool
-	if t == x.tc {
-		x.td[rtid] = true
-		rtidAdded = true
-	}
-
-	// check if
-	//   - type is time.Time, Raw, RawExt
-	//   - the type implements (Text|JSON|Binary)(Unm|M)arshal
-
-	mi := x.varsfx()
-	// x.linef("%sm%s := z.DecBinary()", genTempVarPfx, mi)
-	// x.linef("_ = %sm%s", genTempVarPfx, mi)
-	x.line("if false {")           //start if block
-	defer func() { x.line("}") }() //end if block
-
-	var ptrPfx, addrPfx string
-	if isptr {
-		ptrPfx = "*"
-	} else {
-		addrPfx = "&"
-	}
-	if t == timeTyp {
-		x.linef("} else { %s%v = r.DecodeTime()", ptrPfx, varname)
-		return
-	}
-	if t == rawTyp {
-		x.linef("} else { %s%v = z.DecRaw()", ptrPfx, varname)
-		return
-	}
-
-	if t == rawExtTyp {
-		x.linef("} else { r.DecodeExt(%s%v, 0, nil)", addrPfx, varname)
-		return
-	}
-
-	// only check for extensions if the type is named, and has a packagePath.
-	if !x.nx && genImportPath(t) != "" && t.Name() != "" {
-		// first check if extensions are configued, before doing the interface conversion
-		// x.linef("} else if z.HasExtensions() && z.DecExt(%s) {", varname)
-		yy := fmt.Sprintf("%sxt%s", genTempVarPfx, mi)
-		x.linef("} else if %s := z.Extension(z.I2Rtid(%s)); %s != nil { z.DecExtension(%s, %s) ", yy, varname, yy, varname, yy)
-	}
-
-	if ti2.bu || ti2.bup { // t.Implements(binaryUnmarshalerTyp) || tptr.Implements(binaryUnmarshalerTyp) {
-		x.linef("} else if z.DecBinary() { z.DecBinaryUnmarshal(%s%v) ", addrPfx, varname)
-	}
-	if ti2.ju || ti2.jup { // t.Implements(jsonUnmarshalerTyp) || tptr.Implements(jsonUnmarshalerTyp) {
-		x.linef("} else if !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(%s%v)", addrPfx, varname)
-	} else if ti2.tu || ti2.tup { // t.Implements(textUnmarshalerTyp) || tptr.Implements(textUnmarshalerTyp) {
-		x.linef("} else if !z.DecBinary() { z.DecTextUnmarshal(%s%v)", addrPfx, varname)
-	}
-
-	x.line("} else {")
-
-	if x.decTryAssignPrimitive(varname, t, isptr) {
-		return
-	}
-
-	switch t.Kind() {
-	case reflect.Array, reflect.Chan:
-		x.xtraSM(varname, t, false, isptr)
-	case reflect.Slice:
-		// if a []uint8, call dedicated function
-		// if a known fastpath slice, call dedicated function
-		// else write encode function in-line.
-		// - if elements are primitives or Selfers, call dedicated function on each member.
-		// - else call Encoder.encode(XXX) on it.
-		if rtid == uint8SliceTypId {
-			x.linef("%s%s = r.DecodeBytes(%s(%s[]byte)(%s), false)",
-				ptrPfx, varname, ptrPfx, ptrPfx, varname)
-		} else if fastpathAV.index(rtid) != -1 {
-			g := x.newGenV(t)
-			x.linef("z.F.%sX(%s%s, d)", g.MethodNamePfx("Dec", false), addrPfx, varname)
-		} else {
-			x.xtraSM(varname, t, false, isptr)
-			// x.decListFallback(varname, rtid, false, t)
-		}
-	case reflect.Map:
-		// if a known fastpath map, call dedicated function
-		// else write encode function in-line.
-		// - if elements are primitives or Selfers, call dedicated function on each member.
-		// - else call Encoder.encode(XXX) on it.
-		if fastpathAV.index(rtid) != -1 {
-			g := x.newGenV(t)
-			x.linef("z.F.%sX(%s%s, d)", g.MethodNamePfx("Dec", false), addrPfx, varname)
-		} else {
-			x.xtraSM(varname, t, false, isptr)
-			// x.decMapFallback(varname, rtid, t)
-		}
-	case reflect.Struct:
-		if inlist {
-			// no need to create temp variable if isptr, or x.F or x[F]
-			if isptr || strings.IndexByte(varname, '.') != -1 || strings.IndexByte(varname, '[') != -1 {
-				x.decStruct(varname, rtid, t)
-			} else {
-				varname2 := genTempVarPfx + "j" + mi
-				x.line(varname2 + " := &" + varname)
-				x.decStruct(varname2, rtid, t)
-			}
-		} else {
-			// delete(x.td, rtid)
-			x.line("z.DecFallback(" + addrPfx + varname + ", false)")
-		}
-	default:
-		if rtidAdded {
-			delete(x.te, rtid)
-		}
-		x.line("z.DecFallback(" + addrPfx + varname + ", true)")
-	}
-}
-
-func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type, isptr bool) (done bool) {
-	// This should only be used for exact primitives (ie un-named types).
-	// Named types may be implementations of Selfer, Unmarshaler, etc.
-	// They should be handled by dec(...)
-
-	var ptr string
-	if isptr {
-		ptr = "*"
-	}
-	switch t.Kind() {
-	case reflect.Int:
-		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
-	case reflect.Int8:
-		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 8))", ptr, varname, x.genTypeName(t))
-	case reflect.Int16:
-		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 16))", ptr, varname, x.genTypeName(t))
-	case reflect.Int32:
-		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 32))", ptr, varname, x.genTypeName(t))
-	case reflect.Int64:
-		x.linef("%s%s = (%s)(r.DecodeInt64())", ptr, varname, x.genTypeName(t))
-
-	case reflect.Uint:
-		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
-	case reflect.Uint8:
-		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 8))", ptr, varname, x.genTypeName(t))
-	case reflect.Uint16:
-		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 16))", ptr, varname, x.genTypeName(t))
-	case reflect.Uint32:
-		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 32))", ptr, varname, x.genTypeName(t))
-	case reflect.Uint64:
-		x.linef("%s%s = (%s)(r.DecodeUint64())", ptr, varname, x.genTypeName(t))
-	case reflect.Uintptr:
-		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
-
-	case reflect.Float32:
-		x.linef("%s%s = (%s)(r.DecodeFloat32As64())", ptr, varname, x.genTypeName(t))
-	case reflect.Float64:
-		x.linef("%s%s = (%s)(r.DecodeFloat64())", ptr, varname, x.genTypeName(t))
-
-	case reflect.Bool:
-		x.linef("%s%s = (%s)(r.DecodeBool())", ptr, varname, x.genTypeName(t))
-	case reflect.String:
-		x.linef("%s%s = (%s)(r.DecodeString())", ptr, varname, x.genTypeName(t))
-	default:
-		return false
-	}
-	return true
-}
-
-func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type) {
-	if t.AssignableTo(uint8SliceTyp) {
-		x.line("*" + varname + " = r.DecodeBytes(*((*[]byte)(" + varname + ")), false)")
-		return
-	}
-	if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 {
-		x.linef("r.DecodeBytes( ((*[%d]byte)(%s))[:], true)", t.Len(), varname)
-		return
-	}
-	type tstruc struct {
-		TempVar   string
-		Rand      string
-		Varname   string
-		CTyp      string
-		Typ       string
-		Immutable bool
-		Size      int
-	}
-	telem := t.Elem()
-	ts := tstruc{genTempVarPfx, x.varsfx(), varname, x.genTypeName(t), x.genTypeName(telem), genIsImmutable(telem), int(telem.Size())}
-
-	funcs := make(template.FuncMap)
-
-	funcs["decLineVar"] = func(varname string) string {
-		x.decVar(varname, "", telem, false, true)
-		return ""
-	}
-	funcs["var"] = func(s string) string {
-		return ts.TempVar + s + ts.Rand
-	}
-	funcs["zero"] = func() string {
-		return x.genZeroValueR(telem)
-	}
-	funcs["isArray"] = func() bool {
-		return t.Kind() == reflect.Array
-	}
-	funcs["isSlice"] = func() bool {
-		return t.Kind() == reflect.Slice
-	}
-	funcs["isChan"] = func() bool {
-		return t.Kind() == reflect.Chan
-	}
-	tm, err := template.New("").Funcs(funcs).Parse(genDecListTmpl)
-	if err != nil {
-		panic(err)
-	}
-	if err = tm.Execute(x.w, &ts); err != nil {
-		panic(err)
-	}
-}
-
-func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type) {
-	type tstruc struct {
-		TempVar string
-		Sfx     string
-		Rand    string
-		Varname string
-		KTyp    string
-		Typ     string
-		Size    int
-	}
-	telem := t.Elem()
-	tkey := t.Key()
-	ts := tstruc{
-		genTempVarPfx, x.xs, x.varsfx(), varname, x.genTypeName(tkey),
-		x.genTypeName(telem), int(telem.Size() + tkey.Size()),
-	}
-
-	funcs := make(template.FuncMap)
-	funcs["decElemZero"] = func() string {
-		return x.genZeroValueR(telem)
-	}
-	funcs["decElemKindImmutable"] = func() bool {
-		return genIsImmutable(telem)
-	}
-	funcs["decElemKindPtr"] = func() bool {
-		return telem.Kind() == reflect.Ptr
-	}
-	funcs["decElemKindIntf"] = func() bool {
-		return telem.Kind() == reflect.Interface
-	}
-	funcs["decLineVarK"] = func(varname string) string {
-		x.decVar(varname, "", tkey, false, true)
-		return ""
-	}
-	funcs["decLineVar"] = func(varname, decodedNilVarname string) string {
-		x.decVar(varname, decodedNilVarname, telem, false, true)
-		return ""
-	}
-	funcs["var"] = func(s string) string {
-		return ts.TempVar + s + ts.Rand
-	}
-
-	tm, err := template.New("").Funcs(funcs).Parse(genDecMapTmpl)
-	if err != nil {
-		panic(err)
-	}
-	if err = tm.Execute(x.w, &ts); err != nil {
-		panic(err)
-	}
-}
-
-func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintptr, t reflect.Type) {
-	ti := x.ti.get(rtid, t)
-	tisfi := ti.sfiSrc // always use sequence from file. decStruct expects same thing.
-	x.line("switch (" + kName + ") {")
-	var newbuf, nilbuf genBuf
-	for _, si := range tisfi {
-		x.line("case \"" + si.encName + "\":")
-		newbuf.reset()
-		nilbuf.reset()
-		t2 := x.decVarInitPtr(varname, "", t, si, &newbuf, &nilbuf)
-		x.linef("if r.TryDecodeAsNil() { %s } else { %s", nilbuf.buf, newbuf.buf)
-		x.decVarMain(varname+"."+t2.Name, x.varsfx(), t2.Type, false)
-		x.line("}")
-	}
-	x.line("default:")
-	// pass the slice here, so that the string will not escape, and maybe save allocation
-	x.line("z.DecStructFieldNotFound(-1, " + kName + ")")
-	x.line("} // end switch " + kName)
-}
-
-func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t reflect.Type, style genStructMapStyle) {
-	tpfx := genTempVarPfx
-	ti := x.ti.get(rtid, t)
-	i := x.varsfx()
-	kName := tpfx + "s" + i
-
-	switch style {
-	case genStructMapStyleLenPrefix:
-		x.linef("for %sj%s := 0; %sj%s < %s; %sj%s++ {", tpfx, i, tpfx, i, lenvarname, tpfx, i)
-	case genStructMapStyleCheckBreak:
-		x.linef("for %sj%s := 0; !r.CheckBreak(); %sj%s++ {", tpfx, i, tpfx, i)
-	default: // 0, otherwise.
-		x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length
-		x.linef("for %sj%s := 0; ; %sj%s++ {", tpfx, i, tpfx, i)
-		x.linef("if %shl%s { if %sj%s >= %s { break }", tpfx, i, tpfx, i, lenvarname)
-		x.line("} else { if r.CheckBreak() { break }; }")
-	}
-	x.line("r.ReadMapElemKey()")
-
-	// emulate decstructfieldkey
-	switch ti.keyType {
-	case valueTypeInt:
-		x.linef("%s := z.StringView(strconv.AppendInt(z.DecScratchArrayBuffer()[:0], r.DecodeInt64(), 10))", kName)
-	case valueTypeUint:
-		x.linef("%s := z.StringView(strconv.AppendUint(z.DecScratchArrayBuffer()[:0], r.DecodeUint64(), 10))", kName)
-	case valueTypeFloat:
-		x.linef("%s := z.StringView(strconv.AppendFloat(z.DecScratchArrayBuffer()[:0], r.DecodeFloat64(), 'f', -1, 64))", kName)
-	default: // string
-		x.linef("%s := z.StringView(r.DecodeStringAsBytes())", kName)
-	}
-	// x.linef("%s := z.StringView(r.DecStructFieldKey(codecSelferValueType%s%s, z.DecScratchArrayBuffer()))", kName, ti.keyType.String(), x.xs)
-
-	x.line("r.ReadMapElemValue()")
-	x.decStructMapSwitch(kName, varname, rtid, t)
-
-	x.line("} // end for " + tpfx + "j" + i)
-	x.line("r.ReadMapEnd()")
-}
-
-func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid uintptr, t reflect.Type) {
-	tpfx := genTempVarPfx
-	i := x.varsfx()
-	ti := x.ti.get(rtid, t)
-	tisfi := ti.sfiSrc // always use sequence from file. decStruct expects same thing.
-	x.linef("var %sj%s int", tpfx, i)
-	x.linef("var %sb%s bool", tpfx, i)                        // break
-	x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length
-	var newbuf, nilbuf genBuf
-	for _, si := range tisfi {
-		x.linef("%sj%s++; if %shl%s { %sb%s = %sj%s > %s } else { %sb%s = r.CheckBreak() }",
-			tpfx, i, tpfx, i, tpfx, i,
-			tpfx, i, lenvarname, tpfx, i)
-		x.linef("if %sb%s { r.ReadArrayEnd(); %s }", tpfx, i, breakString)
-		x.line("r.ReadArrayElem()")
-		newbuf.reset()
-		nilbuf.reset()
-		t2 := x.decVarInitPtr(varname, "", t, si, &newbuf, &nilbuf)
-		x.linef("if r.TryDecodeAsNil() { %s } else { %s", nilbuf.buf, newbuf.buf)
-		x.decVarMain(varname+"."+t2.Name, x.varsfx(), t2.Type, false)
-		x.line("}")
-	}
-	// read remaining values and throw away.
-	x.line("for {")
-	x.linef("%sj%s++; if %shl%s { %sb%s = %sj%s > %s } else { %sb%s = r.CheckBreak() }",
-		tpfx, i, tpfx, i, tpfx, i,
-		tpfx, i, lenvarname, tpfx, i)
-	x.linef("if %sb%s { break }", tpfx, i)
-	x.line("r.ReadArrayElem()")
-	x.linef(`z.DecStructFieldNotFound(%sj%s - 1, "")`, tpfx, i)
-	x.line("}")
-	x.line("r.ReadArrayEnd()")
-}
-
-func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) {
-	// varname MUST be a ptr, or a struct field or a slice element.
-	i := x.varsfx()
-	x.linef("%sct%s := r.ContainerType()", genTempVarPfx, i)
-	x.linef("if %sct%s == codecSelferValueTypeMap%s {", genTempVarPfx, i, x.xs)
-	x.line(genTempVarPfx + "l" + i + " := r.ReadMapStart()")
-	x.linef("if %sl%s == 0 {", genTempVarPfx, i)
-	x.line("r.ReadMapEnd()")
-	if genUseOneFunctionForDecStructMap {
-		x.line("} else { ")
-		x.linef("%s.codecDecodeSelfFromMap(%sl%s, d)", varname, genTempVarPfx, i)
-	} else {
-		x.line("} else if " + genTempVarPfx + "l" + i + " > 0 { ")
-		x.line(varname + ".codecDecodeSelfFromMapLenPrefix(" + genTempVarPfx + "l" + i + ", d)")
-		x.line("} else {")
-		x.line(varname + ".codecDecodeSelfFromMapCheckBreak(" + genTempVarPfx + "l" + i + ", d)")
-	}
-	x.line("}")
-
-	// else if container is array
-	x.linef("} else if %sct%s == codecSelferValueTypeArray%s {", genTempVarPfx, i, x.xs)
-	x.line(genTempVarPfx + "l" + i + " := r.ReadArrayStart()")
-	x.linef("if %sl%s == 0 {", genTempVarPfx, i)
-	x.line("r.ReadArrayEnd()")
-	x.line("} else { ")
-	x.linef("%s.codecDecodeSelfFromArray(%sl%s, d)", varname, genTempVarPfx, i)
-	x.line("}")
-	// else panic
-	x.line("} else { ")
-	x.line("panic(errCodecSelferOnlyMapOrArrayEncodeToStruct" + x.xs + ")")
-	x.line("} ")
-}
-
-// --------
-
-type genV struct {
-	// genV is either a primitive (Primitive != "") or a map (MapKey != "") or a slice
-	MapKey    string
-	Elem      string
-	Primitive string
-	Size      int
-}
-
-func (x *genRunner) newGenV(t reflect.Type) (v genV) {
-	switch t.Kind() {
-	case reflect.Slice, reflect.Array:
-		te := t.Elem()
-		v.Elem = x.genTypeName(te)
-		v.Size = int(te.Size())
-	case reflect.Map:
-		te, tk := t.Elem(), t.Key()
-		v.Elem = x.genTypeName(te)
-		v.MapKey = x.genTypeName(tk)
-		v.Size = int(te.Size() + tk.Size())
-	default:
-		panic("unexpected type for newGenV. Requires map or slice type")
-	}
-	return
-}
-
-func (x *genV) MethodNamePfx(prefix string, prim bool) string {
-	var name []byte
-	if prefix != "" {
-		name = append(name, prefix...)
-	}
-	if prim {
-		name = append(name, genTitleCaseName(x.Primitive)...)
-	} else {
-		if x.MapKey == "" {
-			name = append(name, "Slice"...)
-		} else {
-			name = append(name, "Map"...)
-			name = append(name, genTitleCaseName(x.MapKey)...)
-		}
-		name = append(name, genTitleCaseName(x.Elem)...)
-	}
-	return string(name)
-
-}
-
-// genImportPath returns import path of a non-predeclared named typed, or an empty string otherwise.
-//
-// This handles the misbehaviour that occurs when 1.5-style vendoring is enabled,
-// where PkgPath returns the full path, including the vendoring pre-fix that should have been stripped.
-// We strip it here.
-func genImportPath(t reflect.Type) (s string) {
-	s = t.PkgPath()
-	if genCheckVendor {
-		// HACK: always handle vendoring. It should be typically on in go 1.6, 1.7
-		s = genStripVendor(s)
-	}
-	return
-}
-
-// A go identifier is (letter|_)[letter|number|_]*
-func genGoIdentifier(s string, checkFirstChar bool) string {
-	b := make([]byte, 0, len(s))
-	t := make([]byte, 4)
-	var n int
-	for i, r := range s {
-		if checkFirstChar && i == 0 && !unicode.IsLetter(r) {
-			b = append(b, '_')
-		}
-		// r must be unicode_letter, unicode_digit or _
-		if unicode.IsLetter(r) || unicode.IsDigit(r) {
-			n = utf8.EncodeRune(t, r)
-			b = append(b, t[:n]...)
-		} else {
-			b = append(b, '_')
-		}
-	}
-	return string(b)
-}
-
-func genNonPtr(t reflect.Type) reflect.Type {
-	for t.Kind() == reflect.Ptr {
-		t = t.Elem()
-	}
-	return t
-}
-
-func genTitleCaseName(s string) string {
-	switch s {
-	case "interface{}", "interface {}":
-		return "Intf"
-	default:
-		return strings.ToUpper(s[0:1]) + s[1:]
-	}
-}
-
-func genMethodNameT(t reflect.Type, tRef reflect.Type) (n string) {
-	var ptrPfx string
-	for t.Kind() == reflect.Ptr {
-		ptrPfx += "Ptrto"
-		t = t.Elem()
-	}
-	tstr := t.String()
-	if tn := t.Name(); tn != "" {
-		if tRef != nil && genImportPath(t) == genImportPath(tRef) {
-			return ptrPfx + tn
-		} else {
-			if genQNameRegex.MatchString(tstr) {
-				return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
-			} else {
-				return ptrPfx + genCustomTypeName(tstr)
-			}
-		}
-	}
-	switch t.Kind() {
-	case reflect.Map:
-		return ptrPfx + "Map" + genMethodNameT(t.Key(), tRef) + genMethodNameT(t.Elem(), tRef)
-	case reflect.Slice:
-		return ptrPfx + "Slice" + genMethodNameT(t.Elem(), tRef)
-	case reflect.Array:
-		return ptrPfx + "Array" + strconv.FormatInt(int64(t.Len()), 10) + genMethodNameT(t.Elem(), tRef)
-	case reflect.Chan:
-		var cx string
-		switch t.ChanDir() {
-		case reflect.SendDir:
-			cx = "ChanSend"
-		case reflect.RecvDir:
-			cx = "ChanRecv"
-		default:
-			cx = "Chan"
-		}
-		return ptrPfx + cx + genMethodNameT(t.Elem(), tRef)
-	default:
-		if t == intfTyp {
-			return ptrPfx + "Interface"
-		} else {
-			if tRef != nil && genImportPath(t) == genImportPath(tRef) {
-				if t.Name() != "" {
-					return ptrPfx + t.Name()
-				} else {
-					return ptrPfx + genCustomTypeName(tstr)
-				}
-			} else {
-				// best way to get the package name inclusive
-				// return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
-				// return ptrPfx + genBase64enc.EncodeToString([]byte(tstr))
-				if t.Name() != "" && genQNameRegex.MatchString(tstr) {
-					return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
-				} else {
-					return ptrPfx + genCustomTypeName(tstr)
-				}
-			}
-		}
-	}
-}
-
-// genCustomNameForType base64encodes the t.String() value in such a way
-// that it can be used within a function name.
-func genCustomTypeName(tstr string) string {
-	len2 := genBase64enc.EncodedLen(len(tstr))
-	bufx := make([]byte, len2)
-	genBase64enc.Encode(bufx, []byte(tstr))
-	for i := len2 - 1; i >= 0; i-- {
-		if bufx[i] == '=' {
-			len2--
-		} else {
-			break
-		}
-	}
-	return string(bufx[:len2])
-}
-
-func genIsImmutable(t reflect.Type) (v bool) {
-	return isImmutableKind(t.Kind())
-}
-
-type genInternal struct {
-	Version int
-	Values  []genV
-}
-
-func (x genInternal) FastpathLen() (l int) {
-	for _, v := range x.Values {
-		if v.Primitive == "" && !(v.MapKey == "" && v.Elem == "uint8") {
-			l++
-		}
-	}
-	return
-}
-
-func genInternalZeroValue(s string) string {
-	switch s {
-	case "interface{}", "interface {}":
-		return "nil"
-	case "bool":
-		return "false"
-	case "string":
-		return `""`
-	default:
-		return "0"
-	}
-}
-
-var genInternalNonZeroValueIdx [5]uint64
-var genInternalNonZeroValueStrs = [2][5]string{
-	{`"string-is-an-interface"`, "true", `"some-string"`, "11.1", "33"},
-	{`"string-is-an-interface-2"`, "true", `"some-string-2"`, "22.2", "44"},
-}
-
-func genInternalNonZeroValue(s string) string {
-	switch s {
-	case "interface{}", "interface {}":
-		genInternalNonZeroValueIdx[0]++
-		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[0]%2][0] // return string, to remove ambiguity
-	case "bool":
-		genInternalNonZeroValueIdx[1]++
-		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[1]%2][1]
-	case "string":
-		genInternalNonZeroValueIdx[2]++
-		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[2]%2][2]
-	case "float32", "float64", "float", "double":
-		genInternalNonZeroValueIdx[3]++
-		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[3]%2][3]
-	default:
-		genInternalNonZeroValueIdx[4]++
-		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[4]%2][4]
-	}
-}
-
-func genInternalEncCommandAsString(s string, vname string) string {
-	switch s {
-	case "uint", "uint8", "uint16", "uint32", "uint64":
-		return "ee.EncodeUint(uint64(" + vname + "))"
-	case "int", "int8", "int16", "int32", "int64":
-		return "ee.EncodeInt(int64(" + vname + "))"
-	case "string":
-		return "ee.EncodeString(cUTF8, " + vname + ")"
-	case "float32":
-		return "ee.EncodeFloat32(" + vname + ")"
-	case "float64":
-		return "ee.EncodeFloat64(" + vname + ")"
-	case "bool":
-		return "ee.EncodeBool(" + vname + ")"
-	// case "symbol":
-	// 	return "ee.EncodeSymbol(" + vname + ")"
-	default:
-		return "e.encode(" + vname + ")"
-	}
-}
-
-func genInternalDecCommandAsString(s string) string {
-	switch s {
-	case "uint":
-		return "uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))"
-	case "uint8":
-		return "uint8(chkOvf.UintV(dd.DecodeUint64(), 8))"
-	case "uint16":
-		return "uint16(chkOvf.UintV(dd.DecodeUint64(), 16))"
-	case "uint32":
-		return "uint32(chkOvf.UintV(dd.DecodeUint64(), 32))"
-	case "uint64":
-		return "dd.DecodeUint64()"
-	case "uintptr":
-		return "uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))"
-	case "int":
-		return "int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))"
-	case "int8":
-		return "int8(chkOvf.IntV(dd.DecodeInt64(), 8))"
-	case "int16":
-		return "int16(chkOvf.IntV(dd.DecodeInt64(), 16))"
-	case "int32":
-		return "int32(chkOvf.IntV(dd.DecodeInt64(), 32))"
-	case "int64":
-		return "dd.DecodeInt64()"
-
-	case "string":
-		return "dd.DecodeString()"
-	case "float32":
-		return "float32(chkOvf.Float32V(dd.DecodeFloat64()))"
-	case "float64":
-		return "dd.DecodeFloat64()"
-	case "bool":
-		return "dd.DecodeBool()"
-	default:
-		panic(errors.New("gen internal: unknown type for decode: " + s))
-	}
-}
-
-func genInternalSortType(s string, elem bool) string {
-	for _, v := range [...]string{"int", "uint", "float", "bool", "string"} {
-		if strings.HasPrefix(s, v) {
-			if elem {
-				if v == "int" || v == "uint" || v == "float" {
-					return v + "64"
-				} else {
-					return v
-				}
-			}
-			return v + "Slice"
-		}
-	}
-	panic("sorttype: unexpected type: " + s)
-}
-
-func genStripVendor(s string) string {
-	// HACK: Misbehaviour occurs in go 1.5. May have to re-visit this later.
-	// if s contains /vendor/ OR startsWith vendor/, then return everything after it.
-	const vendorStart = "vendor/"
-	const vendorInline = "/vendor/"
-	if i := strings.LastIndex(s, vendorInline); i >= 0 {
-		s = s[i+len(vendorInline):]
-	} else if strings.HasPrefix(s, vendorStart) {
-		s = s[len(vendorStart):]
-	}
-	return s
-}
-
-// var genInternalMu sync.Mutex
-var genInternalV = genInternal{Version: genVersion}
-var genInternalTmplFuncs template.FuncMap
-var genInternalOnce sync.Once
-
-func genInternalInit() {
-	types := [...]string{
-		"interface{}",
-		"string",
-		"float32",
-		"float64",
-		"uint",
-		"uint8",
-		"uint16",
-		"uint32",
-		"uint64",
-		"uintptr",
-		"int",
-		"int8",
-		"int16",
-		"int32",
-		"int64",
-		"bool",
-	}
-	// keep as slice, so it is in specific iteration order.
-	// Initial order was uint64, string, interface{}, int, int64
-	mapvaltypes := [...]string{
-		"interface{}",
-		"string",
-		"uint",
-		"uint8",
-		"uint16",
-		"uint32",
-		"uint64",
-		"uintptr",
-		"int",
-		"int8",
-		"int16",
-		"int32",
-		"int64",
-		"float32",
-		"float64",
-		"bool",
-	}
-	wordSizeBytes := int(intBitsize) / 8
-
-	mapvaltypes2 := map[string]int{
-		"interface{}": 2 * wordSizeBytes,
-		"string":      2 * wordSizeBytes,
-		"uint":        1 * wordSizeBytes,
-		"uint8":       1,
-		"uint16":      2,
-		"uint32":      4,
-		"uint64":      8,
-		"uintptr":     1 * wordSizeBytes,
-		"int":         1 * wordSizeBytes,
-		"int8":        1,
-		"int16":       2,
-		"int32":       4,
-		"int64":       8,
-		"float32":     4,
-		"float64":     8,
-		"bool":        1,
-	}
-	var gt = genInternal{Version: genVersion}
-
-	// For each slice or map type, there must be a (symmetrical) Encode and Decode fast-path function
-	for _, s := range types {
-		gt.Values = append(gt.Values, genV{Primitive: s, Size: mapvaltypes2[s]})
-		// if s != "uint8" { // do not generate fast path for slice of bytes. Treat specially already.
-		// 	gt.Values = append(gt.Values, genV{Elem: s, Size: mapvaltypes2[s]})
-		// }
-		gt.Values = append(gt.Values, genV{Elem: s, Size: mapvaltypes2[s]})
-		if _, ok := mapvaltypes2[s]; !ok {
-			gt.Values = append(gt.Values, genV{MapKey: s, Elem: s, Size: 2 * mapvaltypes2[s]})
-		}
-		for _, ms := range mapvaltypes {
-			gt.Values = append(gt.Values, genV{MapKey: s, Elem: ms, Size: mapvaltypes2[s] + mapvaltypes2[ms]})
-		}
-	}
-
-	funcs := make(template.FuncMap)
-	// funcs["haspfx"] = strings.HasPrefix
-	funcs["encmd"] = genInternalEncCommandAsString
-	funcs["decmd"] = genInternalDecCommandAsString
-	funcs["zerocmd"] = genInternalZeroValue
-	funcs["nonzerocmd"] = genInternalNonZeroValue
-	funcs["hasprefix"] = strings.HasPrefix
-	funcs["sorttype"] = genInternalSortType
-
-	genInternalV = gt
-	genInternalTmplFuncs = funcs
-}
-
-// genInternalGoFile is used to generate source files from templates.
-// It is run by the program author alone.
-// Unfortunately, it has to be exported so that it can be called from a command line tool.
-// *** DO NOT USE ***
-func genInternalGoFile(r io.Reader, w io.Writer) (err error) {
-	genInternalOnce.Do(genInternalInit)
-
-	gt := genInternalV
-
-	t := template.New("").Funcs(genInternalTmplFuncs)
-
-	tmplstr, err := ioutil.ReadAll(r)
-	if err != nil {
-		return
-	}
-
-	if t, err = t.Parse(string(tmplstr)); err != nil {
-		return
-	}
-
-	var out bytes.Buffer
-	err = t.Execute(&out, gt)
-	if err != nil {
-		return
-	}
-
-	bout, err := format.Source(out.Bytes())
-	if err != nil {
-		w.Write(out.Bytes()) // write out if error, so we can still see.
-		// w.Write(bout) // write out if error, as much as possible, so we can still see.
-		return
-	}
-	w.Write(bout)
-	return
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go b/vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
deleted file mode 100644
index 9ddbe20..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.5
-
-package codec
-
-import "reflect"
-
-const reflectArrayOfSupported = true
-
-func reflectArrayOf(count int, elem reflect.Type) reflect.Type {
-	return reflect.ArrayOf(count, elem)
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go b/vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
deleted file mode 100644
index c5fcd66..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build !go1.5
-
-package codec
-
-import "reflect"
-
-const reflectArrayOfSupported = false
-
-func reflectArrayOf(count int, elem reflect.Type) reflect.Type {
-	panic("codec: reflect.ArrayOf unsupported in this go version")
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go b/vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
deleted file mode 100644
index bc39d6b..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.9
-
-package codec
-
-import "reflect"
-
-func makeMapReflect(t reflect.Type, size int) reflect.Value {
-	if size < 0 {
-		return reflect.MakeMapWithSize(t, 4)
-	}
-	return reflect.MakeMapWithSize(t, size)
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go b/vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
deleted file mode 100644
index cde4cd3..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build !go1.9
-
-package codec
-
-import "reflect"
-
-func makeMapReflect(t reflect.Type, size int) reflect.Value {
-	return reflect.MakeMap(t)
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go b/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
deleted file mode 100644
index 794133a..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.10
-
-package codec
-
-const allowSetUnexportedEmbeddedPtr = false
diff --git a/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go b/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
deleted file mode 100644
index fd92ede..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build !go1.10
-
-package codec
-
-const allowSetUnexportedEmbeddedPtr = true
diff --git a/vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go b/vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
deleted file mode 100644
index 8debfa6..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build !go1.4
-
-package codec
-
-// This codec package will only work for go1.4 and above.
-// This is for the following reasons:
-//   - go 1.4 was released in 2014
-//   - go runtime is written fully in go
-//   - interface only holds pointers
-//   - reflect.Value is stabilized as 3 words
-
-func init() {
-	panic("codec: go 1.3 and below are not supported")
-}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
deleted file mode 100644
index 0f1bb01..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.5,!go1.6
-
-package codec
-
-import "os"
-
-var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1"
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
deleted file mode 100644
index 2fb4b05..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.6,!go1.7
-
-package codec
-
-import "os"
-
-var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") != "0"
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
deleted file mode 100644
index c5b8155..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build go1.7
-
-package codec
-
-const genCheckVendor = true
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
deleted file mode 100644
index 837cf24..0000000
--- a/vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build !go1.5
-
-package codec
-
-var genCheckVendor = false
diff --git a/vendor/github.com/ugorji/go/codec/helper.go b/vendor/github.com/ugorji/go/codec/helper.go
deleted file mode 100644
index bd29895..0000000
--- a/vendor/github.com/ugorji/go/codec/helper.go
+++ /dev/null
@@ -1,2414 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-// Contains code shared by both encode and decode.
-
-// Some shared ideas around encoding/decoding
-// ------------------------------------------
-//
-// If an interface{} is passed, we first do a type assertion to see if it is
-// a primitive type or a map/slice of primitive types, and use a fastpath to handle it.
-//
-// If we start with a reflect.Value, we are already in reflect.Value land and
-// will try to grab the function for the underlying Type and directly call that function.
-// This is more performant than calling reflect.Value.Interface().
-//
-// This still helps us bypass many layers of reflection, and give best performance.
-//
-// Containers
-// ------------
-// Containers in the stream are either associative arrays (key-value pairs) or
-// regular arrays (indexed by incrementing integers).
-//
-// Some streams support indefinite-length containers, and use a breaking
-// byte-sequence to denote that the container has come to an end.
-//
-// Some streams also are text-based, and use explicit separators to denote the
-// end/beginning of different values.
-//
-// During encode, we use a high-level condition to determine how to iterate through
-// the container. That decision is based on whether the container is text-based (with
-// separators) or binary (without separators). If binary, we do not even call the
-// encoding of separators.
-//
-// During decode, we use a different high-level condition to determine how to iterate
-// through the containers. That decision is based on whether the stream contained
-// a length prefix, or if it used explicit breaks. If length-prefixed, we assume that
-// it has to be binary, and we do not even try to read separators.
-//
-// Philosophy
-// ------------
-// On decode, this codec will update containers appropriately:
-//    - If struct, update fields from stream into fields of struct.
-//      If field in stream not found in struct, handle appropriately (based on option).
-//      If a struct field has no corresponding value in the stream, leave it AS IS.
-//      If nil in stream, set value to nil/zero value.
-//    - If map, update map from stream.
-//      If the stream value is NIL, set the map to nil.
-//    - if slice, try to update up to length of array in stream.
-//      if container len is less than stream array length,
-//      and container cannot be expanded, handled (based on option).
-//      This means you can decode 4-element stream array into 1-element array.
-//
-// ------------------------------------
-// On encode, user can specify omitEmpty. This means that the value will be omitted
-// if the zero value. The problem may occur during decode, where omitted values do not affect
-// the value being decoded into. This means that if decoding into a struct with an
-// int field with current value=5, and the field is omitted in the stream, then after
-// decoding, the value will still be 5 (not 0).
-// omitEmpty only works if you guarantee that you always decode into zero-values.
-//
-// ------------------------------------
-// We could have truncated a map to remove keys not available in the stream,
-// or set values in the struct which are not in the stream to their zero values.
-// We decided against it because there is no efficient way to do it.
-// We may introduce it as an option later.
-// However, that will require enabling it for both runtime and code generation modes.
-//
-// To support truncate, we need to do 2 passes over the container:
-//   map
-//   - first collect all keys (e.g. in k1)
-//   - for each key in stream, mark k1 that the key should not be removed
-//   - after updating map, do second pass and call delete for all keys in k1 which are not marked
-//   struct:
-//   - for each field, track the *typeInfo s1
-//   - iterate through all s1, and for each one not marked, set value to zero
-//   - this involves checking the possible anonymous fields which are nil ptrs.
-//     too much work.
-//
-// ------------------------------------------
-// Error Handling is done within the library using panic.
-//
-// This way, the code doesn't have to keep checking if an error has happened,
-// and we don't have to keep sending the error value along with each call
-// or storing it in the En|Decoder and checking it constantly along the way.
-//
-// The disadvantage is that small functions which use panics cannot be inlined.
-// The code accounts for that by only using panics behind an interface;
-// since interface calls cannot be inlined, this is irrelevant.
-//
-// We considered storing the error is En|Decoder.
-//   - once it has its err field set, it cannot be used again.
-//   - panicing will be optional, controlled by const flag.
-//   - code should always check error first and return early.
-// We eventually decided against it as it makes the code clumsier to always
-// check for these error conditions.
-
-import (
-	"bytes"
-	"encoding"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"math"
-	"reflect"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-)
-
-const (
-	scratchByteArrayLen = 32
-	// initCollectionCap   = 16 // 32 is defensive. 16 is preferred.
-
-	// Support encoding.(Binary|Text)(Unm|M)arshaler.
-	// This constant flag will enable or disable it.
-	supportMarshalInterfaces = true
-
-	// for debugging, set this to false, to catch panic traces.
-	// Note that this will always cause rpc tests to fail, since they need io.EOF sent via panic.
-	recoverPanicToErr = true
-
-	// arrayCacheLen is the length of the cache used in encoder or decoder for
-	// allowing zero-alloc initialization.
-	arrayCacheLen = 8
-
-	// size of the cacheline: defaulting to value for archs: amd64, arm64, 386
-	// should use "runtime/internal/sys".CacheLineSize, but that is not exposed.
-	cacheLineSize = 64
-
-	wordSizeBits = 32 << (^uint(0) >> 63) // strconv.IntSize
-	wordSize     = wordSizeBits / 8
-
-	maxLevelsEmbedding = 15 // use this, so structFieldInfo fits into 8 bytes
-)
-
-var (
-	oneByteArr    = [1]byte{0}
-	zeroByteSlice = oneByteArr[:0:0]
-)
-
-var refBitset bitset32
-var pool pooler
-var panicv panicHdl
-
-func init() {
-	pool.init()
-
-	refBitset.set(byte(reflect.Map))
-	refBitset.set(byte(reflect.Ptr))
-	refBitset.set(byte(reflect.Func))
-	refBitset.set(byte(reflect.Chan))
-}
-
-type charEncoding uint8
-
-const (
-	cRAW charEncoding = iota
-	cUTF8
-	cUTF16LE
-	cUTF16BE
-	cUTF32LE
-	cUTF32BE
-)
-
-// valueType is the stream type
-type valueType uint8
-
-const (
-	valueTypeUnset valueType = iota
-	valueTypeNil
-	valueTypeInt
-	valueTypeUint
-	valueTypeFloat
-	valueTypeBool
-	valueTypeString
-	valueTypeSymbol
-	valueTypeBytes
-	valueTypeMap
-	valueTypeArray
-	valueTypeTime
-	valueTypeExt
-
-	// valueTypeInvalid = 0xff
-)
-
-var valueTypeStrings = [...]string{
-	"Unset",
-	"Nil",
-	"Int",
-	"Uint",
-	"Float",
-	"Bool",
-	"String",
-	"Symbol",
-	"Bytes",
-	"Map",
-	"Array",
-	"Timestamp",
-	"Ext",
-}
-
-func (x valueType) String() string {
-	if int(x) < len(valueTypeStrings) {
-		return valueTypeStrings[x]
-	}
-	return strconv.FormatInt(int64(x), 10)
-}
-
-type seqType uint8
-
-const (
-	_ seqType = iota
-	seqTypeArray
-	seqTypeSlice
-	seqTypeChan
-)
-
-// note that containerMapStart and containerArraySend are not sent.
-// This is because the ReadXXXStart and EncodeXXXStart already does these.
-type containerState uint8
-
-const (
-	_ containerState = iota
-
-	containerMapStart // slot left open, since Driver method already covers it
-	containerMapKey
-	containerMapValue
-	containerMapEnd
-	containerArrayStart // slot left open, since Driver methods already cover it
-	containerArrayElem
-	containerArrayEnd
-)
-
-// // sfiIdx used for tracking where a (field/enc)Name is seen in a []*structFieldInfo
-// type sfiIdx struct {
-// 	name  string
-// 	index int
-// }
-
-// do not recurse if a containing type refers to an embedded type
-// which refers back to its containing type (via a pointer).
-// The second time this back-reference happens, break out,
-// so as not to cause an infinite loop.
-const rgetMaxRecursion = 2
-
-// Anecdotally, we believe most types have <= 12 fields.
-// - even Java's PMD rules set TooManyFields threshold to 15.
-// However, go has embedded fields, which should be regarded as
-// top level, allowing structs to possibly double or triple.
-// In addition, we don't want to keep creating transient arrays,
-// especially for the sfi index tracking, and the evtypes tracking.
-//
-// So - try to keep typeInfoLoadArray within 2K bytes
-const (
-	typeInfoLoadArraySfisLen   = 16
-	typeInfoLoadArraySfiidxLen = 8 * 112
-	typeInfoLoadArrayEtypesLen = 12
-	typeInfoLoadArrayBLen      = 8 * 4
-)
-
-type typeInfoLoad struct {
-	// fNames   []string
-	// encNames []string
-	etypes []uintptr
-	sfis   []structFieldInfo
-}
-
-type typeInfoLoadArray struct {
-	// fNames   [typeInfoLoadArrayLen]string
-	// encNames [typeInfoLoadArrayLen]string
-	sfis   [typeInfoLoadArraySfisLen]structFieldInfo
-	sfiidx [typeInfoLoadArraySfiidxLen]byte
-	etypes [typeInfoLoadArrayEtypesLen]uintptr
-	b      [typeInfoLoadArrayBLen]byte // scratch - used for struct field names
-}
-
-// mirror json.Marshaler and json.Unmarshaler here,
-// so we don't import the encoding/json package
-
-type jsonMarshaler interface {
-	MarshalJSON() ([]byte, error)
-}
-type jsonUnmarshaler interface {
-	UnmarshalJSON([]byte) error
-}
-
-type isZeroer interface {
-	IsZero() bool
-}
-
-// type byteAccepter func(byte) bool
-
-var (
-	bigen               = binary.BigEndian
-	structInfoFieldName = "_struct"
-
-	mapStrIntfTyp  = reflect.TypeOf(map[string]interface{}(nil))
-	mapIntfIntfTyp = reflect.TypeOf(map[interface{}]interface{}(nil))
-	intfSliceTyp   = reflect.TypeOf([]interface{}(nil))
-	intfTyp        = intfSliceTyp.Elem()
-
-	reflectValTyp = reflect.TypeOf((*reflect.Value)(nil)).Elem()
-
-	stringTyp     = reflect.TypeOf("")
-	timeTyp       = reflect.TypeOf(time.Time{})
-	rawExtTyp     = reflect.TypeOf(RawExt{})
-	rawTyp        = reflect.TypeOf(Raw{})
-	uintptrTyp    = reflect.TypeOf(uintptr(0))
-	uint8Typ      = reflect.TypeOf(uint8(0))
-	uint8SliceTyp = reflect.TypeOf([]uint8(nil))
-	uintTyp       = reflect.TypeOf(uint(0))
-	intTyp        = reflect.TypeOf(int(0))
-
-	mapBySliceTyp = reflect.TypeOf((*MapBySlice)(nil)).Elem()
-
-	binaryMarshalerTyp   = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem()
-	binaryUnmarshalerTyp = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem()
-
-	textMarshalerTyp   = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
-	textUnmarshalerTyp = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
-
-	jsonMarshalerTyp   = reflect.TypeOf((*jsonMarshaler)(nil)).Elem()
-	jsonUnmarshalerTyp = reflect.TypeOf((*jsonUnmarshaler)(nil)).Elem()
-
-	selferTyp = reflect.TypeOf((*Selfer)(nil)).Elem()
-	iszeroTyp = reflect.TypeOf((*isZeroer)(nil)).Elem()
-
-	uint8TypId      = rt2id(uint8Typ)
-	uint8SliceTypId = rt2id(uint8SliceTyp)
-	rawExtTypId     = rt2id(rawExtTyp)
-	rawTypId        = rt2id(rawTyp)
-	intfTypId       = rt2id(intfTyp)
-	timeTypId       = rt2id(timeTyp)
-	stringTypId     = rt2id(stringTyp)
-
-	mapStrIntfTypId  = rt2id(mapStrIntfTyp)
-	mapIntfIntfTypId = rt2id(mapIntfIntfTyp)
-	intfSliceTypId   = rt2id(intfSliceTyp)
-	// mapBySliceTypId  = rt2id(mapBySliceTyp)
-
-	intBitsize  = uint8(intTyp.Bits())
-	uintBitsize = uint8(uintTyp.Bits())
-
-	bsAll0x00 = []byte{0, 0, 0, 0, 0, 0, 0, 0}
-	bsAll0xff = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
-
-	chkOvf checkOverflow
-
-	errNoFieldNameToStructFieldInfo = errors.New("no field name passed to parseStructFieldInfo")
-)
-
-var defTypeInfos = NewTypeInfos([]string{"codec", "json"})
-
-var immutableKindsSet = [32]bool{
-	// reflect.Invalid:  ,
-	reflect.Bool:       true,
-	reflect.Int:        true,
-	reflect.Int8:       true,
-	reflect.Int16:      true,
-	reflect.Int32:      true,
-	reflect.Int64:      true,
-	reflect.Uint:       true,
-	reflect.Uint8:      true,
-	reflect.Uint16:     true,
-	reflect.Uint32:     true,
-	reflect.Uint64:     true,
-	reflect.Uintptr:    true,
-	reflect.Float32:    true,
-	reflect.Float64:    true,
-	reflect.Complex64:  true,
-	reflect.Complex128: true,
-	// reflect.Array
-	// reflect.Chan
-	// reflect.Func: true,
-	// reflect.Interface
-	// reflect.Map
-	// reflect.Ptr
-	// reflect.Slice
-	reflect.String: true,
-	// reflect.Struct
-	// reflect.UnsafePointer
-}
-
-// Selfer defines methods by which a value can encode or decode itself.
-//
-// Any type which implements Selfer will be able to encode or decode itself.
-// Consequently, during (en|de)code, this takes precedence over
-// (text|binary)(M|Unm)arshal or extension support.
-//
-// Note: *the first set of bytes of any value MUST NOT represent nil in the format*.
-// This is because, during each decode, we first check the the next set of bytes
-// represent nil, and if so, we just set the value to nil.
-type Selfer interface {
-	CodecEncodeSelf(*Encoder)
-	CodecDecodeSelf(*Decoder)
-}
-
-// MapBySlice is a tag interface that denotes wrapped slice should encode as a map in the stream.
-// The slice contains a sequence of key-value pairs.
-// This affords storing a map in a specific sequence in the stream.
-//
-// Example usage:
-//    type T1 []string         // or []int or []Point or any other "slice" type
-//    func (_ T1) MapBySlice{} // T1 now implements MapBySlice, and will be encoded as a map
-//    type T2 struct { KeyValues T1 }
-//
-//    var kvs = []string{"one", "1", "two", "2", "three", "3"}
-//    var v2 = T2{ KeyValues: T1(kvs) }
-//    // v2 will be encoded like the map: {"KeyValues": {"one": "1", "two": "2", "three": "3"} }
-//
-// The support of MapBySlice affords the following:
-//   - A slice type which implements MapBySlice will be encoded as a map
-//   - A slice can be decoded from a map in the stream
-//   - It MUST be a slice type (not a pointer receiver) that implements MapBySlice
-type MapBySlice interface {
-	MapBySlice()
-}
-
-// BasicHandle encapsulates the common options and extension functions.
-//
-// Deprecated: DO NOT USE DIRECTLY. EXPORTED FOR GODOC BENEFIT. WILL BE REMOVED.
-type BasicHandle struct {
-	// BasicHandle is always a part of a different type.
-	// It doesn't have to fit into it own cache lines.
-
-	// TypeInfos is used to get the type info for any type.
-	//
-	// If not configured, the default TypeInfos is used, which uses struct tag keys: codec, json
-	TypeInfos *TypeInfos
-
-	// Note: BasicHandle is not comparable, due to these slices here (extHandle, intf2impls).
-	// If *[]T is used instead, this becomes comparable, at the cost of extra indirection.
-	// Thses slices are used all the time, so keep as slices (not pointers).
-
-	extHandle
-
-	intf2impls
-
-	RPCOptions
-
-	// ---- cache line
-
-	DecodeOptions
-
-	// ---- cache line
-
-	EncodeOptions
-
-	// noBuiltInTypeChecker
-}
-
-func (x *BasicHandle) getBasicHandle() *BasicHandle {
-	return x
-}
-
-func (x *BasicHandle) getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
-	if x.TypeInfos == nil {
-		return defTypeInfos.get(rtid, rt)
-	}
-	return x.TypeInfos.get(rtid, rt)
-}
-
-// Handle is the interface for a specific encoding format.
-//
-// Typically, a Handle is pre-configured before first time use,
-// and not modified while in use. Such a pre-configured Handle
-// is safe for concurrent access.
-type Handle interface {
-	Name() string
-	getBasicHandle() *BasicHandle
-	recreateEncDriver(encDriver) bool
-	newEncDriver(w *Encoder) encDriver
-	newDecDriver(r *Decoder) decDriver
-	isBinary() bool
-	hasElemSeparators() bool
-	// IsBuiltinType(rtid uintptr) bool
-}
-
-// Raw represents raw formatted bytes.
-// We "blindly" store it during encode and retrieve the raw bytes during decode.
-// Note: it is dangerous during encode, so we may gate the behaviour
-// behind an Encode flag which must be explicitly set.
-type Raw []byte
-
-// RawExt represents raw unprocessed extension data.
-// Some codecs will decode extension data as a *RawExt
-// if there is no registered extension for the tag.
-//
-// Only one of Data or Value is nil.
-// If Data is nil, then the content of the RawExt is in the Value.
-type RawExt struct {
-	Tag uint64
-	// Data is the []byte which represents the raw ext. If nil, ext is exposed in Value.
-	// Data is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of types
-	Data []byte
-	// Value represents the extension, if Data is nil.
-	// Value is used by codecs (e.g. cbor, json) which leverage the format to do
-	// custom serialization of the types.
-	Value interface{}
-}
-
-// BytesExt handles custom (de)serialization of types to/from []byte.
-// It is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types.
-type BytesExt interface {
-	// WriteExt converts a value to a []byte.
-	//
-	// Note: v is a pointer iff the registered extension type is a struct or array kind.
-	WriteExt(v interface{}) []byte
-
-	// ReadExt updates a value from a []byte.
-	//
-	// Note: dst is always a pointer kind to the registered extension type.
-	ReadExt(dst interface{}, src []byte)
-}
-
-// InterfaceExt handles custom (de)serialization of types to/from another interface{} value.
-// The Encoder or Decoder will then handle the further (de)serialization of that known type.
-//
-// It is used by codecs (e.g. cbor, json) which use the format to do custom serialization of types.
-type InterfaceExt interface {
-	// ConvertExt converts a value into a simpler interface for easy encoding
-	// e.g. convert time.Time to int64.
-	//
-	// Note: v is a pointer iff the registered extension type is a struct or array kind.
-	ConvertExt(v interface{}) interface{}
-
-	// UpdateExt updates a value from a simpler interface for easy decoding
-	// e.g. convert int64 to time.Time.
-	//
-	// Note: dst is always a pointer kind to the registered extension type.
-	UpdateExt(dst interface{}, src interface{})
-}
-
-// Ext handles custom (de)serialization of custom types / extensions.
-type Ext interface {
-	BytesExt
-	InterfaceExt
-}
-
-// addExtWrapper is a wrapper implementation to support former AddExt exported method.
-type addExtWrapper struct {
-	encFn func(reflect.Value) ([]byte, error)
-	decFn func(reflect.Value, []byte) error
-}
-
-func (x addExtWrapper) WriteExt(v interface{}) []byte {
-	bs, err := x.encFn(reflect.ValueOf(v))
-	if err != nil {
-		panic(err)
-	}
-	return bs
-}
-
-func (x addExtWrapper) ReadExt(v interface{}, bs []byte) {
-	if err := x.decFn(reflect.ValueOf(v), bs); err != nil {
-		panic(err)
-	}
-}
-
-func (x addExtWrapper) ConvertExt(v interface{}) interface{} {
-	return x.WriteExt(v)
-}
-
-func (x addExtWrapper) UpdateExt(dest interface{}, v interface{}) {
-	x.ReadExt(dest, v.([]byte))
-}
-
-type extWrapper struct {
-	BytesExt
-	InterfaceExt
-}
-
-type bytesExtFailer struct{}
-
-func (bytesExtFailer) WriteExt(v interface{}) []byte {
-	panicv.errorstr("BytesExt.WriteExt is not supported")
-	return nil
-}
-func (bytesExtFailer) ReadExt(v interface{}, bs []byte) {
-	panicv.errorstr("BytesExt.ReadExt is not supported")
-}
-
-type interfaceExtFailer struct{}
-
-func (interfaceExtFailer) ConvertExt(v interface{}) interface{} {
-	panicv.errorstr("InterfaceExt.ConvertExt is not supported")
-	return nil
-}
-func (interfaceExtFailer) UpdateExt(dest interface{}, v interface{}) {
-	panicv.errorstr("InterfaceExt.UpdateExt is not supported")
-}
-
-type binaryEncodingType struct{}
-
-func (binaryEncodingType) isBinary() bool { return true }
-
-type textEncodingType struct{}
-
-func (textEncodingType) isBinary() bool { return false }
-
-// noBuiltInTypes is embedded into many types which do not support builtins
-// e.g. msgpack, simple, cbor.
-
-// type noBuiltInTypeChecker struct{}
-// func (noBuiltInTypeChecker) IsBuiltinType(rt uintptr) bool { return false }
-// type noBuiltInTypes struct{ noBuiltInTypeChecker }
-
-type noBuiltInTypes struct{}
-
-func (noBuiltInTypes) EncodeBuiltin(rt uintptr, v interface{}) {}
-func (noBuiltInTypes) DecodeBuiltin(rt uintptr, v interface{}) {}
-
-// type noStreamingCodec struct{}
-// func (noStreamingCodec) CheckBreak() bool { return false }
-// func (noStreamingCodec) hasElemSeparators() bool { return false }
-
-type noElemSeparators struct{}
-
-func (noElemSeparators) hasElemSeparators() (v bool)            { return }
-func (noElemSeparators) recreateEncDriver(e encDriver) (v bool) { return }
-
-// bigenHelper.
-// Users must already slice the x completely, because we will not reslice.
-type bigenHelper struct {
-	x []byte // must be correctly sliced to appropriate len. slicing is a cost.
-	w encWriter
-}
-
-func (z bigenHelper) writeUint16(v uint16) {
-	bigen.PutUint16(z.x, v)
-	z.w.writeb(z.x)
-}
-
-func (z bigenHelper) writeUint32(v uint32) {
-	bigen.PutUint32(z.x, v)
-	z.w.writeb(z.x)
-}
-
-func (z bigenHelper) writeUint64(v uint64) {
-	bigen.PutUint64(z.x, v)
-	z.w.writeb(z.x)
-}
-
-type extTypeTagFn struct {
-	rtid    uintptr
-	rtidptr uintptr
-	rt      reflect.Type
-	tag     uint64
-	ext     Ext
-	_       [1]uint64 // padding
-}
-
-type extHandle []extTypeTagFn
-
-// AddExt registes an encode and decode function for a reflect.Type.
-// To deregister an Ext, call AddExt with nil encfn and/or nil decfn.
-//
-// Deprecated: Use SetBytesExt or SetInterfaceExt on the Handle instead.
-func (o *extHandle) AddExt(rt reflect.Type, tag byte,
-	encfn func(reflect.Value) ([]byte, error),
-	decfn func(reflect.Value, []byte) error) (err error) {
-	if encfn == nil || decfn == nil {
-		return o.SetExt(rt, uint64(tag), nil)
-	}
-	return o.SetExt(rt, uint64(tag), addExtWrapper{encfn, decfn})
-}
-
-// SetExt will set the extension for a tag and reflect.Type.
-// Note that the type must be a named type, and specifically not a pointer or Interface.
-// An error is returned if that is not honored.
-// To Deregister an ext, call SetExt with nil Ext.
-//
-// Deprecated: Use SetBytesExt or SetInterfaceExt on the Handle instead.
-func (o *extHandle) SetExt(rt reflect.Type, tag uint64, ext Ext) (err error) {
-	// o is a pointer, because we may need to initialize it
-	rk := rt.Kind()
-	for rk == reflect.Ptr {
-		rt = rt.Elem()
-		rk = rt.Kind()
-	}
-
-	if rt.PkgPath() == "" || rk == reflect.Interface { // || rk == reflect.Ptr {
-		return fmt.Errorf("codec.Handle.SetExt: Takes named type, not a pointer or interface: %v", rt)
-	}
-
-	rtid := rt2id(rt)
-	switch rtid {
-	case timeTypId, rawTypId, rawExtTypId:
-		// all natively supported type, so cannot have an extension
-		return // TODO: should we silently ignore, or return an error???
-	}
-	// if o == nil {
-	// 	return errors.New("codec.Handle.SetExt: extHandle not initialized")
-	// }
-	o2 := *o
-	// if o2 == nil {
-	// 	return errors.New("codec.Handle.SetExt: extHandle not initialized")
-	// }
-	for i := range o2 {
-		v := &o2[i]
-		if v.rtid == rtid {
-			v.tag, v.ext = tag, ext
-			return
-		}
-	}
-	rtidptr := rt2id(reflect.PtrTo(rt))
-	*o = append(o2, extTypeTagFn{rtid, rtidptr, rt, tag, ext, [1]uint64{}})
-	return
-}
-
-func (o extHandle) getExt(rtid uintptr) (v *extTypeTagFn) {
-	for i := range o {
-		v = &o[i]
-		if v.rtid == rtid || v.rtidptr == rtid {
-			return
-		}
-	}
-	return nil
-}
-
-func (o extHandle) getExtForTag(tag uint64) (v *extTypeTagFn) {
-	for i := range o {
-		v = &o[i]
-		if v.tag == tag {
-			return
-		}
-	}
-	return nil
-}
-
-type intf2impl struct {
-	rtid uintptr // for intf
-	impl reflect.Type
-	// _    [1]uint64 // padding // not-needed, as *intf2impl is never returned.
-}
-
-type intf2impls []intf2impl
-
-// Intf2Impl maps an interface to an implementing type.
-// This allows us support infering the concrete type
-// and populating it when passed an interface.
-// e.g. var v io.Reader can be decoded as a bytes.Buffer, etc.
-//
-// Passing a nil impl will clear the mapping.
-func (o *intf2impls) Intf2Impl(intf, impl reflect.Type) (err error) {
-	if impl != nil && !impl.Implements(intf) {
-		return fmt.Errorf("Intf2Impl: %v does not implement %v", impl, intf)
-	}
-	rtid := rt2id(intf)
-	o2 := *o
-	for i := range o2 {
-		v := &o2[i]
-		if v.rtid == rtid {
-			v.impl = impl
-			return
-		}
-	}
-	*o = append(o2, intf2impl{rtid, impl})
-	return
-}
-
-func (o intf2impls) intf2impl(rtid uintptr) (rv reflect.Value) {
-	for i := range o {
-		v := &o[i]
-		if v.rtid == rtid {
-			if v.impl == nil {
-				return
-			}
-			if v.impl.Kind() == reflect.Ptr {
-				return reflect.New(v.impl.Elem())
-			}
-			return reflect.New(v.impl).Elem()
-		}
-	}
-	return
-}
-
-type structFieldInfoFlag uint8
-
-const (
-	_ structFieldInfoFlag = 1 << iota
-	structFieldInfoFlagReady
-	structFieldInfoFlagOmitEmpty
-)
-
-func (x *structFieldInfoFlag) flagSet(f structFieldInfoFlag) {
-	*x = *x | f
-}
-
-func (x *structFieldInfoFlag) flagClr(f structFieldInfoFlag) {
-	*x = *x &^ f
-}
-
-func (x structFieldInfoFlag) flagGet(f structFieldInfoFlag) bool {
-	return x&f != 0
-}
-
-func (x structFieldInfoFlag) omitEmpty() bool {
-	return x.flagGet(structFieldInfoFlagOmitEmpty)
-}
-
-func (x structFieldInfoFlag) ready() bool {
-	return x.flagGet(structFieldInfoFlagReady)
-}
-
-type structFieldInfo struct {
-	encName   string // encode name
-	fieldName string // field name
-
-	is  [maxLevelsEmbedding]uint16 // (recursive/embedded) field index in struct
-	nis uint8                      // num levels of embedding. if 1, then it's not embedded.
-	structFieldInfoFlag
-}
-
-func (si *structFieldInfo) setToZeroValue(v reflect.Value) {
-	if v, valid := si.field(v, false); valid {
-		v.Set(reflect.Zero(v.Type()))
-	}
-}
-
-// rv returns the field of the struct.
-// If anonymous, it returns an Invalid
-func (si *structFieldInfo) field(v reflect.Value, update bool) (rv2 reflect.Value, valid bool) {
-	// replicate FieldByIndex
-	for i, x := range si.is {
-		if uint8(i) == si.nis {
-			break
-		}
-		if v, valid = baseStructRv(v, update); !valid {
-			return
-		}
-		v = v.Field(int(x))
-	}
-
-	return v, true
-}
-
-// func (si *structFieldInfo) fieldval(v reflect.Value, update bool) reflect.Value {
-// 	v, _ = si.field(v, update)
-// 	return v
-// }
-
-func parseStructInfo(stag string) (toArray, omitEmpty bool, keytype valueType) {
-	keytype = valueTypeString // default
-	if stag == "" {
-		return
-	}
-	for i, s := range strings.Split(stag, ",") {
-		if i == 0 {
-		} else {
-			switch s {
-			case "omitempty":
-				omitEmpty = true
-			case "toarray":
-				toArray = true
-			case "int":
-				keytype = valueTypeInt
-			case "uint":
-				keytype = valueTypeUint
-			case "float":
-				keytype = valueTypeFloat
-				// case "bool":
-				// 	keytype = valueTypeBool
-			case "string":
-				keytype = valueTypeString
-			}
-		}
-	}
-	return
-}
-
-func (si *structFieldInfo) parseTag(stag string) {
-	// if fname == "" {
-	// 	panic(errNoFieldNameToStructFieldInfo)
-	// }
-
-	if stag == "" {
-		return
-	}
-	for i, s := range strings.Split(stag, ",") {
-		if i == 0 {
-			if s != "" {
-				si.encName = s
-			}
-		} else {
-			switch s {
-			case "omitempty":
-				si.flagSet(structFieldInfoFlagOmitEmpty)
-				// si.omitEmpty = true
-				// case "toarray":
-				// 	si.toArray = true
-			}
-		}
-	}
-}
-
-type sfiSortedByEncName []*structFieldInfo
-
-func (p sfiSortedByEncName) Len() int {
-	return len(p)
-}
-
-func (p sfiSortedByEncName) Less(i, j int) bool {
-	return p[i].encName < p[j].encName
-}
-
-func (p sfiSortedByEncName) Swap(i, j int) {
-	p[i], p[j] = p[j], p[i]
-}
-
-const structFieldNodeNumToCache = 4
-
-type structFieldNodeCache struct {
-	rv  [structFieldNodeNumToCache]reflect.Value
-	idx [structFieldNodeNumToCache]uint32
-	num uint8
-}
-
-func (x *structFieldNodeCache) get(key uint32) (fv reflect.Value, valid bool) {
-	for i, k := range &x.idx {
-		if uint8(i) == x.num {
-			return // break
-		}
-		if key == k {
-			return x.rv[i], true
-		}
-	}
-	return
-}
-
-func (x *structFieldNodeCache) tryAdd(fv reflect.Value, key uint32) {
-	if x.num < structFieldNodeNumToCache {
-		x.rv[x.num] = fv
-		x.idx[x.num] = key
-		x.num++
-		return
-	}
-}
-
-type structFieldNode struct {
-	v      reflect.Value
-	cache2 structFieldNodeCache
-	cache3 structFieldNodeCache
-	update bool
-}
-
-func (x *structFieldNode) field(si *structFieldInfo) (fv reflect.Value) {
-	// return si.fieldval(x.v, x.update)
-	// Note: we only cache if nis=2 or nis=3 i.e. up to 2 levels of embedding
-	// This mostly saves us time on the repeated calls to v.Elem, v.Field, etc.
-	var valid bool
-	switch si.nis {
-	case 1:
-		fv = x.v.Field(int(si.is[0]))
-	case 2:
-		if fv, valid = x.cache2.get(uint32(si.is[0])); valid {
-			fv = fv.Field(int(si.is[1]))
-			return
-		}
-		fv = x.v.Field(int(si.is[0]))
-		if fv, valid = baseStructRv(fv, x.update); !valid {
-			return
-		}
-		x.cache2.tryAdd(fv, uint32(si.is[0]))
-		fv = fv.Field(int(si.is[1]))
-	case 3:
-		var key uint32 = uint32(si.is[0])<<16 | uint32(si.is[1])
-		if fv, valid = x.cache3.get(key); valid {
-			fv = fv.Field(int(si.is[2]))
-			return
-		}
-		fv = x.v.Field(int(si.is[0]))
-		if fv, valid = baseStructRv(fv, x.update); !valid {
-			return
-		}
-		fv = fv.Field(int(si.is[1]))
-		if fv, valid = baseStructRv(fv, x.update); !valid {
-			return
-		}
-		x.cache3.tryAdd(fv, key)
-		fv = fv.Field(int(si.is[2]))
-	default:
-		fv, _ = si.field(x.v, x.update)
-	}
-	return
-}
-
-func baseStructRv(v reflect.Value, update bool) (v2 reflect.Value, valid bool) {
-	for v.Kind() == reflect.Ptr {
-		if v.IsNil() {
-			if !update {
-				return
-			}
-			v.Set(reflect.New(v.Type().Elem()))
-		}
-		v = v.Elem()
-	}
-	return v, true
-}
-
-type typeInfoFlag uint8
-
-const (
-	typeInfoFlagComparable = 1 << iota
-	typeInfoFlagIsZeroer
-	typeInfoFlagIsZeroerPtr
-)
-
-// typeInfo keeps information about each (non-ptr) type referenced in the encode/decode sequence.
-//
-// During an encode/decode sequence, we work as below:
-//   - If base is a built in type, en/decode base value
-//   - If base is registered as an extension, en/decode base value
-//   - If type is binary(M/Unm)arshaler, call Binary(M/Unm)arshal method
-//   - If type is text(M/Unm)arshaler, call Text(M/Unm)arshal method
-//   - Else decode appropriately based on the reflect.Kind
-type typeInfo struct {
-	rt      reflect.Type
-	elem    reflect.Type
-	pkgpath string
-
-	rtid uintptr
-	// rv0  reflect.Value // saved zero value, used if immutableKind
-
-	numMeth uint16 // number of methods
-	kind    uint8
-	chandir uint8
-
-	anyOmitEmpty bool      // true if a struct, and any of the fields are tagged "omitempty"
-	toArray      bool      // whether this (struct) type should be encoded as an array
-	keyType      valueType // if struct, how is the field name stored in a stream? default is string
-	mbs          bool      // base type (T or *T) is a MapBySlice
-
-	// ---- cpu cache line boundary?
-	sfiSort []*structFieldInfo // sorted. Used when enc/dec struct to map.
-	sfiSrc  []*structFieldInfo // unsorted. Used when enc/dec struct to array.
-
-	key reflect.Type
-
-	// ---- cpu cache line boundary?
-	// sfis         []structFieldInfo // all sfi, in src order, as created.
-	sfiNamesSort []byte // all names, with indexes into the sfiSort
-
-	// format of marshal type fields below: [btj][mu]p? OR csp?
-
-	bm  bool // T is a binaryMarshaler
-	bmp bool // *T is a binaryMarshaler
-	bu  bool // T is a binaryUnmarshaler
-	bup bool // *T is a binaryUnmarshaler
-	tm  bool // T is a textMarshaler
-	tmp bool // *T is a textMarshaler
-	tu  bool // T is a textUnmarshaler
-	tup bool // *T is a textUnmarshaler
-
-	jm  bool // T is a jsonMarshaler
-	jmp bool // *T is a jsonMarshaler
-	ju  bool // T is a jsonUnmarshaler
-	jup bool // *T is a jsonUnmarshaler
-	cs  bool // T is a Selfer
-	csp bool // *T is a Selfer
-
-	// other flags, with individual bits representing if set.
-	flags typeInfoFlag
-
-	// _ [2]byte   // padding
-	_ [3]uint64 // padding
-}
-
-func (ti *typeInfo) isFlag(f typeInfoFlag) bool {
-	return ti.flags&f != 0
-}
-
-func (ti *typeInfo) indexForEncName(name []byte) (index int16) {
-	var sn []byte
-	if len(name)+2 <= 32 {
-		var buf [32]byte // should not escape
-		sn = buf[:len(name)+2]
-	} else {
-		sn = make([]byte, len(name)+2)
-	}
-	copy(sn[1:], name)
-	sn[0], sn[len(sn)-1] = tiSep2(name), 0xff
-	j := bytes.Index(ti.sfiNamesSort, sn)
-	if j < 0 {
-		return -1
-	}
-	index = int16(uint16(ti.sfiNamesSort[j+len(sn)+1]) | uint16(ti.sfiNamesSort[j+len(sn)])<<8)
-	return
-}
-
-type rtid2ti struct {
-	rtid uintptr
-	ti   *typeInfo
-}
-
-// TypeInfos caches typeInfo for each type on first inspection.
-//
-// It is configured with a set of tag keys, which are used to get
-// configuration for the type.
-type TypeInfos struct {
-	// infos: formerly map[uintptr]*typeInfo, now *[]rtid2ti, 2 words expected
-	infos atomicTypeInfoSlice
-	mu    sync.Mutex
-	tags  []string
-	_     [2]uint64 // padding
-}
-
-// NewTypeInfos creates a TypeInfos given a set of struct tags keys.
-//
-// This allows users customize the struct tag keys which contain configuration
-// of their types.
-func NewTypeInfos(tags []string) *TypeInfos {
-	return &TypeInfos{tags: tags}
-}
-
-func (x *TypeInfos) structTag(t reflect.StructTag) (s string) {
-	// check for tags: codec, json, in that order.
-	// this allows seamless support for many configured structs.
-	for _, x := range x.tags {
-		s = t.Get(x)
-		if s != "" {
-			return s
-		}
-	}
-	return
-}
-
-func (x *TypeInfos) find(s []rtid2ti, rtid uintptr) (idx int, ti *typeInfo) {
-	// binary search. adapted from sort/search.go.
-	// if sp == nil {
-	// 	return -1, nil
-	// }
-	// s := *sp
-	h, i, j := 0, 0, len(s)
-	for i < j {
-		h = i + (j-i)/2
-		if s[h].rtid < rtid {
-			i = h + 1
-		} else {
-			j = h
-		}
-	}
-	if i < len(s) && s[i].rtid == rtid {
-		return i, s[i].ti
-	}
-	return i, nil
-}
-
-func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
-	sp := x.infos.load()
-	var idx int
-	if sp != nil {
-		idx, pti = x.find(sp, rtid)
-		if pti != nil {
-			return
-		}
-	}
-
-	rk := rt.Kind()
-
-	if rk == reflect.Ptr { // || (rk == reflect.Interface && rtid != intfTypId) {
-		panicv.errorf("invalid kind passed to TypeInfos.get: %v - %v", rk, rt)
-	}
-
-	// do not hold lock while computing this.
-	// it may lead to duplication, but that's ok.
-	ti := typeInfo{rt: rt, rtid: rtid, kind: uint8(rk), pkgpath: rt.PkgPath()}
-	// ti.rv0 = reflect.Zero(rt)
-
-	// ti.comparable = rt.Comparable()
-	ti.numMeth = uint16(rt.NumMethod())
-
-	ti.bm, ti.bmp = implIntf(rt, binaryMarshalerTyp)
-	ti.bu, ti.bup = implIntf(rt, binaryUnmarshalerTyp)
-	ti.tm, ti.tmp = implIntf(rt, textMarshalerTyp)
-	ti.tu, ti.tup = implIntf(rt, textUnmarshalerTyp)
-	ti.jm, ti.jmp = implIntf(rt, jsonMarshalerTyp)
-	ti.ju, ti.jup = implIntf(rt, jsonUnmarshalerTyp)
-	ti.cs, ti.csp = implIntf(rt, selferTyp)
-
-	b1, b2 := implIntf(rt, iszeroTyp)
-	if b1 {
-		ti.flags |= typeInfoFlagIsZeroer
-	}
-	if b2 {
-		ti.flags |= typeInfoFlagIsZeroerPtr
-	}
-	if rt.Comparable() {
-		ti.flags |= typeInfoFlagComparable
-	}
-
-	switch rk {
-	case reflect.Struct:
-		var omitEmpty bool
-		if f, ok := rt.FieldByName(structInfoFieldName); ok {
-			ti.toArray, omitEmpty, ti.keyType = parseStructInfo(x.structTag(f.Tag))
-		} else {
-			ti.keyType = valueTypeString
-		}
-		pp, pi := pool.tiLoad()
-		pv := pi.(*typeInfoLoadArray)
-		pv.etypes[0] = ti.rtid
-		// vv := typeInfoLoad{pv.fNames[:0], pv.encNames[:0], pv.etypes[:1], pv.sfis[:0]}
-		vv := typeInfoLoad{pv.etypes[:1], pv.sfis[:0]}
-		x.rget(rt, rtid, omitEmpty, nil, &vv)
-		// ti.sfis = vv.sfis
-		ti.sfiSrc, ti.sfiSort, ti.sfiNamesSort, ti.anyOmitEmpty = rgetResolveSFI(rt, vv.sfis, pv)
-		pp.Put(pi)
-	case reflect.Map:
-		ti.elem = rt.Elem()
-		ti.key = rt.Key()
-	case reflect.Slice:
-		ti.mbs, _ = implIntf(rt, mapBySliceTyp)
-		ti.elem = rt.Elem()
-	case reflect.Chan:
-		ti.elem = rt.Elem()
-		ti.chandir = uint8(rt.ChanDir())
-	case reflect.Array, reflect.Ptr:
-		ti.elem = rt.Elem()
-	}
-	// sfi = sfiSrc
-
-	x.mu.Lock()
-	sp = x.infos.load()
-	if sp == nil {
-		pti = &ti
-		vs := []rtid2ti{{rtid, pti}}
-		x.infos.store(vs)
-	} else {
-		idx, pti = x.find(sp, rtid)
-		if pti == nil {
-			pti = &ti
-			vs := make([]rtid2ti, len(sp)+1)
-			copy(vs, sp[:idx])
-			copy(vs[idx+1:], sp[idx:])
-			vs[idx] = rtid2ti{rtid, pti}
-			x.infos.store(vs)
-		}
-	}
-	x.mu.Unlock()
-	return
-}
-
-func (x *TypeInfos) rget(rt reflect.Type, rtid uintptr, omitEmpty bool,
-	indexstack []uint16, pv *typeInfoLoad) {
-	// Read up fields and store how to access the value.
-	//
-	// It uses go's rules for message selectors,
-	// which say that the field with the shallowest depth is selected.
-	//
-	// Note: we consciously use slices, not a map, to simulate a set.
-	//       Typically, types have < 16 fields,
-	//       and iteration using equals is faster than maps there
-	flen := rt.NumField()
-	if flen > (1<<maxLevelsEmbedding - 1) {
-		panicv.errorf("codec: types with > %v fields are not supported - has %v fields",
-			(1<<maxLevelsEmbedding - 1), flen)
-	}
-	// pv.sfis = make([]structFieldInfo, flen)
-LOOP:
-	for j, jlen := uint16(0), uint16(flen); j < jlen; j++ {
-		f := rt.Field(int(j))
-		fkind := f.Type.Kind()
-		// skip if a func type, or is unexported, or structTag value == "-"
-		switch fkind {
-		case reflect.Func, reflect.Complex64, reflect.Complex128, reflect.UnsafePointer:
-			continue LOOP
-		}
-
-		isUnexported := f.PkgPath != ""
-		if isUnexported && !f.Anonymous {
-			continue
-		}
-		stag := x.structTag(f.Tag)
-		if stag == "-" {
-			continue
-		}
-		var si structFieldInfo
-		var parsed bool
-		// if anonymous and no struct tag (or it's blank),
-		// and a struct (or pointer to struct), inline it.
-		if f.Anonymous && fkind != reflect.Interface {
-			// ^^ redundant but ok: per go spec, an embedded pointer type cannot be to an interface
-			ft := f.Type
-			isPtr := ft.Kind() == reflect.Ptr
-			for ft.Kind() == reflect.Ptr {
-				ft = ft.Elem()
-			}
-			isStruct := ft.Kind() == reflect.Struct
-
-			// Ignore embedded fields of unexported non-struct types.
-			// Also, from go1.10, ignore pointers to unexported struct types
-			// because unmarshal cannot assign a new struct to an unexported field.
-			// See https://golang.org/issue/21357
-			if (isUnexported && !isStruct) || (!allowSetUnexportedEmbeddedPtr && isUnexported && isPtr) {
-				continue
-			}
-			doInline := stag == ""
-			if !doInline {
-				si.parseTag(stag)
-				parsed = true
-				doInline = si.encName == ""
-				// doInline = si.isZero()
-			}
-			if doInline && isStruct {
-				// if etypes contains this, don't call rget again (as fields are already seen here)
-				ftid := rt2id(ft)
-				// We cannot recurse forever, but we need to track other field depths.
-				// So - we break if we see a type twice (not the first time).
-				// This should be sufficient to handle an embedded type that refers to its
-				// owning type, which then refers to its embedded type.
-				processIt := true
-				numk := 0
-				for _, k := range pv.etypes {
-					if k == ftid {
-						numk++
-						if numk == rgetMaxRecursion {
-							processIt = false
-							break
-						}
-					}
-				}
-				if processIt {
-					pv.etypes = append(pv.etypes, ftid)
-					indexstack2 := make([]uint16, len(indexstack)+1)
-					copy(indexstack2, indexstack)
-					indexstack2[len(indexstack)] = j
-					// indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j)
-					x.rget(ft, ftid, omitEmpty, indexstack2, pv)
-				}
-				continue
-			}
-		}
-
-		// after the anonymous dance: if an unexported field, skip
-		if isUnexported {
-			continue
-		}
-
-		if f.Name == "" {
-			panic(errNoFieldNameToStructFieldInfo)
-		}
-
-		// pv.fNames = append(pv.fNames, f.Name)
-		// if si.encName == "" {
-
-		if !parsed {
-			si.encName = f.Name
-			si.parseTag(stag)
-			parsed = true
-		} else if si.encName == "" {
-			si.encName = f.Name
-		}
-		si.fieldName = f.Name
-		si.flagSet(structFieldInfoFlagReady)
-
-		// pv.encNames = append(pv.encNames, si.encName)
-
-		// si.ikind = int(f.Type.Kind())
-		if len(indexstack) > maxLevelsEmbedding-1 {
-			panicv.errorf("codec: only supports up to %v depth of embedding - type has %v depth",
-				maxLevelsEmbedding-1, len(indexstack))
-		}
-		si.nis = uint8(len(indexstack)) + 1
-		copy(si.is[:], indexstack)
-		si.is[len(indexstack)] = j
-
-		if omitEmpty {
-			si.flagSet(structFieldInfoFlagOmitEmpty)
-		}
-		pv.sfis = append(pv.sfis, si)
-	}
-}
-
-func tiSep(name string) uint8 {
-	// (xn[0]%64) // (between 192-255 - outside ascii BMP)
-	// return 0xfe - (name[0] & 63)
-	// return 0xfe - (name[0] & 63) - uint8(len(name))
-	// return 0xfe - (name[0] & 63) - uint8(len(name)&63)
-	// return ((0xfe - (name[0] & 63)) & 0xf8) | (uint8(len(name) & 0x07))
-	return 0xfe - (name[0] & 63) - uint8(len(name)&63)
-}
-
-func tiSep2(name []byte) uint8 {
-	return 0xfe - (name[0] & 63) - uint8(len(name)&63)
-}
-
-// resolves the struct field info got from a call to rget.
-// Returns a trimmed, unsorted and sorted []*structFieldInfo.
-func rgetResolveSFI(rt reflect.Type, x []structFieldInfo, pv *typeInfoLoadArray) (
-	y, z []*structFieldInfo, ss []byte, anyOmitEmpty bool) {
-	sa := pv.sfiidx[:0]
-	sn := pv.b[:]
-	n := len(x)
-
-	var xn string
-	var ui uint16
-	var sep byte
-
-	for i := range x {
-		ui = uint16(i)
-		xn = x[i].encName // fieldName or encName? use encName for now.
-		if len(xn)+2 > cap(pv.b) {
-			sn = make([]byte, len(xn)+2)
-		} else {
-			sn = sn[:len(xn)+2]
-		}
-		// use a custom sep, so that misses are less frequent,
-		// since the sep (first char in search) is as unique as first char in field name.
-		sep = tiSep(xn)
-		sn[0], sn[len(sn)-1] = sep, 0xff
-		copy(sn[1:], xn)
-		j := bytes.Index(sa, sn)
-		if j == -1 {
-			sa = append(sa, sep)
-			sa = append(sa, xn...)
-			sa = append(sa, 0xff, byte(ui>>8), byte(ui))
-		} else {
-			index := uint16(sa[j+len(sn)+1]) | uint16(sa[j+len(sn)])<<8
-			// one of them must be reset to nil,
-			// and the index updated appropriately to the other one
-			if x[i].nis == x[index].nis {
-			} else if x[i].nis < x[index].nis {
-				sa[j+len(sn)], sa[j+len(sn)+1] = byte(ui>>8), byte(ui)
-				if x[index].ready() {
-					x[index].flagClr(structFieldInfoFlagReady)
-					n--
-				}
-			} else {
-				if x[i].ready() {
-					x[i].flagClr(structFieldInfoFlagReady)
-					n--
-				}
-			}
-		}
-
-	}
-	var w []structFieldInfo
-	sharingArray := len(x) <= typeInfoLoadArraySfisLen // sharing array with typeInfoLoadArray
-	if sharingArray {
-		w = make([]structFieldInfo, n)
-	}
-
-	// remove all the nils (non-ready)
-	y = make([]*structFieldInfo, n)
-	n = 0
-	var sslen int
-	for i := range x {
-		if !x[i].ready() {
-			continue
-		}
-		if !anyOmitEmpty && x[i].omitEmpty() {
-			anyOmitEmpty = true
-		}
-		if sharingArray {
-			w[n] = x[i]
-			y[n] = &w[n]
-		} else {
-			y[n] = &x[i]
-		}
-		sslen = sslen + len(x[i].encName) + 4
-		n++
-	}
-	if n != len(y) {
-		panicv.errorf("failure reading struct %v - expecting %d of %d valid fields, got %d",
-			rt, len(y), len(x), n)
-	}
-
-	z = make([]*structFieldInfo, len(y))
-	copy(z, y)
-	sort.Sort(sfiSortedByEncName(z))
-
-	sharingArray = len(sa) <= typeInfoLoadArraySfiidxLen
-	if sharingArray {
-		ss = make([]byte, 0, sslen)
-	} else {
-		ss = sa[:0] // reuse the newly made sa array if necessary
-	}
-	for i := range z {
-		xn = z[i].encName
-		sep = tiSep(xn)
-		ui = uint16(i)
-		ss = append(ss, sep)
-		ss = append(ss, xn...)
-		ss = append(ss, 0xff, byte(ui>>8), byte(ui))
-	}
-	return
-}
-
-func implIntf(rt, iTyp reflect.Type) (base bool, indir bool) {
-	return rt.Implements(iTyp), reflect.PtrTo(rt).Implements(iTyp)
-}
-
-// isEmptyStruct is only called from isEmptyValue, and checks if a struct is empty:
-//    - does it implement IsZero() bool
-//    - is it comparable, and can i compare directly using ==
-//    - if checkStruct, then walk through the encodable fields
-//      and check if they are empty or not.
-func isEmptyStruct(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
-	// v is a struct kind - no need to check again.
-	// We only check isZero on a struct kind, to reduce the amount of times
-	// that we lookup the rtid and typeInfo for each type as we walk the tree.
-
-	vt := v.Type()
-	rtid := rt2id(vt)
-	if tinfos == nil {
-		tinfos = defTypeInfos
-	}
-	ti := tinfos.get(rtid, vt)
-	if ti.rtid == timeTypId {
-		return rv2i(v).(time.Time).IsZero()
-	}
-	if ti.isFlag(typeInfoFlagIsZeroerPtr) && v.CanAddr() {
-		return rv2i(v.Addr()).(isZeroer).IsZero()
-	}
-	if ti.isFlag(typeInfoFlagIsZeroer) {
-		return rv2i(v).(isZeroer).IsZero()
-	}
-	if ti.isFlag(typeInfoFlagComparable) {
-		return rv2i(v) == rv2i(reflect.Zero(vt))
-	}
-	if !checkStruct {
-		return false
-	}
-	// We only care about what we can encode/decode,
-	// so that is what we use to check omitEmpty.
-	for _, si := range ti.sfiSrc {
-		sfv, valid := si.field(v, false)
-		if valid && !isEmptyValue(sfv, tinfos, deref, checkStruct) {
-			return false
-		}
-	}
-	return true
-}
-
-// func roundFloat(x float64) float64 {
-// 	t := math.Trunc(x)
-// 	if math.Abs(x-t) >= 0.5 {
-// 		return t + math.Copysign(1, x)
-// 	}
-// 	return t
-// }
-
-func panicToErr(h errstrDecorator, err *error) {
-	// Note: This method MUST be called directly from defer i.e. defer panicToErr ...
-	// else it seems the recover is not fully handled
-	if recoverPanicToErr {
-		if x := recover(); x != nil {
-			// fmt.Printf("panic'ing with: %v\n", x)
-			// debug.PrintStack()
-			panicValToErr(h, x, err)
-		}
-	}
-}
-
-func panicValToErr(h errstrDecorator, v interface{}, err *error) {
-	switch xerr := v.(type) {
-	case nil:
-	case error:
-		switch xerr {
-		case nil:
-		case io.EOF, io.ErrUnexpectedEOF, errEncoderNotInitialized, errDecoderNotInitialized:
-			// treat as special (bubble up)
-			*err = xerr
-		default:
-			h.wrapErrstr(xerr.Error(), err)
-		}
-	case string:
-		if xerr != "" {
-			h.wrapErrstr(xerr, err)
-		}
-	case fmt.Stringer:
-		if xerr != nil {
-			h.wrapErrstr(xerr.String(), err)
-		}
-	default:
-		h.wrapErrstr(v, err)
-	}
-}
-
-func isImmutableKind(k reflect.Kind) (v bool) {
-	return immutableKindsSet[k]
-}
-
-// ----
-
-type codecFnInfo struct {
-	ti    *typeInfo
-	xfFn  Ext
-	xfTag uint64
-	seq   seqType
-	addrD bool
-	addrF bool // if addrD, this says whether decode function can take a value or a ptr
-	addrE bool
-	ready bool // ready to use
-}
-
-// codecFn encapsulates the captured variables and the encode function.
-// This way, we only do some calculations one times, and pass to the
-// code block that should be called (encapsulated in a function)
-// instead of executing the checks every time.
-type codecFn struct {
-	i  codecFnInfo
-	fe func(*Encoder, *codecFnInfo, reflect.Value)
-	fd func(*Decoder, *codecFnInfo, reflect.Value)
-	_  [1]uint64 // padding
-}
-
-type codecRtidFn struct {
-	rtid uintptr
-	fn   *codecFn
-}
-
-type codecFner struct {
-	// hh Handle
-	h  *BasicHandle
-	s  []codecRtidFn
-	be bool
-	js bool
-	_  [6]byte   // padding
-	_  [3]uint64 // padding
-}
-
-func (c *codecFner) reset(hh Handle) {
-	bh := hh.getBasicHandle()
-	// only reset iff extensions changed or *TypeInfos changed
-	var hhSame = true &&
-		c.h == bh && c.h.TypeInfos == bh.TypeInfos &&
-		len(c.h.extHandle) == len(bh.extHandle) &&
-		(len(c.h.extHandle) == 0 || &c.h.extHandle[0] == &bh.extHandle[0])
-	if !hhSame {
-		// c.hh = hh
-		c.h, bh = bh, c.h // swap both
-		_, c.js = hh.(*JsonHandle)
-		c.be = hh.isBinary()
-		for i := range c.s {
-			c.s[i].fn.i.ready = false
-		}
-	}
-}
-
-func (c *codecFner) get(rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn *codecFn) {
-	rtid := rt2id(rt)
-
-	for _, x := range c.s {
-		if x.rtid == rtid {
-			// if rtid exists, then there's a *codenFn attached (non-nil)
-			fn = x.fn
-			if fn.i.ready {
-				return
-			}
-			break
-		}
-	}
-	var ti *typeInfo
-	if fn == nil {
-		fn = new(codecFn)
-		if c.s == nil {
-			c.s = make([]codecRtidFn, 0, 8)
-		}
-		c.s = append(c.s, codecRtidFn{rtid, fn})
-	} else {
-		ti = fn.i.ti
-		*fn = codecFn{}
-		fn.i.ti = ti
-		// fn.fe, fn.fd = nil, nil
-	}
-	fi := &(fn.i)
-	fi.ready = true
-	if ti == nil {
-		ti = c.h.getTypeInfo(rtid, rt)
-		fi.ti = ti
-	}
-
-	rk := reflect.Kind(ti.kind)
-
-	if checkCodecSelfer && (ti.cs || ti.csp) {
-		fn.fe = (*Encoder).selferMarshal
-		fn.fd = (*Decoder).selferUnmarshal
-		fi.addrF = true
-		fi.addrD = ti.csp
-		fi.addrE = ti.csp
-	} else if rtid == timeTypId {
-		fn.fe = (*Encoder).kTime
-		fn.fd = (*Decoder).kTime
-	} else if rtid == rawTypId {
-		fn.fe = (*Encoder).raw
-		fn.fd = (*Decoder).raw
-	} else if rtid == rawExtTypId {
-		fn.fe = (*Encoder).rawExt
-		fn.fd = (*Decoder).rawExt
-		fi.addrF = true
-		fi.addrD = true
-		fi.addrE = true
-	} else if xfFn := c.h.getExt(rtid); xfFn != nil {
-		fi.xfTag, fi.xfFn = xfFn.tag, xfFn.ext
-		fn.fe = (*Encoder).ext
-		fn.fd = (*Decoder).ext
-		fi.addrF = true
-		fi.addrD = true
-		if rk == reflect.Struct || rk == reflect.Array {
-			fi.addrE = true
-		}
-	} else if supportMarshalInterfaces && c.be && (ti.bm || ti.bmp) && (ti.bu || ti.bup) {
-		fn.fe = (*Encoder).binaryMarshal
-		fn.fd = (*Decoder).binaryUnmarshal
-		fi.addrF = true
-		fi.addrD = ti.bup
-		fi.addrE = ti.bmp
-	} else if supportMarshalInterfaces && !c.be && c.js && (ti.jm || ti.jmp) && (ti.ju || ti.jup) {
-		//If JSON, we should check JSONMarshal before textMarshal
-		fn.fe = (*Encoder).jsonMarshal
-		fn.fd = (*Decoder).jsonUnmarshal
-		fi.addrF = true
-		fi.addrD = ti.jup
-		fi.addrE = ti.jmp
-	} else if supportMarshalInterfaces && !c.be && (ti.tm || ti.tmp) && (ti.tu || ti.tup) {
-		fn.fe = (*Encoder).textMarshal
-		fn.fd = (*Decoder).textUnmarshal
-		fi.addrF = true
-		fi.addrD = ti.tup
-		fi.addrE = ti.tmp
-	} else {
-		if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) {
-			if ti.pkgpath == "" { // un-named slice or map
-				if idx := fastpathAV.index(rtid); idx != -1 {
-					fn.fe = fastpathAV[idx].encfn
-					fn.fd = fastpathAV[idx].decfn
-					fi.addrD = true
-					fi.addrF = false
-				}
-			} else {
-				// use mapping for underlying type if there
-				var rtu reflect.Type
-				if rk == reflect.Map {
-					rtu = reflect.MapOf(ti.key, ti.elem)
-				} else {
-					rtu = reflect.SliceOf(ti.elem)
-				}
-				rtuid := rt2id(rtu)
-				if idx := fastpathAV.index(rtuid); idx != -1 {
-					xfnf := fastpathAV[idx].encfn
-					xrt := fastpathAV[idx].rt
-					fn.fe = func(e *Encoder, xf *codecFnInfo, xrv reflect.Value) {
-						xfnf(e, xf, xrv.Convert(xrt))
-					}
-					fi.addrD = true
-					fi.addrF = false // meaning it can be an address(ptr) or a value
-					xfnf2 := fastpathAV[idx].decfn
-					fn.fd = func(d *Decoder, xf *codecFnInfo, xrv reflect.Value) {
-						if xrv.Kind() == reflect.Ptr {
-							xfnf2(d, xf, xrv.Convert(reflect.PtrTo(xrt)))
-						} else {
-							xfnf2(d, xf, xrv.Convert(xrt))
-						}
-					}
-				}
-			}
-		}
-		if fn.fe == nil && fn.fd == nil {
-			switch rk {
-			case reflect.Bool:
-				fn.fe = (*Encoder).kBool
-				fn.fd = (*Decoder).kBool
-			case reflect.String:
-				fn.fe = (*Encoder).kString
-				fn.fd = (*Decoder).kString
-			case reflect.Int:
-				fn.fd = (*Decoder).kInt
-				fn.fe = (*Encoder).kInt
-			case reflect.Int8:
-				fn.fe = (*Encoder).kInt8
-				fn.fd = (*Decoder).kInt8
-			case reflect.Int16:
-				fn.fe = (*Encoder).kInt16
-				fn.fd = (*Decoder).kInt16
-			case reflect.Int32:
-				fn.fe = (*Encoder).kInt32
-				fn.fd = (*Decoder).kInt32
-			case reflect.Int64:
-				fn.fe = (*Encoder).kInt64
-				fn.fd = (*Decoder).kInt64
-			case reflect.Uint:
-				fn.fd = (*Decoder).kUint
-				fn.fe = (*Encoder).kUint
-			case reflect.Uint8:
-				fn.fe = (*Encoder).kUint8
-				fn.fd = (*Decoder).kUint8
-			case reflect.Uint16:
-				fn.fe = (*Encoder).kUint16
-				fn.fd = (*Decoder).kUint16
-			case reflect.Uint32:
-				fn.fe = (*Encoder).kUint32
-				fn.fd = (*Decoder).kUint32
-			case reflect.Uint64:
-				fn.fe = (*Encoder).kUint64
-				fn.fd = (*Decoder).kUint64
-			case reflect.Uintptr:
-				fn.fe = (*Encoder).kUintptr
-				fn.fd = (*Decoder).kUintptr
-			case reflect.Float32:
-				fn.fe = (*Encoder).kFloat32
-				fn.fd = (*Decoder).kFloat32
-			case reflect.Float64:
-				fn.fe = (*Encoder).kFloat64
-				fn.fd = (*Decoder).kFloat64
-			case reflect.Invalid:
-				fn.fe = (*Encoder).kInvalid
-				fn.fd = (*Decoder).kErr
-			case reflect.Chan:
-				fi.seq = seqTypeChan
-				fn.fe = (*Encoder).kSlice
-				fn.fd = (*Decoder).kSlice
-			case reflect.Slice:
-				fi.seq = seqTypeSlice
-				fn.fe = (*Encoder).kSlice
-				fn.fd = (*Decoder).kSlice
-			case reflect.Array:
-				fi.seq = seqTypeArray
-				fn.fe = (*Encoder).kSlice
-				fi.addrF = false
-				fi.addrD = false
-				rt2 := reflect.SliceOf(ti.elem)
-				fn.fd = func(d *Decoder, xf *codecFnInfo, xrv reflect.Value) {
-					d.cfer().get(rt2, true, false).fd(d, xf, xrv.Slice(0, xrv.Len()))
-				}
-				// fn.fd = (*Decoder).kArray
-			case reflect.Struct:
-				if ti.anyOmitEmpty {
-					fn.fe = (*Encoder).kStruct
-				} else {
-					fn.fe = (*Encoder).kStructNoOmitempty
-				}
-				fn.fd = (*Decoder).kStruct
-			case reflect.Map:
-				fn.fe = (*Encoder).kMap
-				fn.fd = (*Decoder).kMap
-			case reflect.Interface:
-				// encode: reflect.Interface are handled already by preEncodeValue
-				fn.fd = (*Decoder).kInterface
-				fn.fe = (*Encoder).kErr
-			default:
-				// reflect.Ptr and reflect.Interface are handled already by preEncodeValue
-				fn.fe = (*Encoder).kErr
-				fn.fd = (*Decoder).kErr
-			}
-		}
-	}
-	return
-}
-
-type codecFnPooler struct {
-	cf  *codecFner
-	cfp *sync.Pool
-	hh  Handle
-}
-
-func (d *codecFnPooler) cfer() *codecFner {
-	if d.cf == nil {
-		var v interface{}
-		d.cfp, v = pool.codecFner()
-		d.cf = v.(*codecFner)
-		d.cf.reset(d.hh)
-	}
-	return d.cf
-}
-
-func (d *codecFnPooler) alwaysAtEnd() {
-	if d.cf != nil {
-		d.cfp.Put(d.cf)
-		d.cf, d.cfp = nil, nil
-	}
-}
-
-// ----
-
-// these "checkOverflow" functions must be inlinable, and not call anybody.
-// Overflow means that the value cannot be represented without wrapping/overflow.
-// Overflow=false does not mean that the value can be represented without losing precision
-// (especially for floating point).
-
-type checkOverflow struct{}
-
-// func (checkOverflow) Float16(f float64) (overflow bool) {
-// 	panicv.errorf("unimplemented")
-// 	if f < 0 {
-// 		f = -f
-// 	}
-// 	return math.MaxFloat32 < f && f <= math.MaxFloat64
-// }
-
-func (checkOverflow) Float32(v float64) (overflow bool) {
-	if v < 0 {
-		v = -v
-	}
-	return math.MaxFloat32 < v && v <= math.MaxFloat64
-}
-func (checkOverflow) Uint(v uint64, bitsize uint8) (overflow bool) {
-	if bitsize == 0 || bitsize >= 64 || v == 0 {
-		return
-	}
-	if trunc := (v << (64 - bitsize)) >> (64 - bitsize); v != trunc {
-		overflow = true
-	}
-	return
-}
-func (checkOverflow) Int(v int64, bitsize uint8) (overflow bool) {
-	if bitsize == 0 || bitsize >= 64 || v == 0 {
-		return
-	}
-	if trunc := (v << (64 - bitsize)) >> (64 - bitsize); v != trunc {
-		overflow = true
-	}
-	return
-}
-func (checkOverflow) SignedInt(v uint64) (overflow bool) {
-	//e.g. -127 to 128 for int8
-	pos := (v >> 63) == 0
-	ui2 := v & 0x7fffffffffffffff
-	if pos {
-		if ui2 > math.MaxInt64 {
-			overflow = true
-		}
-	} else {
-		if ui2 > math.MaxInt64-1 {
-			overflow = true
-		}
-	}
-	return
-}
-
-func (x checkOverflow) Float32V(v float64) float64 {
-	if x.Float32(v) {
-		panicv.errorf("float32 overflow: %v", v)
-	}
-	return v
-}
-func (x checkOverflow) UintV(v uint64, bitsize uint8) uint64 {
-	if x.Uint(v, bitsize) {
-		panicv.errorf("uint64 overflow: %v", v)
-	}
-	return v
-}
-func (x checkOverflow) IntV(v int64, bitsize uint8) int64 {
-	if x.Int(v, bitsize) {
-		panicv.errorf("int64 overflow: %v", v)
-	}
-	return v
-}
-func (x checkOverflow) SignedIntV(v uint64) int64 {
-	if x.SignedInt(v) {
-		panicv.errorf("uint64 to int64 overflow: %v", v)
-	}
-	return int64(v)
-}
-
-// ------------------ SORT -----------------
-
-func isNaN(f float64) bool { return f != f }
-
-// -----------------------
-
-type ioFlusher interface {
-	Flush() error
-}
-
-type ioPeeker interface {
-	Peek(int) ([]byte, error)
-}
-
-type ioBuffered interface {
-	Buffered() int
-}
-
-// -----------------------
-
-type intSlice []int64
-type uintSlice []uint64
-
-// type uintptrSlice []uintptr
-type floatSlice []float64
-type boolSlice []bool
-type stringSlice []string
-
-// type bytesSlice [][]byte
-
-func (p intSlice) Len() int           { return len(p) }
-func (p intSlice) Less(i, j int) bool { return p[i] < p[j] }
-func (p intSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-func (p uintSlice) Len() int           { return len(p) }
-func (p uintSlice) Less(i, j int) bool { return p[i] < p[j] }
-func (p uintSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-// func (p uintptrSlice) Len() int           { return len(p) }
-// func (p uintptrSlice) Less(i, j int) bool { return p[i] < p[j] }
-// func (p uintptrSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-func (p floatSlice) Len() int { return len(p) }
-func (p floatSlice) Less(i, j int) bool {
-	return p[i] < p[j] || isNaN(p[i]) && !isNaN(p[j])
-}
-func (p floatSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-
-func (p stringSlice) Len() int           { return len(p) }
-func (p stringSlice) Less(i, j int) bool { return p[i] < p[j] }
-func (p stringSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-// func (p bytesSlice) Len() int           { return len(p) }
-// func (p bytesSlice) Less(i, j int) bool { return bytes.Compare(p[i], p[j]) == -1 }
-// func (p bytesSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-func (p boolSlice) Len() int           { return len(p) }
-func (p boolSlice) Less(i, j int) bool { return !p[i] && p[j] }
-func (p boolSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-// ---------------------
-
-type intRv struct {
-	v int64
-	r reflect.Value
-}
-type intRvSlice []intRv
-type uintRv struct {
-	v uint64
-	r reflect.Value
-}
-type uintRvSlice []uintRv
-type floatRv struct {
-	v float64
-	r reflect.Value
-}
-type floatRvSlice []floatRv
-type boolRv struct {
-	v bool
-	r reflect.Value
-}
-type boolRvSlice []boolRv
-type stringRv struct {
-	v string
-	r reflect.Value
-}
-type stringRvSlice []stringRv
-type bytesRv struct {
-	v []byte
-	r reflect.Value
-}
-type bytesRvSlice []bytesRv
-type timeRv struct {
-	v time.Time
-	r reflect.Value
-}
-type timeRvSlice []timeRv
-
-func (p intRvSlice) Len() int           { return len(p) }
-func (p intRvSlice) Less(i, j int) bool { return p[i].v < p[j].v }
-func (p intRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-func (p uintRvSlice) Len() int           { return len(p) }
-func (p uintRvSlice) Less(i, j int) bool { return p[i].v < p[j].v }
-func (p uintRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-func (p floatRvSlice) Len() int { return len(p) }
-func (p floatRvSlice) Less(i, j int) bool {
-	return p[i].v < p[j].v || isNaN(p[i].v) && !isNaN(p[j].v)
-}
-func (p floatRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-
-func (p stringRvSlice) Len() int           { return len(p) }
-func (p stringRvSlice) Less(i, j int) bool { return p[i].v < p[j].v }
-func (p stringRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-func (p bytesRvSlice) Len() int           { return len(p) }
-func (p bytesRvSlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 }
-func (p bytesRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-func (p boolRvSlice) Len() int           { return len(p) }
-func (p boolRvSlice) Less(i, j int) bool { return !p[i].v && p[j].v }
-func (p boolRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-func (p timeRvSlice) Len() int           { return len(p) }
-func (p timeRvSlice) Less(i, j int) bool { return p[i].v.Before(p[j].v) }
-func (p timeRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-// -----------------
-
-type bytesI struct {
-	v []byte
-	i interface{}
-}
-
-type bytesISlice []bytesI
-
-func (p bytesISlice) Len() int           { return len(p) }
-func (p bytesISlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 }
-func (p bytesISlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-// -----------------
-
-type set []uintptr
-
-func (s *set) add(v uintptr) (exists bool) {
-	// e.ci is always nil, or len >= 1
-	x := *s
-	if x == nil {
-		x = make([]uintptr, 1, 8)
-		x[0] = v
-		*s = x
-		return
-	}
-	// typically, length will be 1. make this perform.
-	if len(x) == 1 {
-		if j := x[0]; j == 0 {
-			x[0] = v
-		} else if j == v {
-			exists = true
-		} else {
-			x = append(x, v)
-			*s = x
-		}
-		return
-	}
-	// check if it exists
-	for _, j := range x {
-		if j == v {
-			exists = true
-			return
-		}
-	}
-	// try to replace a "deleted" slot
-	for i, j := range x {
-		if j == 0 {
-			x[i] = v
-			return
-		}
-	}
-	// if unable to replace deleted slot, just append it.
-	x = append(x, v)
-	*s = x
-	return
-}
-
-func (s *set) remove(v uintptr) (exists bool) {
-	x := *s
-	if len(x) == 0 {
-		return
-	}
-	if len(x) == 1 {
-		if x[0] == v {
-			x[0] = 0
-		}
-		return
-	}
-	for i, j := range x {
-		if j == v {
-			exists = true
-			x[i] = 0 // set it to 0, as way to delete it.
-			// copy(x[i:], x[i+1:])
-			// x = x[:len(x)-1]
-			return
-		}
-	}
-	return
-}
-
-// ------
-
-// bitset types are better than [256]bool, because they permit the whole
-// bitset array being on a single cache line and use less memory.
-
-// given x > 0 and n > 0 and x is exactly 2^n, then pos/x === pos>>n AND pos%x === pos&(x-1).
-// consequently, pos/32 === pos>>5, pos/16 === pos>>4, pos/8 === pos>>3, pos%8 == pos&7
-
-type bitset256 [32]byte
-
-func (x *bitset256) isset(pos byte) bool {
-	return x[pos>>3]&(1<<(pos&7)) != 0
-}
-func (x *bitset256) issetv(pos byte) byte {
-	return x[pos>>3] & (1 << (pos & 7))
-}
-func (x *bitset256) set(pos byte) {
-	x[pos>>3] |= (1 << (pos & 7))
-}
-
-// func (x *bitset256) unset(pos byte) {
-// 	x[pos>>3] &^= (1 << (pos & 7))
-// }
-
-type bitset128 [16]byte
-
-func (x *bitset128) isset(pos byte) bool {
-	return x[pos>>3]&(1<<(pos&7)) != 0
-}
-func (x *bitset128) set(pos byte) {
-	x[pos>>3] |= (1 << (pos & 7))
-}
-
-// func (x *bitset128) unset(pos byte) {
-// 	x[pos>>3] &^= (1 << (pos & 7))
-// }
-
-type bitset32 [4]byte
-
-func (x *bitset32) isset(pos byte) bool {
-	return x[pos>>3]&(1<<(pos&7)) != 0
-}
-func (x *bitset32) set(pos byte) {
-	x[pos>>3] |= (1 << (pos & 7))
-}
-
-// func (x *bitset32) unset(pos byte) {
-// 	x[pos>>3] &^= (1 << (pos & 7))
-// }
-
-// type bit2set256 [64]byte
-
-// func (x *bit2set256) set(pos byte, v1, v2 bool) {
-// 	var pos2 uint8 = (pos & 3) << 1 // returning 0, 2, 4 or 6
-// 	if v1 {
-// 		x[pos>>2] |= 1 << (pos2 + 1)
-// 	}
-// 	if v2 {
-// 		x[pos>>2] |= 1 << pos2
-// 	}
-// }
-// func (x *bit2set256) get(pos byte) uint8 {
-// 	var pos2 uint8 = (pos & 3) << 1     // returning 0, 2, 4 or 6
-// 	return x[pos>>2] << (6 - pos2) >> 6 // 11000000 -> 00000011
-// }
-
-// ------------
-
-type pooler struct {
-	dn                                          sync.Pool // for decNaked
-	cfn                                         sync.Pool // for codecFner
-	tiload                                      sync.Pool
-	strRv8, strRv16, strRv32, strRv64, strRv128 sync.Pool // for stringRV
-}
-
-func (p *pooler) init() {
-	p.strRv8.New = func() interface{} { return new([8]stringRv) }
-	p.strRv16.New = func() interface{} { return new([16]stringRv) }
-	p.strRv32.New = func() interface{} { return new([32]stringRv) }
-	p.strRv64.New = func() interface{} { return new([64]stringRv) }
-	p.strRv128.New = func() interface{} { return new([128]stringRv) }
-	p.dn.New = func() interface{} { x := new(decNaked); x.init(); return x }
-	p.tiload.New = func() interface{} { return new(typeInfoLoadArray) }
-	p.cfn.New = func() interface{} { return new(codecFner) }
-}
-
-func (p *pooler) stringRv8() (sp *sync.Pool, v interface{}) {
-	return &p.strRv8, p.strRv8.Get()
-}
-func (p *pooler) stringRv16() (sp *sync.Pool, v interface{}) {
-	return &p.strRv16, p.strRv16.Get()
-}
-func (p *pooler) stringRv32() (sp *sync.Pool, v interface{}) {
-	return &p.strRv32, p.strRv32.Get()
-}
-func (p *pooler) stringRv64() (sp *sync.Pool, v interface{}) {
-	return &p.strRv64, p.strRv64.Get()
-}
-func (p *pooler) stringRv128() (sp *sync.Pool, v interface{}) {
-	return &p.strRv128, p.strRv128.Get()
-}
-func (p *pooler) decNaked() (sp *sync.Pool, v interface{}) {
-	return &p.dn, p.dn.Get()
-}
-func (p *pooler) codecFner() (sp *sync.Pool, v interface{}) {
-	return &p.cfn, p.cfn.Get()
-}
-func (p *pooler) tiLoad() (sp *sync.Pool, v interface{}) {
-	return &p.tiload, p.tiload.Get()
-}
-
-// func (p *pooler) decNaked() (v *decNaked, f func(*decNaked) ) {
-// 	sp := &(p.dn)
-// 	vv := sp.Get()
-// 	return vv.(*decNaked), func(x *decNaked) { sp.Put(vv) }
-// }
-// func (p *pooler) decNakedGet() (v interface{}) {
-// 	return p.dn.Get()
-// }
-// func (p *pooler) codecFnerGet() (v interface{}) {
-// 	return p.cfn.Get()
-// }
-// func (p *pooler) tiLoadGet() (v interface{}) {
-// 	return p.tiload.Get()
-// }
-// func (p *pooler) decNakedPut(v interface{}) {
-// 	p.dn.Put(v)
-// }
-// func (p *pooler) codecFnerPut(v interface{}) {
-// 	p.cfn.Put(v)
-// }
-// func (p *pooler) tiLoadPut(v interface{}) {
-// 	p.tiload.Put(v)
-// }
-
-type panicHdl struct{}
-
-func (panicHdl) errorv(err error) {
-	if err != nil {
-		panic(err)
-	}
-}
-
-func (panicHdl) errorstr(message string) {
-	if message != "" {
-		panic(message)
-	}
-}
-
-func (panicHdl) errorf(format string, params ...interface{}) {
-	if format != "" {
-		if len(params) == 0 {
-			panic(format)
-		} else {
-			panic(fmt.Sprintf(format, params...))
-		}
-	}
-}
-
-type errstrDecorator interface {
-	wrapErrstr(interface{}, *error)
-}
-
-type errstrDecoratorDef struct{}
-
-func (errstrDecoratorDef) wrapErrstr(v interface{}, e *error) { *e = fmt.Errorf("%v", v) }
-
-type must struct{}
-
-func (must) String(s string, err error) string {
-	if err != nil {
-		panicv.errorv(err)
-	}
-	return s
-}
-func (must) Int(s int64, err error) int64 {
-	if err != nil {
-		panicv.errorv(err)
-	}
-	return s
-}
-func (must) Uint(s uint64, err error) uint64 {
-	if err != nil {
-		panicv.errorv(err)
-	}
-	return s
-}
-func (must) Float(s float64, err error) float64 {
-	if err != nil {
-		panicv.errorv(err)
-	}
-	return s
-}
-
-// xdebugf prints the message in red on the terminal.
-// Use it in place of fmt.Printf (which it calls internally)
-func xdebugf(pattern string, args ...interface{}) {
-	var delim string
-	if len(pattern) > 0 && pattern[len(pattern)-1] != '\n' {
-		delim = "\n"
-	}
-	fmt.Printf("\033[1;31m"+pattern+delim+"\033[0m", args...)
-}
-
-// func isImmutableKind(k reflect.Kind) (v bool) {
-// 	return false ||
-// 		k == reflect.Int ||
-// 		k == reflect.Int8 ||
-// 		k == reflect.Int16 ||
-// 		k == reflect.Int32 ||
-// 		k == reflect.Int64 ||
-// 		k == reflect.Uint ||
-// 		k == reflect.Uint8 ||
-// 		k == reflect.Uint16 ||
-// 		k == reflect.Uint32 ||
-// 		k == reflect.Uint64 ||
-// 		k == reflect.Uintptr ||
-// 		k == reflect.Float32 ||
-// 		k == reflect.Float64 ||
-// 		k == reflect.Bool ||
-// 		k == reflect.String
-// }
-
-// func timeLocUTCName(tzint int16) string {
-// 	if tzint == 0 {
-// 		return "UTC"
-// 	}
-// 	var tzname = []byte("UTC+00:00")
-// 	//tzname := fmt.Sprintf("UTC%s%02d:%02d", tzsign, tz/60, tz%60) //perf issue using Sprintf. inline below.
-// 	//tzhr, tzmin := tz/60, tz%60 //faster if u convert to int first
-// 	var tzhr, tzmin int16
-// 	if tzint < 0 {
-// 		tzname[3] = '-' // (TODO: verify. this works here)
-// 		tzhr, tzmin = -tzint/60, (-tzint)%60
-// 	} else {
-// 		tzhr, tzmin = tzint/60, tzint%60
-// 	}
-// 	tzname[4] = timeDigits[tzhr/10]
-// 	tzname[5] = timeDigits[tzhr%10]
-// 	tzname[7] = timeDigits[tzmin/10]
-// 	tzname[8] = timeDigits[tzmin%10]
-// 	return string(tzname)
-// 	//return time.FixedZone(string(tzname), int(tzint)*60)
-// }
diff --git a/vendor/github.com/ugorji/go/codec/helper_internal.go b/vendor/github.com/ugorji/go/codec/helper_internal.go
deleted file mode 100644
index 0cbd665..0000000
--- a/vendor/github.com/ugorji/go/codec/helper_internal.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-// All non-std package dependencies live in this file,
-// so porting to different environment is easy (just update functions).
-
-func pruneSignExt(v []byte, pos bool) (n int) {
-	if len(v) < 2 {
-	} else if pos && v[0] == 0 {
-		for ; v[n] == 0 && n+1 < len(v) && (v[n+1]&(1<<7) == 0); n++ {
-		}
-	} else if !pos && v[0] == 0xff {
-		for ; v[n] == 0xff && n+1 < len(v) && (v[n+1]&(1<<7) != 0); n++ {
-		}
-	}
-	return
-}
-
-// validate that this function is correct ...
-// culled from OGRE (Object-Oriented Graphics Rendering Engine)
-// function: halfToFloatI (http://stderr.org/doc/ogre-doc/api/OgreBitwise_8h-source.html)
-func halfFloatToFloatBits(yy uint16) (d uint32) {
-	y := uint32(yy)
-	s := (y >> 15) & 0x01
-	e := (y >> 10) & 0x1f
-	m := y & 0x03ff
-
-	if e == 0 {
-		if m == 0 { // plu or minus 0
-			return s << 31
-		}
-		// Denormalized number -- renormalize it
-		for (m & 0x00000400) == 0 {
-			m <<= 1
-			e -= 1
-		}
-		e += 1
-		const zz uint32 = 0x0400
-		m &= ^zz
-	} else if e == 31 {
-		if m == 0 { // Inf
-			return (s << 31) | 0x7f800000
-		}
-		return (s << 31) | 0x7f800000 | (m << 13) // NaN
-	}
-	e = e + (127 - 15)
-	m = m << 13
-	return (s << 31) | (e << 23) | m
-}
-
-// GrowCap will return a new capacity for a slice, given the following:
-//   - oldCap: current capacity
-//   - unit: in-memory size of an element
-//   - num: number of elements to add
-func growCap(oldCap, unit, num int) (newCap int) {
-	// appendslice logic (if cap < 1024, *2, else *1.25):
-	//   leads to many copy calls, especially when copying bytes.
-	//   bytes.Buffer model (2*cap + n): much better for bytes.
-	// smarter way is to take the byte-size of the appended element(type) into account
-
-	// maintain 3 thresholds:
-	// t1: if cap <= t1, newcap = 2x
-	// t2: if cap <= t2, newcap = 1.75x
-	// t3: if cap <= t3, newcap = 1.5x
-	//     else          newcap = 1.25x
-	//
-	// t1, t2, t3 >= 1024 always.
-	// i.e. if unit size >= 16, then always do 2x or 1.25x (ie t1, t2, t3 are all same)
-	//
-	// With this, appending for bytes increase by:
-	//    100% up to 4K
-	//     75% up to 8K
-	//     50% up to 16K
-	//     25% beyond that
-
-	// unit can be 0 e.g. for struct{}{}; handle that appropriately
-	var t1, t2, t3 int // thresholds
-	if unit <= 1 {
-		t1, t2, t3 = 4*1024, 8*1024, 16*1024
-	} else if unit < 16 {
-		t3 = 16 / unit * 1024
-		t1 = t3 * 1 / 4
-		t2 = t3 * 2 / 4
-	} else {
-		t1, t2, t3 = 1024, 1024, 1024
-	}
-
-	var x int // temporary variable
-
-	// x is multiplier here: one of 5, 6, 7 or 8; incr of 25%, 50%, 75% or 100% respectively
-	if oldCap <= t1 { // [0,t1]
-		x = 8
-	} else if oldCap > t3 { // (t3,infinity]
-		x = 5
-	} else if oldCap <= t2 { // (t1,t2]
-		x = 7
-	} else { // (t2,t3]
-		x = 6
-	}
-	newCap = x * oldCap / 4
-
-	if num > 0 {
-		newCap += num
-	}
-
-	// ensure newCap is a multiple of 64 (if it is > 64) or 16.
-	if newCap > 64 {
-		if x = newCap % 64; x != 0 {
-			x = newCap / 64
-			newCap = 64 * (x + 1)
-		}
-	} else {
-		if x = newCap % 16; x != 0 {
-			x = newCap / 16
-			newCap = 16 * (x + 1)
-		}
-	}
-	return
-}
diff --git a/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go b/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
deleted file mode 100644
index fd52690..0000000
--- a/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
+++ /dev/null
@@ -1,272 +0,0 @@
-// +build !go1.7 safe appengine
-
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"reflect"
-	"sync/atomic"
-	"time"
-)
-
-const safeMode = true
-
-// stringView returns a view of the []byte as a string.
-// In unsafe mode, it doesn't incur allocation and copying caused by conversion.
-// In regular safe mode, it is an allocation and copy.
-//
-// Usage: Always maintain a reference to v while result of this call is in use,
-//        and call keepAlive4BytesView(v) at point where done with view.
-func stringView(v []byte) string {
-	return string(v)
-}
-
-// bytesView returns a view of the string as a []byte.
-// In unsafe mode, it doesn't incur allocation and copying caused by conversion.
-// In regular safe mode, it is an allocation and copy.
-//
-// Usage: Always maintain a reference to v while result of this call is in use,
-//        and call keepAlive4BytesView(v) at point where done with view.
-func bytesView(v string) []byte {
-	return []byte(v)
-}
-
-func definitelyNil(v interface{}) bool {
-	// this is a best-effort option.
-	// We just return false, so we don't unnecessarily incur the cost of reflection this early.
-	return false
-}
-
-func rv2i(rv reflect.Value) interface{} {
-	return rv.Interface()
-}
-
-func rt2id(rt reflect.Type) uintptr {
-	return reflect.ValueOf(rt).Pointer()
-}
-
-func rv2rtid(rv reflect.Value) uintptr {
-	return reflect.ValueOf(rv.Type()).Pointer()
-}
-
-func i2rtid(i interface{}) uintptr {
-	return reflect.ValueOf(reflect.TypeOf(i)).Pointer()
-}
-
-// --------------------------
-
-func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
-	switch v.Kind() {
-	case reflect.Invalid:
-		return true
-	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
-		return v.Len() == 0
-	case reflect.Bool:
-		return !v.Bool()
-	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 v.Float() == 0
-	case reflect.Interface, reflect.Ptr:
-		if deref {
-			if v.IsNil() {
-				return true
-			}
-			return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
-		}
-		return v.IsNil()
-	case reflect.Struct:
-		return isEmptyStruct(v, tinfos, deref, checkStruct)
-	}
-	return false
-}
-
-// --------------------------
-// type ptrToRvMap struct{}
-
-// func (*ptrToRvMap) init() {}
-// func (*ptrToRvMap) get(i interface{}) reflect.Value {
-// 	return reflect.ValueOf(i).Elem()
-// }
-
-// --------------------------
-type atomicTypeInfoSlice struct { // expected to be 2 words
-	v atomic.Value
-}
-
-func (x *atomicTypeInfoSlice) load() []rtid2ti {
-	i := x.v.Load()
-	if i == nil {
-		return nil
-	}
-	return i.([]rtid2ti)
-}
-
-func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
-	x.v.Store(p)
-}
-
-// --------------------------
-func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
-	rv.SetBytes(d.rawBytes())
-}
-
-func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
-	rv.SetString(d.d.DecodeString())
-}
-
-func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
-	rv.SetBool(d.d.DecodeBool())
-}
-
-func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
-	rv.Set(reflect.ValueOf(d.d.DecodeTime()))
-}
-
-func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
-	fv := d.d.DecodeFloat64()
-	if chkOvf.Float32(fv) {
-		d.errorf("float32 overflow: %v", fv)
-	}
-	rv.SetFloat(fv)
-}
-
-func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
-	rv.SetFloat(d.d.DecodeFloat64())
-}
-
-func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
-	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
-}
-
-func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
-	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 8))
-}
-
-func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
-	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 16))
-}
-
-func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
-	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 32))
-}
-
-func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
-	rv.SetInt(d.d.DecodeInt64())
-}
-
-func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
-}
-
-func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
-}
-
-func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 8))
-}
-
-func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 16))
-}
-
-func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 32))
-}
-
-func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
-	rv.SetUint(d.d.DecodeUint64())
-}
-
-// ----------------
-
-func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeBool(rv.Bool())
-}
-
-func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeTime(rv2i(rv).(time.Time))
-}
-
-func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeString(cUTF8, rv.String())
-}
-
-func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeFloat64(rv.Float())
-}
-
-func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeFloat32(float32(rv.Float()))
-}
-
-func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeInt(rv.Int())
-}
-
-func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeInt(rv.Int())
-}
-
-func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeInt(rv.Int())
-}
-
-func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeInt(rv.Int())
-}
-
-func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeInt(rv.Int())
-}
-
-func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
-	e.e.EncodeUint(rv.Uint())
-}
-
-// // keepAlive4BytesView maintains a reference to the input parameter for bytesView.
-// //
-// // Usage: call this at point where done with the bytes view.
-// func keepAlive4BytesView(v string) {}
-
-// // keepAlive4BytesView maintains a reference to the input parameter for stringView.
-// //
-// // Usage: call this at point where done with the string view.
-// func keepAlive4StringView(v []byte) {}
-
-// func definitelyNil(v interface{}) bool {
-// 	rv := reflect.ValueOf(v)
-// 	switch rv.Kind() {
-// 	case reflect.Invalid:
-// 		return true
-// 	case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map, reflect.Func:
-// 		return rv.IsNil()
-// 	default:
-// 		return false
-// 	}
-// }
diff --git a/vendor/github.com/ugorji/go/codec/helper_unsafe.go b/vendor/github.com/ugorji/go/codec/helper_unsafe.go
deleted file mode 100644
index e3df60a..0000000
--- a/vendor/github.com/ugorji/go/codec/helper_unsafe.go
+++ /dev/null
@@ -1,639 +0,0 @@
-// +build !safe
-// +build !appengine
-// +build go1.7
-
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"reflect"
-	"sync/atomic"
-	"time"
-	"unsafe"
-)
-
-// This file has unsafe variants of some helper methods.
-// NOTE: See helper_not_unsafe.go for the usage information.
-
-// var zeroRTv [4]uintptr
-
-const safeMode = false
-const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
-
-type unsafeString struct {
-	Data unsafe.Pointer
-	Len  int
-}
-
-type unsafeSlice struct {
-	Data unsafe.Pointer
-	Len  int
-	Cap  int
-}
-
-type unsafeIntf struct {
-	typ  unsafe.Pointer
-	word unsafe.Pointer
-}
-
-type unsafeReflectValue struct {
-	typ  unsafe.Pointer
-	ptr  unsafe.Pointer
-	flag uintptr
-}
-
-func stringView(v []byte) string {
-	if len(v) == 0 {
-		return ""
-	}
-	bx := (*unsafeSlice)(unsafe.Pointer(&v))
-	return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
-}
-
-func bytesView(v string) []byte {
-	if len(v) == 0 {
-		return zeroByteSlice
-	}
-	sx := (*unsafeString)(unsafe.Pointer(&v))
-	return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
-}
-
-func definitelyNil(v interface{}) bool {
-	// There is no global way of checking if an interface is nil.
-	// For true references (map, ptr, func, chan), you can just look
-	// at the word of the interface. However, for slices, you have to dereference
-	// the word, and get a pointer to the 3-word interface value.
-	//
-	// However, the following are cheap calls
-	// - TypeOf(interface): cheap 2-line call.
-	// - ValueOf(interface{}): expensive
-	// - type.Kind: cheap call through an interface
-	// - Value.Type(): cheap call
-	//                 except it's a method value (e.g. r.Read, which implies that it is a Func)
-
-	return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
-}
-
-func rv2i(rv reflect.Value) interface{} {
-	// TODO: consider a more generally-known optimization for reflect.Value ==> Interface
-	//
-	// Currently, we use this fragile method that taps into implememtation details from
-	// the source go stdlib reflect/value.go, and trims the implementation.
-
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	// true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
-	var ptr unsafe.Pointer
-	if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
-		ptr = *(*unsafe.Pointer)(urv.ptr)
-	} else {
-		ptr = urv.ptr
-	}
-	return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
-}
-
-func rt2id(rt reflect.Type) uintptr {
-	return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
-}
-
-func rv2rtid(rv reflect.Value) uintptr {
-	return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
-}
-
-func i2rtid(i interface{}) uintptr {
-	return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
-}
-
-// --------------------------
-
-func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
-	if urv.flag == 0 {
-		return true
-	}
-	switch v.Kind() {
-	case reflect.Invalid:
-		return true
-	case reflect.String:
-		return (*unsafeString)(urv.ptr).Len == 0
-	case reflect.Slice:
-		return (*unsafeSlice)(urv.ptr).Len == 0
-	case reflect.Bool:
-		return !*(*bool)(urv.ptr)
-	case reflect.Int:
-		return *(*int)(urv.ptr) == 0
-	case reflect.Int8:
-		return *(*int8)(urv.ptr) == 0
-	case reflect.Int16:
-		return *(*int16)(urv.ptr) == 0
-	case reflect.Int32:
-		return *(*int32)(urv.ptr) == 0
-	case reflect.Int64:
-		return *(*int64)(urv.ptr) == 0
-	case reflect.Uint:
-		return *(*uint)(urv.ptr) == 0
-	case reflect.Uint8:
-		return *(*uint8)(urv.ptr) == 0
-	case reflect.Uint16:
-		return *(*uint16)(urv.ptr) == 0
-	case reflect.Uint32:
-		return *(*uint32)(urv.ptr) == 0
-	case reflect.Uint64:
-		return *(*uint64)(urv.ptr) == 0
-	case reflect.Uintptr:
-		return *(*uintptr)(urv.ptr) == 0
-	case reflect.Float32:
-		return *(*float32)(urv.ptr) == 0
-	case reflect.Float64:
-		return *(*float64)(urv.ptr) == 0
-	case reflect.Interface:
-		isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
-		if deref {
-			if isnil {
-				return true
-			}
-			return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
-		}
-		return isnil
-	case reflect.Ptr:
-		// isnil := urv.ptr == nil (not sufficient, as a pointer value encodes the type)
-		isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
-		if deref {
-			if isnil {
-				return true
-			}
-			return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
-		}
-		return isnil
-	case reflect.Struct:
-		return isEmptyStruct(v, tinfos, deref, checkStruct)
-	case reflect.Map, reflect.Array, reflect.Chan:
-		return v.Len() == 0
-	}
-	return false
-}
-
-// --------------------------
-
-// atomicTypeInfoSlice contains length and pointer to the array for a slice.
-// It is expected to be 2 words.
-//
-// Previously, we atomically loaded and stored the length and array pointer separately,
-// which could lead to some races.
-// We now just atomically store and load the pointer to the value directly.
-
-type atomicTypeInfoSlice struct { // expected to be 2 words
-	l int            // length of the data array (must be first in struct, for 64-bit alignment necessary for 386)
-	v unsafe.Pointer // data array - Pointer (not uintptr) to maintain GC reference
-}
-
-func (x *atomicTypeInfoSlice) load() []rtid2ti {
-	xp := unsafe.Pointer(x)
-	x2 := *(*atomicTypeInfoSlice)(atomic.LoadPointer(&xp))
-	if x2.l == 0 {
-		return nil
-	}
-	return *(*[]rtid2ti)(unsafe.Pointer(&unsafeSlice{Data: x2.v, Len: x2.l, Cap: x2.l}))
-}
-
-func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
-	s := (*unsafeSlice)(unsafe.Pointer(&p))
-	xp := unsafe.Pointer(x)
-	atomic.StorePointer(&xp, unsafe.Pointer(&atomicTypeInfoSlice{l: s.Len, v: s.Data}))
-}
-
-// --------------------------
-func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*[]byte)(urv.ptr) = d.rawBytes()
-}
-
-func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*string)(urv.ptr) = d.d.DecodeString()
-}
-
-func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*bool)(urv.ptr) = d.d.DecodeBool()
-}
-
-func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*time.Time)(urv.ptr) = d.d.DecodeTime()
-}
-
-func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
-	fv := d.d.DecodeFloat64()
-	if chkOvf.Float32(fv) {
-		d.errorf("float32 overflow: %v", fv)
-	}
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*float32)(urv.ptr) = float32(fv)
-}
-
-func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*float64)(urv.ptr) = d.d.DecodeFloat64()
-}
-
-func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*int)(urv.ptr) = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
-}
-
-func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*int8)(urv.ptr) = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
-}
-
-func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*int16)(urv.ptr) = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
-}
-
-func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*int32)(urv.ptr) = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
-}
-
-func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*int64)(urv.ptr) = d.d.DecodeInt64()
-}
-
-func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uint)(urv.ptr) = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
-}
-
-func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uintptr)(urv.ptr) = uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
-}
-
-func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uint8)(urv.ptr) = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
-}
-
-func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uint16)(urv.ptr) = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
-}
-
-func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uint32)(urv.ptr) = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
-}
-
-func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
-	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	*(*uint64)(urv.ptr) = d.d.DecodeUint64()
-}
-
-// ------------
-
-func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeBool(*(*bool)(v.ptr))
-}
-
-func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeTime(*(*time.Time)(v.ptr))
-}
-
-func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeString(cUTF8, *(*string)(v.ptr))
-}
-
-func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeFloat64(*(*float64)(v.ptr))
-}
-
-func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeFloat32(*(*float32)(v.ptr))
-}
-
-func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeInt(int64(*(*int)(v.ptr)))
-}
-
-func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeInt(int64(*(*int8)(v.ptr)))
-}
-
-func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeInt(int64(*(*int16)(v.ptr)))
-}
-
-func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeInt(int64(*(*int32)(v.ptr)))
-}
-
-func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeInt(int64(*(*int64)(v.ptr)))
-}
-
-func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uint)(v.ptr)))
-}
-
-func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uint8)(v.ptr)))
-}
-
-func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uint16)(v.ptr)))
-}
-
-func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uint32)(v.ptr)))
-}
-
-func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uint64)(v.ptr)))
-}
-
-func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
-	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-	e.e.EncodeUint(uint64(*(*uintptr)(v.ptr)))
-}
-
-// ------------
-
-// func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
-// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-// 	// if urv.flag&unsafeFlagIndir != 0 {
-// 	// 	urv.ptr = *(*unsafe.Pointer)(urv.ptr)
-// 	// }
-// 	*(*[]byte)(urv.ptr) = d.rawBytes()
-// }
-
-// func rv0t(rt reflect.Type) reflect.Value {
-// 	ut := (*unsafeIntf)(unsafe.Pointer(&rt))
-// 	// we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
-// 	uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
-// 	return *(*reflect.Value)(unsafe.Pointer(&uv})
-// }
-
-// func rv2i(rv reflect.Value) interface{} {
-// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-// 	// true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
-// 	var ptr unsafe.Pointer
-// 	// kk := reflect.Kind(urv.flag & (1<<5 - 1))
-// 	// if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
-// 	if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
-// 		ptr = *(*unsafe.Pointer)(urv.ptr)
-// 	} else {
-// 		ptr = urv.ptr
-// 	}
-// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
-// 	// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
-// 	// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// }
-
-// func definitelyNil(v interface{}) bool {
-// 	var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
-// 	if ui.word == nil {
-// 		return true
-// 	}
-// 	var tk = reflect.TypeOf(v).Kind()
-// 	return (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
-// 	fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n",
-// 	v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
-// }
-
-// func keepAlive4BytesView(v string) {
-// 	runtime.KeepAlive(v)
-// }
-
-// func keepAlive4StringView(v []byte) {
-// 	runtime.KeepAlive(v)
-// }
-
-// func rt2id(rt reflect.Type) uintptr {
-// 	return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
-// 	// var i interface{} = rt
-// 	// // ui := (*unsafeIntf)(unsafe.Pointer(&i))
-// 	// return ((*unsafeIntf)(unsafe.Pointer(&i))).word
-// }
-
-// func rv2i(rv reflect.Value) interface{} {
-// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-// 	// non-reference type: already indir
-// 	// reference type: depend on flagIndir property ('cos maybe was double-referenced)
-// 	// const (unsafeRvFlagKindMask    = 1<<5 - 1 , unsafeRvFlagIndir       = 1 << 7 )
-// 	// rvk := reflect.Kind(urv.flag & (1<<5 - 1))
-// 	// if (rvk == reflect.Chan ||
-// 	// 	rvk == reflect.Func ||
-// 	// 	rvk == reflect.Interface ||
-// 	// 	rvk == reflect.Map ||
-// 	// 	rvk == reflect.Ptr ||
-// 	// 	rvk == reflect.UnsafePointer) && urv.flag&(1<<8) != 0 {
-// 	// 	fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
-// 	// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
-// 	// }
-// 	if urv.flag&(1<<5-1) == uintptr(reflect.Map) && urv.flag&(1<<7) != 0 {
-// 		// fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
-// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
-// 	}
-// 	// fmt.Printf(">>>>> ++++ direct reference: %v, %v\n", rvk, rv.Type())
-// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// }
-
-// const (
-// 	unsafeRvFlagKindMask    = 1<<5 - 1
-// 	unsafeRvKindDirectIface = 1 << 5
-// 	unsafeRvFlagIndir       = 1 << 7
-// 	unsafeRvFlagAddr        = 1 << 8
-// 	unsafeRvFlagMethod      = 1 << 9
-
-// 	_USE_RV_INTERFACE bool = false
-// 	_UNSAFE_RV_DEBUG       = true
-// )
-
-// type unsafeRtype struct {
-// 	_    [2]uintptr
-// 	_    uint32
-// 	_    uint8
-// 	_    uint8
-// 	_    uint8
-// 	kind uint8
-// 	_    [2]uintptr
-// 	_    int32
-// }
-
-// func _rv2i(rv reflect.Value) interface{} {
-// 	// Note: From use,
-// 	//   - it's never an interface
-// 	//   - the only calls here are for ifaceIndir types.
-// 	//     (though that conditional is wrong)
-// 	//     To know for sure, we need the value of t.kind (which is not exposed).
-// 	//
-// 	// Need to validate the path: type is indirect ==> only value is indirect ==> default (value is direct)
-// 	//    - Type indirect, Value indirect: ==> numbers, boolean, slice, struct, array, string
-// 	//    - Type Direct,   Value indirect: ==> map???
-// 	//    - Type Direct,   Value direct:   ==> pointers, unsafe.Pointer, func, chan, map
-// 	//
-// 	// TRANSLATES TO:
-// 	//    if typeIndirect { } else if valueIndirect { } else { }
-// 	//
-// 	// Since we don't deal with funcs, then "flagNethod" is unset, and can be ignored.
-
-// 	if _USE_RV_INTERFACE {
-// 		return rv.Interface()
-// 	}
-// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-
-// 	// if urv.flag&unsafeRvFlagMethod != 0 || urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
-// 	// 	println("***** IS flag method or interface: delegating to rv.Interface()")
-// 	// 	return rv.Interface()
-// 	// }
-
-// 	// if urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
-// 	// 	println("***** IS Interface: delegate to rv.Interface")
-// 	// 	return rv.Interface()
-// 	// }
-// 	// if urv.flag&unsafeRvFlagKindMask&unsafeRvKindDirectIface == 0 {
-// 	// 	if urv.flag&unsafeRvFlagAddr == 0 {
-// 	// 		println("***** IS ifaceIndir typ")
-// 	// 		// ui := unsafeIntf{word: urv.ptr, typ: urv.typ}
-// 	// 		// return *(*interface{})(unsafe.Pointer(&ui))
-// 	// 		// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// 	// 	}
-// 	// } else if urv.flag&unsafeRvFlagIndir != 0 {
-// 	// 	println("***** IS flagindir")
-// 	// 	// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
-// 	// } else {
-// 	// 	println("***** NOT flagindir")
-// 	// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// 	// }
-// 	// println("***** default: delegate to rv.Interface")
-
-// 	urt := (*unsafeRtype)(unsafe.Pointer(urv.typ))
-// 	if _UNSAFE_RV_DEBUG {
-// 		fmt.Printf(">>>> start: %v: ", rv.Type())
-// 		fmt.Printf("%v - %v\n", *urv, *urt)
-// 	}
-// 	if urt.kind&unsafeRvKindDirectIface == 0 {
-// 		if _UNSAFE_RV_DEBUG {
-// 			fmt.Printf("**** +ifaceIndir type: %v\n", rv.Type())
-// 		}
-// 		// println("***** IS ifaceIndir typ")
-// 		// if true || urv.flag&unsafeRvFlagAddr == 0 {
-// 		// 	// println("    ***** IS NOT addr")
-// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// 		// }
-// 	} else if urv.flag&unsafeRvFlagIndir != 0 {
-// 		if _UNSAFE_RV_DEBUG {
-// 			fmt.Printf("**** +flagIndir type: %v\n", rv.Type())
-// 		}
-// 		// println("***** IS flagindir")
-// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
-// 	} else {
-// 		if _UNSAFE_RV_DEBUG {
-// 			fmt.Printf("**** -flagIndir type: %v\n", rv.Type())
-// 		}
-// 		// println("***** NOT flagindir")
-// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
-// 	}
-// 	// println("***** default: delegating to rv.Interface()")
-// 	// return rv.Interface()
-// }
-
-// var staticM0 = make(map[string]uint64)
-// var staticI0 = (int32)(-5)
-
-// func staticRv2iTest() {
-// 	i0 := (int32)(-5)
-// 	m0 := make(map[string]uint16)
-// 	m0["1"] = 1
-// 	for _, i := range []interface{}{
-// 		(int)(7),
-// 		(uint)(8),
-// 		(int16)(-9),
-// 		(uint16)(19),
-// 		(uintptr)(77),
-// 		(bool)(true),
-// 		float32(-32.7),
-// 		float64(64.9),
-// 		complex(float32(19), 5),
-// 		complex(float64(-32), 7),
-// 		[4]uint64{1, 2, 3, 4},
-// 		(chan<- int)(nil), // chan,
-// 		rv2i,              // func
-// 		io.Writer(ioutil.Discard),
-// 		make(map[string]uint),
-// 		(map[string]uint)(nil),
-// 		staticM0,
-// 		m0,
-// 		&m0,
-// 		i0,
-// 		&i0,
-// 		&staticI0,
-// 		&staticM0,
-// 		[]uint32{6, 7, 8},
-// 		"abc",
-// 		Raw{},
-// 		RawExt{},
-// 		&Raw{},
-// 		&RawExt{},
-// 		unsafe.Pointer(&i0),
-// 	} {
-// 		i2 := rv2i(reflect.ValueOf(i))
-// 		eq := reflect.DeepEqual(i, i2)
-// 		fmt.Printf(">>>> %v == %v? %v\n", i, i2, eq)
-// 	}
-// 	// os.Exit(0)
-// }
-
-// func init() {
-// 	staticRv2iTest()
-// }
-
-// func rv2i(rv reflect.Value) interface{} {
-// 	if _USE_RV_INTERFACE || rv.Kind() == reflect.Interface || rv.CanAddr() {
-// 		return rv.Interface()
-// 	}
-// 	// var i interface{}
-// 	// ui := (*unsafeIntf)(unsafe.Pointer(&i))
-// 	var ui unsafeIntf
-// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
-// 	// fmt.Printf("urv: flag: %b, typ: %b, ptr: %b\n", urv.flag, uintptr(urv.typ), uintptr(urv.ptr))
-// 	if (urv.flag&unsafeRvFlagKindMask)&unsafeRvKindDirectIface == 0 {
-// 		if urv.flag&unsafeRvFlagAddr != 0 {
-// 			println("***** indirect and addressable! Needs typed move - delegate to rv.Interface()")
-// 			return rv.Interface()
-// 		}
-// 		println("****** indirect type/kind")
-// 		ui.word = urv.ptr
-// 	} else if urv.flag&unsafeRvFlagIndir != 0 {
-// 		println("****** unsafe rv flag indir")
-// 		ui.word = *(*unsafe.Pointer)(urv.ptr)
-// 	} else {
-// 		println("****** default: assign prt to word directly")
-// 		ui.word = urv.ptr
-// 	}
-// 	// ui.word = urv.ptr
-// 	ui.typ = urv.typ
-// 	// fmt.Printf("(pointers) ui.typ: %p, word: %p\n", ui.typ, ui.word)
-// 	// fmt.Printf("(binary)   ui.typ: %b, word: %b\n", uintptr(ui.typ), uintptr(ui.word))
-// 	return *(*interface{})(unsafe.Pointer(&ui))
-// 	// return i
-// }
diff --git a/vendor/github.com/ugorji/go/codec/json.go b/vendor/github.com/ugorji/go/codec/json.go
deleted file mode 100644
index bdd1996..0000000
--- a/vendor/github.com/ugorji/go/codec/json.go
+++ /dev/null
@@ -1,1423 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-// By default, this json support uses base64 encoding for bytes, because you cannot
-// store and read any arbitrary string in json (only unicode).
-// However, the user can configre how to encode/decode bytes.
-//
-// This library specifically supports UTF-8 for encoding and decoding only.
-//
-// Note that the library will happily encode/decode things which are not valid
-// json e.g. a map[int64]string. We do it for consistency. With valid json,
-// we will encode and decode appropriately.
-// Users can specify their map type if necessary to force it.
-//
-// Note:
-//   - we cannot use strconv.Quote and strconv.Unquote because json quotes/unquotes differently.
-//     We implement it here.
-
-// Top-level methods of json(End|Dec)Driver (which are implementations of (en|de)cDriver
-// MUST not call one-another.
-
-import (
-	"bytes"
-	"encoding/base64"
-	"math"
-	"reflect"
-	"strconv"
-	"time"
-	"unicode"
-	"unicode/utf16"
-	"unicode/utf8"
-)
-
-//--------------------------------
-
-var jsonLiterals = [...]byte{
-	'"', 't', 'r', 'u', 'e', '"',
-	'"', 'f', 'a', 'l', 's', 'e', '"',
-	'"', 'n', 'u', 'l', 'l', '"',
-}
-
-const (
-	jsonLitTrueQ  = 0
-	jsonLitTrue   = 1
-	jsonLitFalseQ = 6
-	jsonLitFalse  = 7
-	jsonLitNullQ  = 13
-	jsonLitNull   = 14
-)
-
-const (
-	jsonU4Chk2 = '0'
-	jsonU4Chk1 = 'a' - 10
-	jsonU4Chk0 = 'A' - 10
-
-	jsonScratchArrayLen = 64
-)
-
-const (
-	// If !jsonValidateSymbols, decoding will be faster, by skipping some checks:
-	//   - If we see first character of null, false or true,
-	//     do not validate subsequent characters.
-	//   - e.g. if we see a n, assume null and skip next 3 characters,
-	//     and do not validate they are ull.
-	// P.S. Do not expect a significant decoding boost from this.
-	jsonValidateSymbols = true
-
-	jsonSpacesOrTabsLen = 128
-
-	jsonAlwaysReturnInternString = false
-)
-
-var (
-	// jsonTabs and jsonSpaces are used as caches for indents
-	jsonTabs, jsonSpaces [jsonSpacesOrTabsLen]byte
-
-	jsonCharHtmlSafeSet   bitset128
-	jsonCharSafeSet       bitset128
-	jsonCharWhitespaceSet bitset256
-	jsonNumSet            bitset256
-)
-
-func init() {
-	for i := 0; i < jsonSpacesOrTabsLen; i++ {
-		jsonSpaces[i] = ' '
-		jsonTabs[i] = '\t'
-	}
-
-	// populate the safe values as true: note: ASCII control characters are (0-31)
-	// jsonCharSafeSet:     all true except (0-31) " \
-	// jsonCharHtmlSafeSet: all true except (0-31) " \ < > &
-	var i byte
-	for i = 32; i < utf8.RuneSelf; i++ {
-		switch i {
-		case '"', '\\':
-		case '<', '>', '&':
-			jsonCharSafeSet.set(i) // = true
-		default:
-			jsonCharSafeSet.set(i)
-			jsonCharHtmlSafeSet.set(i)
-		}
-	}
-	for i = 0; i <= utf8.RuneSelf; i++ {
-		switch i {
-		case ' ', '\t', '\r', '\n':
-			jsonCharWhitespaceSet.set(i)
-		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-':
-			jsonNumSet.set(i)
-		}
-	}
-}
-
-// ----------------
-
-type jsonEncDriverTypical struct {
-	w encWriter
-	// w  *encWriterSwitch
-	b  *[jsonScratchArrayLen]byte
-	tw bool // term white space
-	c  containerState
-}
-
-func (e *jsonEncDriverTypical) typical() {}
-
-func (e *jsonEncDriverTypical) reset(ee *jsonEncDriver) {
-	e.w = ee.ew
-	// e.w = &ee.e.encWriterSwitch
-	e.b = &ee.b
-	e.tw = ee.h.TermWhitespace
-	e.c = 0
-}
-
-func (e *jsonEncDriverTypical) WriteArrayStart(length int) {
-	e.w.writen1('[')
-	e.c = containerArrayStart
-}
-
-func (e *jsonEncDriverTypical) WriteArrayElem() {
-	if e.c != containerArrayStart {
-		e.w.writen1(',')
-	}
-	e.c = containerArrayElem
-}
-
-func (e *jsonEncDriverTypical) WriteArrayEnd() {
-	e.w.writen1(']')
-	e.c = containerArrayEnd
-}
-
-func (e *jsonEncDriverTypical) WriteMapStart(length int) {
-	e.w.writen1('{')
-	e.c = containerMapStart
-}
-
-func (e *jsonEncDriverTypical) WriteMapElemKey() {
-	if e.c != containerMapStart {
-		e.w.writen1(',')
-	}
-	e.c = containerMapKey
-}
-
-func (e *jsonEncDriverTypical) WriteMapElemValue() {
-	e.w.writen1(':')
-	e.c = containerMapValue
-}
-
-func (e *jsonEncDriverTypical) WriteMapEnd() {
-	e.w.writen1('}')
-	e.c = containerMapEnd
-}
-
-func (e *jsonEncDriverTypical) EncodeBool(b bool) {
-	if b {
-		e.w.writeb(jsonLiterals[jsonLitTrue : jsonLitTrue+4])
-	} else {
-		e.w.writeb(jsonLiterals[jsonLitFalse : jsonLitFalse+5])
-	}
-}
-
-func (e *jsonEncDriverTypical) EncodeFloat64(f float64) {
-	fmt, prec := jsonFloatStrconvFmtPrec(f)
-	e.w.writeb(strconv.AppendFloat(e.b[:0], f, fmt, prec, 64))
-}
-
-func (e *jsonEncDriverTypical) EncodeInt(v int64) {
-	e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
-}
-
-func (e *jsonEncDriverTypical) EncodeUint(v uint64) {
-	e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
-}
-
-func (e *jsonEncDriverTypical) EncodeFloat32(f float32) {
-	e.EncodeFloat64(float64(f))
-}
-
-func (e *jsonEncDriverTypical) atEndOfEncode() {
-	if e.tw {
-		e.w.writen1(' ')
-	}
-}
-
-// ----------------
-
-type jsonEncDriverGeneric struct {
-	w encWriter // encWriter // *encWriterSwitch
-	b *[jsonScratchArrayLen]byte
-	c containerState
-	// ds string // indent string
-	di int8    // indent per
-	d  bool    // indenting?
-	dt bool    // indent using tabs
-	dl uint16  // indent level
-	ks bool    // map key as string
-	is byte    // integer as string
-	tw bool    // term white space
-	_  [7]byte // padding
-}
-
-// indent is done as below:
-//   - newline and indent are added before each mapKey or arrayElem
-//   - newline and indent are added before each ending,
-//     except there was no entry (so we can have {} or [])
-
-func (e *jsonEncDriverGeneric) reset(ee *jsonEncDriver) {
-	e.w = ee.ew
-	e.b = &ee.b
-	e.tw = ee.h.TermWhitespace
-	e.c = 0
-	e.d, e.dt, e.dl, e.di = false, false, 0, 0
-	h := ee.h
-	if h.Indent > 0 {
-		e.d = true
-		e.di = int8(h.Indent)
-	} else if h.Indent < 0 {
-		e.d = true
-		e.dt = true
-		e.di = int8(-h.Indent)
-	}
-	e.ks = h.MapKeyAsString
-	e.is = h.IntegerAsString
-}
-
-func (e *jsonEncDriverGeneric) WriteArrayStart(length int) {
-	if e.d {
-		e.dl++
-	}
-	e.w.writen1('[')
-	e.c = containerArrayStart
-}
-
-func (e *jsonEncDriverGeneric) WriteArrayElem() {
-	if e.c != containerArrayStart {
-		e.w.writen1(',')
-	}
-	if e.d {
-		e.writeIndent()
-	}
-	e.c = containerArrayElem
-}
-
-func (e *jsonEncDriverGeneric) WriteArrayEnd() {
-	if e.d {
-		e.dl--
-		if e.c != containerArrayStart {
-			e.writeIndent()
-		}
-	}
-	e.w.writen1(']')
-	e.c = containerArrayEnd
-}
-
-func (e *jsonEncDriverGeneric) WriteMapStart(length int) {
-	if e.d {
-		e.dl++
-	}
-	e.w.writen1('{')
-	e.c = containerMapStart
-}
-
-func (e *jsonEncDriverGeneric) WriteMapElemKey() {
-	if e.c != containerMapStart {
-		e.w.writen1(',')
-	}
-	if e.d {
-		e.writeIndent()
-	}
-	e.c = containerMapKey
-}
-
-func (e *jsonEncDriverGeneric) WriteMapElemValue() {
-	if e.d {
-		e.w.writen2(':', ' ')
-	} else {
-		e.w.writen1(':')
-	}
-	e.c = containerMapValue
-}
-
-func (e *jsonEncDriverGeneric) WriteMapEnd() {
-	if e.d {
-		e.dl--
-		if e.c != containerMapStart {
-			e.writeIndent()
-		}
-	}
-	e.w.writen1('}')
-	e.c = containerMapEnd
-}
-
-func (e *jsonEncDriverGeneric) writeIndent() {
-	e.w.writen1('\n')
-	x := int(e.di) * int(e.dl)
-	if e.dt {
-		for x > jsonSpacesOrTabsLen {
-			e.w.writeb(jsonTabs[:])
-			x -= jsonSpacesOrTabsLen
-		}
-		e.w.writeb(jsonTabs[:x])
-	} else {
-		for x > jsonSpacesOrTabsLen {
-			e.w.writeb(jsonSpaces[:])
-			x -= jsonSpacesOrTabsLen
-		}
-		e.w.writeb(jsonSpaces[:x])
-	}
-}
-
-func (e *jsonEncDriverGeneric) EncodeBool(b bool) {
-	if e.ks && e.c == containerMapKey {
-		if b {
-			e.w.writeb(jsonLiterals[jsonLitTrueQ : jsonLitTrueQ+6])
-		} else {
-			e.w.writeb(jsonLiterals[jsonLitFalseQ : jsonLitFalseQ+7])
-		}
-	} else {
-		if b {
-			e.w.writeb(jsonLiterals[jsonLitTrue : jsonLitTrue+4])
-		} else {
-			e.w.writeb(jsonLiterals[jsonLitFalse : jsonLitFalse+5])
-		}
-	}
-}
-
-func (e *jsonEncDriverGeneric) EncodeFloat64(f float64) {
-	// instead of using 'g', specify whether to use 'e' or 'f'
-	fmt, prec := jsonFloatStrconvFmtPrec(f)
-
-	var blen int
-	if e.ks && e.c == containerMapKey {
-		blen = 2 + len(strconv.AppendFloat(e.b[1:1], f, fmt, prec, 64))
-		e.b[0] = '"'
-		e.b[blen-1] = '"'
-	} else {
-		blen = len(strconv.AppendFloat(e.b[:0], f, fmt, prec, 64))
-	}
-	e.w.writeb(e.b[:blen])
-}
-
-func (e *jsonEncDriverGeneric) EncodeInt(v int64) {
-	x := e.is
-	if x == 'A' || x == 'L' && (v > 1<<53 || v < -(1<<53)) || (e.ks && e.c == containerMapKey) {
-		blen := 2 + len(strconv.AppendInt(e.b[1:1], v, 10))
-		e.b[0] = '"'
-		e.b[blen-1] = '"'
-		e.w.writeb(e.b[:blen])
-		return
-	}
-	e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
-}
-
-func (e *jsonEncDriverGeneric) EncodeUint(v uint64) {
-	x := e.is
-	if x == 'A' || x == 'L' && v > 1<<53 || (e.ks && e.c == containerMapKey) {
-		blen := 2 + len(strconv.AppendUint(e.b[1:1], v, 10))
-		e.b[0] = '"'
-		e.b[blen-1] = '"'
-		e.w.writeb(e.b[:blen])
-		return
-	}
-	e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
-}
-
-func (e *jsonEncDriverGeneric) EncodeFloat32(f float32) {
-	// e.encodeFloat(float64(f), 32)
-	// always encode all floats as IEEE 64-bit floating point.
-	// It also ensures that we can decode in full precision even if into a float32,
-	// as what is written is always to float64 precision.
-	e.EncodeFloat64(float64(f))
-}
-
-func (e *jsonEncDriverGeneric) atEndOfEncode() {
-	if e.tw {
-		if e.d {
-			e.w.writen1('\n')
-		} else {
-			e.w.writen1(' ')
-		}
-	}
-}
-
-// --------------------
-
-type jsonEncDriver struct {
-	noBuiltInTypes
-	e  *Encoder
-	h  *JsonHandle
-	ew encWriter // encWriter // *encWriterSwitch
-	se extWrapper
-	// ---- cpu cache line boundary?
-	bs []byte // scratch
-	// ---- cpu cache line boundary?
-	b [jsonScratchArrayLen]byte // scratch (encode time,
-}
-
-func (e *jsonEncDriver) EncodeNil() {
-	// We always encode nil as just null (never in quotes)
-	// This allows us to easily decode if a nil in the json stream
-	// ie if initial token is n.
-	e.ew.writeb(jsonLiterals[jsonLitNull : jsonLitNull+4])
-
-	// if e.h.MapKeyAsString && e.c == containerMapKey {
-	// 	e.ew.writeb(jsonLiterals[jsonLitNullQ : jsonLitNullQ+6])
-	// } else {
-	// 	e.ew.writeb(jsonLiterals[jsonLitNull : jsonLitNull+4])
-	// }
-}
-
-func (e *jsonEncDriver) EncodeTime(t time.Time) {
-	// Do NOT use MarshalJSON, as it allocates internally.
-	// instead, we call AppendFormat directly, using our scratch buffer (e.b)
-	if t.IsZero() {
-		e.EncodeNil()
-	} else {
-		e.b[0] = '"'
-		b := t.AppendFormat(e.b[1:1], time.RFC3339Nano)
-		e.b[len(b)+1] = '"'
-		e.ew.writeb(e.b[:len(b)+2])
-	}
-	// v, err := t.MarshalJSON(); if err != nil { e.e.error(err) } e.ew.writeb(v)
-}
-
-func (e *jsonEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
-	if v := ext.ConvertExt(rv); v == nil {
-		e.EncodeNil()
-	} else {
-		en.encode(v)
-	}
-}
-
-func (e *jsonEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
-	// only encodes re.Value (never re.Data)
-	if re.Value == nil {
-		e.EncodeNil()
-	} else {
-		en.encode(re.Value)
-	}
-}
-
-func (e *jsonEncDriver) EncodeString(c charEncoding, v string) {
-	e.quoteStr(v)
-}
-
-func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
-	// if encoding raw bytes and RawBytesExt is configured, use it to encode
-	if v == nil {
-		e.EncodeNil()
-		return
-	}
-	if c == cRAW {
-		if e.se.InterfaceExt != nil {
-			e.EncodeExt(v, 0, &e.se, e.e)
-			return
-		}
-
-		slen := base64.StdEncoding.EncodedLen(len(v))
-		if cap(e.bs) >= slen+2 {
-			e.bs = e.bs[:slen+2]
-		} else {
-			e.bs = make([]byte, slen+2)
-		}
-		e.bs[0] = '"'
-		base64.StdEncoding.Encode(e.bs[1:], v)
-		e.bs[slen+1] = '"'
-		e.ew.writeb(e.bs)
-	} else {
-		e.quoteStr(stringView(v))
-	}
-}
-
-func (e *jsonEncDriver) EncodeAsis(v []byte) {
-	e.ew.writeb(v)
-}
-
-func (e *jsonEncDriver) quoteStr(s string) {
-	// adapted from std pkg encoding/json
-	const hex = "0123456789abcdef"
-	w := e.ew
-	htmlasis := e.h.HTMLCharsAsIs
-	w.writen1('"')
-	var start int
-	for i, slen := 0, len(s); i < slen; {
-		// encode all bytes < 0x20 (except \r, \n).
-		// also encode < > & to prevent security holes when served to some browsers.
-		if b := s[i]; b < utf8.RuneSelf {
-			// if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
-			// if (htmlasis && jsonCharSafeSet.isset(b)) || jsonCharHtmlSafeSet.isset(b) {
-			if jsonCharHtmlSafeSet.isset(b) || (htmlasis && jsonCharSafeSet.isset(b)) {
-				i++
-				continue
-			}
-			if start < i {
-				w.writestr(s[start:i])
-			}
-			switch b {
-			case '\\', '"':
-				w.writen2('\\', b)
-			case '\n':
-				w.writen2('\\', 'n')
-			case '\r':
-				w.writen2('\\', 'r')
-			case '\b':
-				w.writen2('\\', 'b')
-			case '\f':
-				w.writen2('\\', 'f')
-			case '\t':
-				w.writen2('\\', 't')
-			default:
-				w.writestr(`\u00`)
-				w.writen2(hex[b>>4], hex[b&0xF])
-			}
-			i++
-			start = i
-			continue
-		}
-		c, size := utf8.DecodeRuneInString(s[i:])
-		if c == utf8.RuneError && size == 1 {
-			if start < i {
-				w.writestr(s[start:i])
-			}
-			w.writestr(`\ufffd`)
-			i += size
-			start = i
-			continue
-		}
-		// U+2028 is LINE SEPARATOR. U+2029 is PARAGRAPH SEPARATOR.
-		// Both technically valid JSON, but bomb on JSONP, so fix here unconditionally.
-		if c == '\u2028' || c == '\u2029' {
-			if start < i {
-				w.writestr(s[start:i])
-			}
-			w.writestr(`\u202`)
-			w.writen1(hex[c&0xF])
-			i += size
-			start = i
-			continue
-		}
-		i += size
-	}
-	if start < len(s) {
-		w.writestr(s[start:])
-	}
-	w.writen1('"')
-}
-
-type jsonDecDriver struct {
-	noBuiltInTypes
-	d  *Decoder
-	h  *JsonHandle
-	r  decReader // *decReaderSwitch // decReader
-	se extWrapper
-
-	// ---- writable fields during execution --- *try* to keep in sep cache line
-
-	c containerState
-	// tok is used to store the token read right after skipWhiteSpace.
-	tok   uint8
-	fnull bool    // found null from appendStringAsBytes
-	bs    []byte  // scratch. Initialized from b. Used for parsing strings or numbers.
-	bstr  [8]byte // scratch used for string \UXXX parsing
-	// ---- cpu cache line boundary?
-	b  [jsonScratchArrayLen]byte // scratch 1, used for parsing strings or numbers or time.Time
-	b2 [jsonScratchArrayLen]byte // scratch 2, used only for readUntil, decNumBytes
-
-	_ [3]uint64 // padding
-	// n jsonNum
-}
-
-// func jsonIsWS(b byte) bool {
-// 	// return b == ' ' || b == '\t' || b == '\r' || b == '\n'
-// 	return jsonCharWhitespaceSet.isset(b)
-// }
-
-func (d *jsonDecDriver) uncacheRead() {
-	if d.tok != 0 {
-		d.r.unreadn1()
-		d.tok = 0
-	}
-}
-
-func (d *jsonDecDriver) ReadMapStart() int {
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	const xc uint8 = '{'
-	if d.tok != xc {
-		d.d.errorf("read map - expect char '%c' but got char '%c'", xc, d.tok)
-	}
-	d.tok = 0
-	d.c = containerMapStart
-	return -1
-}
-
-func (d *jsonDecDriver) ReadArrayStart() int {
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	const xc uint8 = '['
-	if d.tok != xc {
-		d.d.errorf("read array - expect char '%c' but got char '%c'", xc, d.tok)
-	}
-	d.tok = 0
-	d.c = containerArrayStart
-	return -1
-}
-
-func (d *jsonDecDriver) CheckBreak() bool {
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	return d.tok == '}' || d.tok == ']'
-}
-
-// For the ReadXXX methods below, we could just delegate to helper functions
-// readContainerState(c containerState, xc uint8, check bool)
-// - ReadArrayElem would become:
-//   readContainerState(containerArrayElem, ',', d.c != containerArrayStart)
-//
-// However, until mid-stack inlining comes in go1.11 which supports inlining of
-// one-liners, we explicitly write them all 5 out to elide the extra func call.
-//
-// TODO: For Go 1.11, if inlined, consider consolidating these.
-
-func (d *jsonDecDriver) ReadArrayElem() {
-	const xc uint8 = ','
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	if d.c != containerArrayStart {
-		if d.tok != xc {
-			d.d.errorf("read array element - expect char '%c' but got char '%c'", xc, d.tok)
-		}
-		d.tok = 0
-	}
-	d.c = containerArrayElem
-}
-
-func (d *jsonDecDriver) ReadArrayEnd() {
-	const xc uint8 = ']'
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	if d.tok != xc {
-		d.d.errorf("read array end - expect char '%c' but got char '%c'", xc, d.tok)
-	}
-	d.tok = 0
-	d.c = containerArrayEnd
-}
-
-func (d *jsonDecDriver) ReadMapElemKey() {
-	const xc uint8 = ','
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	if d.c != containerMapStart {
-		if d.tok != xc {
-			d.d.errorf("read map key - expect char '%c' but got char '%c'", xc, d.tok)
-		}
-		d.tok = 0
-	}
-	d.c = containerMapKey
-}
-
-func (d *jsonDecDriver) ReadMapElemValue() {
-	const xc uint8 = ':'
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	if d.tok != xc {
-		d.d.errorf("read map value - expect char '%c' but got char '%c'", xc, d.tok)
-	}
-	d.tok = 0
-	d.c = containerMapValue
-}
-
-func (d *jsonDecDriver) ReadMapEnd() {
-	const xc uint8 = '}'
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	if d.tok != xc {
-		d.d.errorf("read map end - expect char '%c' but got char '%c'", xc, d.tok)
-	}
-	d.tok = 0
-	d.c = containerMapEnd
-}
-
-func (d *jsonDecDriver) readLit(length, fromIdx uint8) {
-	bs := d.r.readx(int(length))
-	d.tok = 0
-	if jsonValidateSymbols && !bytes.Equal(bs, jsonLiterals[fromIdx:fromIdx+length]) {
-		d.d.errorf("expecting %s: got %s", jsonLiterals[fromIdx:fromIdx+length], bs)
-		return
-	}
-}
-
-func (d *jsonDecDriver) TryDecodeAsNil() bool {
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	// we shouldn't try to see if "null" was here, right?
-	// only the plain string: `null` denotes a nil (ie not quotes)
-	if d.tok == 'n' {
-		d.readLit(3, jsonLitNull+1) // (n)ull
-		return true
-	}
-	return false
-}
-
-func (d *jsonDecDriver) DecodeBool() (v bool) {
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	fquot := d.c == containerMapKey && d.tok == '"'
-	if fquot {
-		d.tok = d.r.readn1()
-	}
-	switch d.tok {
-	case 'f':
-		d.readLit(4, jsonLitFalse+1) // (f)alse
-		// v = false
-	case 't':
-		d.readLit(3, jsonLitTrue+1) // (t)rue
-		v = true
-	default:
-		d.d.errorf("decode bool: got first char %c", d.tok)
-		// v = false // "unreachable"
-	}
-	if fquot {
-		d.r.readn1()
-	}
-	return
-}
-
-func (d *jsonDecDriver) DecodeTime() (t time.Time) {
-	// read string, and pass the string into json.unmarshal
-	d.appendStringAsBytes()
-	if d.fnull {
-		return
-	}
-	t, err := time.Parse(time.RFC3339, stringView(d.bs))
-	if err != nil {
-		d.d.errorv(err)
-	}
-	return
-}
-
-func (d *jsonDecDriver) ContainerType() (vt valueType) {
-	// check container type by checking the first char
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-
-	// optimize this, so we don't do 4 checks but do one computation.
-	// return jsonContainerSet[d.tok]
-
-	// ContainerType is mostly called for Map and Array,
-	// so this conditional is good enough (max 2 checks typically)
-	if b := d.tok; b == '{' {
-		return valueTypeMap
-	} else if b == '[' {
-		return valueTypeArray
-	} else if b == 'n' {
-		return valueTypeNil
-	} else if b == '"' {
-		return valueTypeString
-	}
-	return valueTypeUnset
-}
-
-func (d *jsonDecDriver) decNumBytes() (bs []byte) {
-	// stores num bytes in d.bs
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	if d.tok == '"' {
-		bs = d.r.readUntil(d.b2[:0], '"')
-		bs = bs[:len(bs)-1]
-	} else {
-		d.r.unreadn1()
-		bs = d.r.readTo(d.bs[:0], &jsonNumSet)
-	}
-	d.tok = 0
-	return bs
-}
-
-func (d *jsonDecDriver) DecodeUint64() (u uint64) {
-	bs := d.decNumBytes()
-	n, neg, badsyntax, overflow := jsonParseInteger(bs)
-	if overflow {
-		d.d.errorf("overflow parsing unsigned integer: %s", bs)
-	} else if neg {
-		d.d.errorf("minus found parsing unsigned integer: %s", bs)
-	} else if badsyntax {
-		// fallback: try to decode as float, and cast
-		n = d.decUint64ViaFloat(stringView(bs))
-	}
-	return n
-}
-
-func (d *jsonDecDriver) DecodeInt64() (i int64) {
-	const cutoff = uint64(1 << uint(64-1))
-	bs := d.decNumBytes()
-	n, neg, badsyntax, overflow := jsonParseInteger(bs)
-	if overflow {
-		d.d.errorf("overflow parsing integer: %s", bs)
-	} else if badsyntax {
-		// d.d.errorf("invalid syntax for integer: %s", bs)
-		// fallback: try to decode as float, and cast
-		if neg {
-			n = d.decUint64ViaFloat(stringView(bs[1:]))
-		} else {
-			n = d.decUint64ViaFloat(stringView(bs))
-		}
-	}
-	if neg {
-		if n > cutoff {
-			d.d.errorf("overflow parsing integer: %s", bs)
-		}
-		i = -(int64(n))
-	} else {
-		if n >= cutoff {
-			d.d.errorf("overflow parsing integer: %s", bs)
-		}
-		i = int64(n)
-	}
-	return
-}
-
-func (d *jsonDecDriver) decUint64ViaFloat(s string) (u uint64) {
-	f, err := strconv.ParseFloat(s, 64)
-	if err != nil {
-		d.d.errorf("invalid syntax for integer: %s", s)
-		// d.d.errorv(err)
-	}
-	fi, ff := math.Modf(f)
-	if ff > 0 {
-		d.d.errorf("fractional part found parsing integer: %s", s)
-	} else if fi > float64(math.MaxUint64) {
-		d.d.errorf("overflow parsing integer: %s", s)
-	}
-	return uint64(fi)
-}
-
-func (d *jsonDecDriver) DecodeFloat64() (f float64) {
-	bs := d.decNumBytes()
-	f, err := strconv.ParseFloat(stringView(bs), 64)
-	if err != nil {
-		d.d.errorv(err)
-	}
-	return
-}
-
-func (d *jsonDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
-	if ext == nil {
-		re := rv.(*RawExt)
-		re.Tag = xtag
-		d.d.decode(&re.Value)
-	} else {
-		var v interface{}
-		d.d.decode(&v)
-		ext.UpdateExt(rv, v)
-	}
-	return
-}
-
-func (d *jsonDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
-	// if decoding into raw bytes, and the RawBytesExt is configured, use it to decode.
-	if d.se.InterfaceExt != nil {
-		bsOut = bs
-		d.DecodeExt(&bsOut, 0, &d.se)
-		return
-	}
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	if d.tok == '[' {
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	}
-	d.appendStringAsBytes()
-	// base64 encodes []byte{} as "", and we encode nil []byte as null.
-	// Consequently, base64 should decode null as a nil []byte, and "" as an empty []byte{}.
-	// appendStringAsBytes returns a zero-len slice for both, so as not to reset d.bs.
-	// However, it sets a fnull field to true, so we can check if a null was found.
-	if len(d.bs) == 0 {
-		if d.fnull {
-			return nil
-		}
-		return []byte{}
-	}
-	bs0 := d.bs
-	slen := base64.StdEncoding.DecodedLen(len(bs0))
-	if slen <= cap(bs) {
-		bsOut = bs[:slen]
-	} else if zerocopy && slen <= cap(d.b2) {
-		bsOut = d.b2[:slen]
-	} else {
-		bsOut = make([]byte, slen)
-	}
-	slen2, err := base64.StdEncoding.Decode(bsOut, bs0)
-	if err != nil {
-		d.d.errorf("error decoding base64 binary '%s': %v", bs0, err)
-		return nil
-	}
-	if slen != slen2 {
-		bsOut = bsOut[:slen2]
-	}
-	return
-}
-
-func (d *jsonDecDriver) DecodeString() (s string) {
-	d.appendStringAsBytes()
-	return d.bsToString()
-}
-
-func (d *jsonDecDriver) DecodeStringAsBytes() (s []byte) {
-	d.appendStringAsBytes()
-	return d.bs
-}
-
-func (d *jsonDecDriver) appendStringAsBytes() {
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-
-	d.fnull = false
-	if d.tok != '"' {
-		// d.d.errorf("expect char '%c' but got char '%c'", '"', d.tok)
-		// handle non-string scalar: null, true, false or a number
-		switch d.tok {
-		case 'n':
-			d.readLit(3, jsonLitNull+1) // (n)ull
-			d.bs = d.bs[:0]
-			d.fnull = true
-		case 'f':
-			d.readLit(4, jsonLitFalse+1) // (f)alse
-			d.bs = d.bs[:5]
-			copy(d.bs, "false")
-		case 't':
-			d.readLit(3, jsonLitTrue+1) // (t)rue
-			d.bs = d.bs[:4]
-			copy(d.bs, "true")
-		default:
-			// try to parse a valid number
-			bs := d.decNumBytes()
-			if len(bs) <= cap(d.bs) {
-				d.bs = d.bs[:len(bs)]
-			} else {
-				d.bs = make([]byte, len(bs))
-			}
-			copy(d.bs, bs)
-		}
-		return
-	}
-
-	d.tok = 0
-	r := d.r
-	var cs = r.readUntil(d.b2[:0], '"')
-	var cslen = len(cs)
-	var c uint8
-	v := d.bs[:0]
-	// append on each byte seen can be expensive, so we just
-	// keep track of where we last read a contiguous set of
-	// non-special bytes (using cursor variable),
-	// and when we see a special byte
-	// e.g. end-of-slice, " or \,
-	// we will append the full range into the v slice before proceeding
-	for i, cursor := 0, 0; ; {
-		if i == cslen {
-			v = append(v, cs[cursor:]...)
-			cs = r.readUntil(d.b2[:0], '"')
-			cslen = len(cs)
-			i, cursor = 0, 0
-		}
-		c = cs[i]
-		if c == '"' {
-			v = append(v, cs[cursor:i]...)
-			break
-		}
-		if c != '\\' {
-			i++
-			continue
-		}
-		v = append(v, cs[cursor:i]...)
-		i++
-		c = cs[i]
-		switch c {
-		case '"', '\\', '/', '\'':
-			v = append(v, c)
-		case 'b':
-			v = append(v, '\b')
-		case 'f':
-			v = append(v, '\f')
-		case 'n':
-			v = append(v, '\n')
-		case 'r':
-			v = append(v, '\r')
-		case 't':
-			v = append(v, '\t')
-		case 'u':
-			var r rune
-			var rr uint32
-			if len(cs) < i+4 { // may help reduce bounds-checking
-				d.d.errorf("need at least 4 more bytes for unicode sequence")
-			}
-			// c = cs[i+4] // may help reduce bounds-checking
-			for j := 1; j < 5; j++ {
-				// best to use explicit if-else
-				// - not a table, etc which involve memory loads, array lookup with bounds checks, etc
-				c = cs[i+j]
-				if c >= '0' && c <= '9' {
-					rr = rr*16 + uint32(c-jsonU4Chk2)
-				} else if c >= 'a' && c <= 'f' {
-					rr = rr*16 + uint32(c-jsonU4Chk1)
-				} else if c >= 'A' && c <= 'F' {
-					rr = rr*16 + uint32(c-jsonU4Chk0)
-				} else {
-					r = unicode.ReplacementChar
-					i += 4
-					goto encode_rune
-				}
-			}
-			r = rune(rr)
-			i += 4
-			if utf16.IsSurrogate(r) {
-				if len(cs) >= i+6 && cs[i+2] == 'u' && cs[i+1] == '\\' {
-					i += 2
-					// c = cs[i+4] // may help reduce bounds-checking
-					var rr1 uint32
-					for j := 1; j < 5; j++ {
-						c = cs[i+j]
-						if c >= '0' && c <= '9' {
-							rr = rr*16 + uint32(c-jsonU4Chk2)
-						} else if c >= 'a' && c <= 'f' {
-							rr = rr*16 + uint32(c-jsonU4Chk1)
-						} else if c >= 'A' && c <= 'F' {
-							rr = rr*16 + uint32(c-jsonU4Chk0)
-						} else {
-							r = unicode.ReplacementChar
-							i += 4
-							goto encode_rune
-						}
-					}
-					r = utf16.DecodeRune(r, rune(rr1))
-					i += 4
-				} else {
-					r = unicode.ReplacementChar
-					goto encode_rune
-				}
-			}
-		encode_rune:
-			w2 := utf8.EncodeRune(d.bstr[:], r)
-			v = append(v, d.bstr[:w2]...)
-		default:
-			d.d.errorf("unsupported escaped value: %c", c)
-		}
-		i++
-		cursor = i
-	}
-	d.bs = v
-}
-
-func (d *jsonDecDriver) nakedNum(z *decNaked, bs []byte) (err error) {
-	const cutoff = uint64(1 << uint(64-1))
-	var n uint64
-	var neg, badsyntax, overflow bool
-
-	if d.h.PreferFloat {
-		goto F
-	}
-	n, neg, badsyntax, overflow = jsonParseInteger(bs)
-	if badsyntax || overflow {
-		goto F
-	}
-	if neg {
-		if n > cutoff {
-			goto F
-		}
-		z.v = valueTypeInt
-		z.i = -(int64(n))
-	} else if d.h.SignedInteger {
-		if n >= cutoff {
-			goto F
-		}
-		z.v = valueTypeInt
-		z.i = int64(n)
-	} else {
-		z.v = valueTypeUint
-		z.u = n
-	}
-	return
-F:
-	z.v = valueTypeFloat
-	z.f, err = strconv.ParseFloat(stringView(bs), 64)
-	return
-}
-
-func (d *jsonDecDriver) bsToString() string {
-	// if x := d.s.sc; x != nil && x.so && x.st == '}' { // map key
-	if jsonAlwaysReturnInternString || d.c == containerMapKey {
-		return d.d.string(d.bs)
-	}
-	return string(d.bs)
-}
-
-func (d *jsonDecDriver) DecodeNaked() {
-	z := d.d.n
-	// var decodeFurther bool
-
-	if d.tok == 0 {
-		d.tok = d.r.skip(&jsonCharWhitespaceSet)
-	}
-	switch d.tok {
-	case 'n':
-		d.readLit(3, jsonLitNull+1) // (n)ull
-		z.v = valueTypeNil
-	case 'f':
-		d.readLit(4, jsonLitFalse+1) // (f)alse
-		z.v = valueTypeBool
-		z.b = false
-	case 't':
-		d.readLit(3, jsonLitTrue+1) // (t)rue
-		z.v = valueTypeBool
-		z.b = true
-	case '{':
-		z.v = valueTypeMap // don't consume. kInterfaceNaked will call ReadMapStart
-	case '[':
-		z.v = valueTypeArray // don't consume. kInterfaceNaked will call ReadArrayStart
-	case '"':
-		// if a string, and MapKeyAsString, then try to decode it as a nil, bool or number first
-		d.appendStringAsBytes()
-		if len(d.bs) > 0 && d.c == containerMapKey && d.h.MapKeyAsString {
-			switch stringView(d.bs) {
-			case "null":
-				z.v = valueTypeNil
-			case "true":
-				z.v = valueTypeBool
-				z.b = true
-			case "false":
-				z.v = valueTypeBool
-				z.b = false
-			default:
-				// check if a number: float, int or uint
-				if err := d.nakedNum(z, d.bs); err != nil {
-					z.v = valueTypeString
-					z.s = d.bsToString()
-				}
-			}
-		} else {
-			z.v = valueTypeString
-			z.s = d.bsToString()
-		}
-	default: // number
-		bs := d.decNumBytes()
-		if len(bs) == 0 {
-			d.d.errorf("decode number from empty string")
-			return
-		}
-		if err := d.nakedNum(z, bs); err != nil {
-			d.d.errorf("decode number from %s: %v", bs, err)
-			return
-		}
-	}
-	// if decodeFurther {
-	// 	d.s.sc.retryRead()
-	// }
-	return
-}
-
-//----------------------
-
-// JsonHandle is a handle for JSON encoding format.
-//
-// Json is comprehensively supported:
-//    - decodes numbers into interface{} as int, uint or float64
-//      based on how the number looks and some config parameters e.g. PreferFloat, SignedInt, etc.
-//    - decode integers from float formatted numbers e.g. 1.27e+8
-//    - decode any json value (numbers, bool, etc) from quoted strings
-//    - configurable way to encode/decode []byte .
-//      by default, encodes and decodes []byte using base64 Std Encoding
-//    - UTF-8 support for encoding and decoding
-//
-// It has better performance than the json library in the standard library,
-// by leveraging the performance improvements of the codec library.
-//
-// In addition, it doesn't read more bytes than necessary during a decode, which allows
-// reading multiple values from a stream containing json and non-json content.
-// For example, a user can read a json value, then a cbor value, then a msgpack value,
-// all from the same stream in sequence.
-//
-// Note that, when decoding quoted strings, invalid UTF-8 or invalid UTF-16 surrogate pairs are
-// not treated as an error. Instead, they are replaced by the Unicode replacement character U+FFFD.
-type JsonHandle struct {
-	textEncodingType
-	BasicHandle
-
-	// Indent indicates how a value is encoded.
-	//   - If positive, indent by that number of spaces.
-	//   - If negative, indent by that number of tabs.
-	Indent int8
-
-	// IntegerAsString controls how integers (signed and unsigned) are encoded.
-	//
-	// Per the JSON Spec, JSON numbers are 64-bit floating point numbers.
-	// Consequently, integers > 2^53 cannot be represented as a JSON number without losing precision.
-	// This can be mitigated by configuring how to encode integers.
-	//
-	// IntegerAsString interpretes the following values:
-	//   - if 'L', then encode integers > 2^53 as a json string.
-	//   - if 'A', then encode all integers as a json string
-	//             containing the exact integer representation as a decimal.
-	//   - else    encode all integers as a json number (default)
-	IntegerAsString byte
-
-	// HTMLCharsAsIs controls how to encode some special characters to html: < > &
-	//
-	// By default, we encode them as \uXXX
-	// to prevent security holes when served from some browsers.
-	HTMLCharsAsIs bool
-
-	// PreferFloat says that we will default to decoding a number as a float.
-	// If not set, we will examine the characters of the number and decode as an
-	// integer type if it doesn't have any of the characters [.eE].
-	PreferFloat bool
-
-	// TermWhitespace says that we add a whitespace character
-	// at the end of an encoding.
-	//
-	// The whitespace is important, especially if using numbers in a context
-	// where multiple items are written to a stream.
-	TermWhitespace bool
-
-	// MapKeyAsString says to encode all map keys as strings.
-	//
-	// Use this to enforce strict json output.
-	// The only caveat is that nil value is ALWAYS written as null (never as "null")
-	MapKeyAsString bool
-
-	// _ [2]byte // padding
-
-	// Note: below, we store hardly-used items e.g. RawBytesExt is cached in the (en|de)cDriver.
-
-	// RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way.
-	// If not configured, raw bytes are encoded to/from base64 text.
-	RawBytesExt InterfaceExt
-
-	_ [2]uint64 // padding
-}
-
-// Name returns the name of the handle: json
-func (h *JsonHandle) Name() string            { return "json" }
-func (h *JsonHandle) hasElemSeparators() bool { return true }
-func (h *JsonHandle) typical() bool {
-	return h.Indent == 0 && !h.MapKeyAsString && h.IntegerAsString != 'A' && h.IntegerAsString != 'L'
-}
-
-type jsonTypical interface {
-	typical()
-}
-
-func (h *JsonHandle) recreateEncDriver(ed encDriver) (v bool) {
-	_, v = ed.(jsonTypical)
-	return v != h.typical()
-}
-
-// SetInterfaceExt sets an extension
-func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
-}
-
-type jsonEncDriverTypicalImpl struct {
-	jsonEncDriver
-	jsonEncDriverTypical
-	_ [1]uint64 // padding
-}
-
-func (x *jsonEncDriverTypicalImpl) reset() {
-	x.jsonEncDriver.reset()
-	x.jsonEncDriverTypical.reset(&x.jsonEncDriver)
-}
-
-type jsonEncDriverGenericImpl struct {
-	jsonEncDriver
-	jsonEncDriverGeneric
-}
-
-func (x *jsonEncDriverGenericImpl) reset() {
-	x.jsonEncDriver.reset()
-	x.jsonEncDriverGeneric.reset(&x.jsonEncDriver)
-}
-
-func (h *JsonHandle) newEncDriver(e *Encoder) (ee encDriver) {
-	var hd *jsonEncDriver
-	if h.typical() {
-		var v jsonEncDriverTypicalImpl
-		ee = &v
-		hd = &v.jsonEncDriver
-	} else {
-		var v jsonEncDriverGenericImpl
-		ee = &v
-		hd = &v.jsonEncDriver
-	}
-	hd.e, hd.h, hd.bs = e, h, hd.b[:0]
-	hd.se.BytesExt = bytesExtFailer{}
-	ee.reset()
-	return
-}
-
-func (h *JsonHandle) newDecDriver(d *Decoder) decDriver {
-	// d := jsonDecDriver{r: r.(*bytesDecReader), h: h}
-	hd := jsonDecDriver{d: d, h: h}
-	hd.se.BytesExt = bytesExtFailer{}
-	hd.bs = hd.b[:0]
-	hd.reset()
-	return &hd
-}
-
-func (e *jsonEncDriver) reset() {
-	e.ew = e.e.w // e.e.w // &e.e.encWriterSwitch
-	e.se.InterfaceExt = e.h.RawBytesExt
-	if e.bs != nil {
-		e.bs = e.bs[:0]
-	}
-}
-
-func (d *jsonDecDriver) reset() {
-	d.r = d.d.r // &d.d.decReaderSwitch // d.d.r
-	d.se.InterfaceExt = d.h.RawBytesExt
-	if d.bs != nil {
-		d.bs = d.bs[:0]
-	}
-	d.c, d.tok = 0, 0
-	// d.n.reset()
-}
-
-func jsonFloatStrconvFmtPrec(f float64) (fmt byte, prec int) {
-	prec = -1
-	var abs = math.Abs(f)
-	if abs != 0 && (abs < 1e-6 || abs >= 1e21) {
-		fmt = 'e'
-	} else {
-		fmt = 'f'
-		// set prec to 1 iff mod is 0.
-		//     better than using jsonIsFloatBytesB2 to check if a . or E in the float bytes.
-		// this ensures that every float has an e or .0 in it.
-		if abs <= 1 {
-			if abs == 0 || abs == 1 {
-				prec = 1
-			}
-		} else if _, mod := math.Modf(abs); mod == 0 {
-			prec = 1
-		}
-	}
-	return
-}
-
-// custom-fitted version of strconv.Parse(Ui|I)nt.
-// Also ensures we don't have to search for .eE to determine if a float or not.
-func jsonParseInteger(s []byte) (n uint64, neg, badSyntax, overflow bool) {
-	const maxUint64 = (1<<64 - 1)
-	const cutoff = maxUint64/10 + 1
-
-	if len(s) == 0 {
-		badSyntax = true
-		return
-	}
-	switch s[0] {
-	case '+':
-		s = s[1:]
-	case '-':
-		s = s[1:]
-		neg = true
-	}
-	for _, c := range s {
-		if c < '0' || c > '9' {
-			badSyntax = true
-			return
-		}
-		// unsigned integers don't overflow well on multiplication, so check cutoff here
-		// e.g. (maxUint64-5)*10 doesn't overflow well ...
-		if n >= cutoff {
-			overflow = true
-			return
-		}
-		n *= 10
-		n1 := n + uint64(c-'0')
-		if n1 < n || n1 > maxUint64 {
-			overflow = true
-			return
-		}
-		n = n1
-	}
-	return
-}
-
-var _ decDriver = (*jsonDecDriver)(nil)
-var _ encDriver = (*jsonEncDriverGenericImpl)(nil)
-var _ encDriver = (*jsonEncDriverTypicalImpl)(nil)
-var _ jsonTypical = (*jsonEncDriverTypical)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl b/vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl
deleted file mode 100644
index 90d758c..0000000
--- a/vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// Code generated from mammoth-test.go.tmpl - DO NOT EDIT.
-
-package codec
-
-import "testing"
-import "fmt"
-import "reflect"
-
-// TestMammoth has all the different paths optimized in fast-path
-// It has all the primitives, slices and maps.
-// 
-// For each of those types, it has a pointer and a non-pointer field.
-
-func init() { _ = fmt.Printf } // so we can include fmt as needed
-
-type TestMammoth struct {
-
-{{range .Values }}{{if .Primitive }}{{/*
-*/}}{{ .MethodNamePfx "F" true }} {{ .Primitive }}
-{{ .MethodNamePfx "Fptr" true }} *{{ .Primitive }}
-{{end}}{{end}}
-
-{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
-*/}}{{ .MethodNamePfx "F" false }} []{{ .Elem }}
-{{ .MethodNamePfx "Fptr" false }} *[]{{ .Elem }}
-{{end}}{{end}}{{end}}
-
-{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
-*/}}{{ .MethodNamePfx "F" false }} map[{{ .MapKey }}]{{ .Elem }}
-{{ .MethodNamePfx "Fptr" false }} *map[{{ .MapKey }}]{{ .Elem }}
-{{end}}{{end}}{{end}}
-
-}
-
-{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
-*/}} type {{ .MethodNamePfx "typMbs" false }} []{{ .Elem }}
-func (_ {{ .MethodNamePfx "typMbs" false }}) MapBySlice() { }
-{{end}}{{end}}{{end}}
-
-{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
-*/}} type {{ .MethodNamePfx "typMap" false }} map[{{ .MapKey }}]{{ .Elem }}
-{{end}}{{end}}{{end}}
-
-func doTestMammothSlices(t *testing.T, h Handle) {
-{{range $i, $e := .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
-*/}}
-    var v{{$i}}va [8]{{ .Elem }}
-    for _, v := range [][]{{ .Elem }}{ nil, {}, { {{ nonzerocmd .Elem }}, {{ zerocmd .Elem }}, {{ zerocmd .Elem }}, {{ nonzerocmd .Elem }} } } { {{/*
-    // fmt.Printf(">>>> running mammoth slice v{{$i}}: %v\n", v)
-    //   - encode value to some []byte
-    //   - decode into a length-wise-equal []byte
-    //   - check if equal to initial slice
-    //   - encode ptr to the value
-    //   - check if encode bytes are same
-    //   - decode into ptrs to: nil, then 1-elem slice, equal-length, then large len slice
-    //   - decode into non-addressable slice of equal length, then larger len 
-    //   - for each decode, compare elem-by-elem to the original slice
-    //   - 
-    //   - rinse and repeat for a MapBySlice version
-    //   - 
-    */}}
-    var v{{$i}}v1, v{{$i}}v2 []{{ .Elem }}
-	v{{$i}}v1 = v
-	bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-slice-v{{$i}}")
-	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
-	testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}")
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}")
-	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
-	testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-slice-v{{$i}}-noaddr") // non-addressable value
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-noaddr")
-	// ...
-	bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-slice-v{{$i}}-p")
-	v{{$i}}v2 = nil
-	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p")
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p")
-	v{{$i}}va = [8]{{ .Elem }}{} // clear the array
-	v{{$i}}v2 = v{{$i}}va[:1:1]
-	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-1")
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-1")
-	v{{$i}}va = [8]{{ .Elem }}{} // clear the array
-	v{{$i}}v2 = v{{$i}}va[:len(v{{$i}}v1):len(v{{$i}}v1)]
-	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-len")
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-len")
-	v{{$i}}va = [8]{{ .Elem }}{} // clear the array
-	v{{$i}}v2 = v{{$i}}va[:]
-	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-cap")
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-cap")
-	if len(v{{$i}}v1) > 1 {
-	v{{$i}}va = [8]{{ .Elem }}{} // clear the array
-	testUnmarshalErr((&v{{$i}}va)[:len(v{{$i}}v1)], bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-len-noaddr")
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}va[:len(v{{$i}}v1)], t, "equal-slice-v{{$i}}-p-len-noaddr")
-	v{{$i}}va = [8]{{ .Elem }}{} // clear the array
-	testUnmarshalErr((&v{{$i}}va)[:], bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-cap-noaddr")
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}va[:len(v{{$i}}v1)], t, "equal-slice-v{{$i}}-p-cap-noaddr")
-    }
-    // ...
-    var v{{$i}}v3, v{{$i}}v4 {{ .MethodNamePfx "typMbs" false }}
-	v{{$i}}v2 = nil
-    if v != nil { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
-    v{{$i}}v3 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v1)
-    v{{$i}}v4 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v2)
-    bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom")
-    testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom")
-    testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom")
-    bs{{$i}} = testMarshalErr(&v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom-p")
-    v{{$i}}v2 = nil
-    v{{$i}}v4 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v2)
-    testUnmarshalErr(&v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom-p")
-    testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom-p")
-    }
-{{end}}{{end}}{{end}}
-}
-
-func doTestMammothMaps(t *testing.T, h Handle) {
-{{range $i, $e := .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
-*/}}
-    for _, v := range []map[{{ .MapKey }}]{{ .Elem }}{ nil, {}, { {{ nonzerocmd .MapKey }}:{{ zerocmd .Elem }} {{if ne "bool" .MapKey}}, {{ nonzerocmd .MapKey }}:{{ nonzerocmd .Elem }} {{end}} } } {
-    // fmt.Printf(">>>> running mammoth map v{{$i}}: %v\n", v)
-    var v{{$i}}v1, v{{$i}}v2 map[{{ .MapKey }}]{{ .Elem }}
-	v{{$i}}v1 = v
-	bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-map-v{{$i}}")
-	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
-	testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}")
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}")
-	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
-	testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-map-v{{$i}}-noaddr") // decode into non-addressable map value
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-noaddr")
-	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
-	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-len")
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p-len")
-	bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-map-v{{$i}}-p")
-	v{{$i}}v2 = nil
-	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-nil")
-	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p-nil")
-    // ...
-	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
-    var v{{$i}}v3, v{{$i}}v4 {{ .MethodNamePfx "typMap" false }}
-	v{{$i}}v3 = {{ .MethodNamePfx "typMap" false }}(v{{$i}}v1)
-	v{{$i}}v4 = {{ .MethodNamePfx "typMap" false }}(v{{$i}}v2)
-    bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-map-v{{$i}}-custom")
-	testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-len")
-	testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-map-v{{$i}}-p-len")
-    }
-{{end}}{{end}}{{end}}
-
-}
-
-func doTestMammothMapsAndSlices(t *testing.T, h Handle) {
-     doTestMammothSlices(t, h)
-     doTestMammothMaps(t, h)
-}
diff --git a/vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl b/vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl
deleted file mode 100644
index 7cdf8f5..0000000
--- a/vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl
+++ /dev/null
@@ -1,94 +0,0 @@
-// +build !notfastpath
-
-// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// Code generated from mammoth2-test.go.tmpl - DO NOT EDIT.
-
-package codec
-
-// Increase codecoverage by covering all the codecgen paths, in fast-path and gen-helper.go....
-//
-// Add:
-// - test file for creating a mammoth generated file as _mammoth_generated.go
-//   - generate a second mammoth files in a different file: mammoth2_generated_test.go
-//     - mammoth-test.go.tmpl will do this
-//   - run codecgen on it, into mammoth2_codecgen_generated_test.go (no build tags)
-//   - as part of TestMammoth, run it also
-//   - this will cover all the codecgen, gen-helper, etc in one full run
-//   - check in mammoth* files into github also
-// - then
-//
-// Now, add some types:
-//  - some that implement BinaryMarshal, TextMarshal, JSONMarshal, and one that implements none of it
-//  - create a wrapper type that includes TestMammoth2, with it in slices, and maps, and the custom types
-//  - this wrapper object is what we work encode/decode (so that the codecgen methods are called)
-
-
-// import "encoding/binary"
-import "fmt"
-
-type TestMammoth2 struct {
-
-{{range .Values }}{{if .Primitive }}{{/*
-*/}}{{ .MethodNamePfx "F" true }} {{ .Primitive }}
-{{ .MethodNamePfx "Fptr" true }} *{{ .Primitive }}
-{{end}}{{end}}
-
-{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
-*/}}{{ .MethodNamePfx "F" false }} []{{ .Elem }}
-{{ .MethodNamePfx "Fptr" false }} *[]{{ .Elem }}
-{{end}}{{end}}{{end}}
-
-{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
-*/}}{{ .MethodNamePfx "F" false }} map[{{ .MapKey }}]{{ .Elem }}
-{{ .MethodNamePfx "Fptr" false }} *map[{{ .MapKey }}]{{ .Elem }}
-{{end}}{{end}}{{end}}
-
-}
-
-// -----------
-
-type testMammoth2Binary uint64
-func (x testMammoth2Binary) MarshalBinary() (data []byte, err error) {
-data = make([]byte, 8)
-bigen.PutUint64(data, uint64(x))
-return
-}
-func (x *testMammoth2Binary) UnmarshalBinary(data []byte) (err error) {
-*x = testMammoth2Binary(bigen.Uint64(data))
-return
-}
-
-type testMammoth2Text uint64
-func (x testMammoth2Text) MarshalText() (data []byte, err error) {
-data = []byte(fmt.Sprintf("%b", uint64(x)))
-return
-}
-func (x *testMammoth2Text) UnmarshalText(data []byte) (err error) {
-_, err = fmt.Sscanf(string(data), "%b", (*uint64)(x))
-return
-}
-
-type testMammoth2Json uint64
-func (x testMammoth2Json) MarshalJSON() (data []byte, err error) {
-data = []byte(fmt.Sprintf("%v", uint64(x)))
-return
-}
-func (x *testMammoth2Json) UnmarshalJSON(data []byte) (err error) {
-_, err = fmt.Sscanf(string(data), "%v", (*uint64)(x))
-return
-}
-
-type testMammoth2Basic [4]uint64
-
-type TestMammoth2Wrapper struct {
-  V TestMammoth2
-  T testMammoth2Text
-  B testMammoth2Binary
-  J testMammoth2Json
-  C testMammoth2Basic
-  M map[testMammoth2Basic]TestMammoth2
-  L []TestMammoth2
-  A [4]int64
-}
diff --git a/vendor/github.com/ugorji/go/codec/msgpack.go b/vendor/github.com/ugorji/go/codec/msgpack.go
deleted file mode 100644
index 3271579..0000000
--- a/vendor/github.com/ugorji/go/codec/msgpack.go
+++ /dev/null
@@ -1,1092 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-/*
-MSGPACK
-
-Msgpack-c implementation powers the c, c++, python, ruby, etc libraries.
-We need to maintain compatibility with it and how it encodes integer values
-without caring about the type.
-
-For compatibility with behaviour of msgpack-c reference implementation:
-  - Go intX (>0) and uintX
-       IS ENCODED AS
-    msgpack +ve fixnum, unsigned
-  - Go intX (<0)
-       IS ENCODED AS
-    msgpack -ve fixnum, signed
-*/
-
-package codec
-
-import (
-	"fmt"
-	"io"
-	"math"
-	"net/rpc"
-	"reflect"
-	"time"
-)
-
-const (
-	mpPosFixNumMin byte = 0x00
-	mpPosFixNumMax      = 0x7f
-	mpFixMapMin         = 0x80
-	mpFixMapMax         = 0x8f
-	mpFixArrayMin       = 0x90
-	mpFixArrayMax       = 0x9f
-	mpFixStrMin         = 0xa0
-	mpFixStrMax         = 0xbf
-	mpNil               = 0xc0
-	_                   = 0xc1
-	mpFalse             = 0xc2
-	mpTrue              = 0xc3
-	mpFloat             = 0xca
-	mpDouble            = 0xcb
-	mpUint8             = 0xcc
-	mpUint16            = 0xcd
-	mpUint32            = 0xce
-	mpUint64            = 0xcf
-	mpInt8              = 0xd0
-	mpInt16             = 0xd1
-	mpInt32             = 0xd2
-	mpInt64             = 0xd3
-
-	// extensions below
-	mpBin8     = 0xc4
-	mpBin16    = 0xc5
-	mpBin32    = 0xc6
-	mpExt8     = 0xc7
-	mpExt16    = 0xc8
-	mpExt32    = 0xc9
-	mpFixExt1  = 0xd4
-	mpFixExt2  = 0xd5
-	mpFixExt4  = 0xd6
-	mpFixExt8  = 0xd7
-	mpFixExt16 = 0xd8
-
-	mpStr8  = 0xd9 // new
-	mpStr16 = 0xda
-	mpStr32 = 0xdb
-
-	mpArray16 = 0xdc
-	mpArray32 = 0xdd
-
-	mpMap16 = 0xde
-	mpMap32 = 0xdf
-
-	mpNegFixNumMin = 0xe0
-	mpNegFixNumMax = 0xff
-)
-
-var mpTimeExtTag int8 = -1
-var mpTimeExtTagU = uint8(mpTimeExtTag)
-
-// var mpdesc = map[byte]string{
-// 	mpPosFixNumMin: "PosFixNumMin",
-// 	mpPosFixNumMax: "PosFixNumMax",
-// 	mpFixMapMin:    "FixMapMin",
-// 	mpFixMapMax:    "FixMapMax",
-// 	mpFixArrayMin:  "FixArrayMin",
-// 	mpFixArrayMax:  "FixArrayMax",
-// 	mpFixStrMin:    "FixStrMin",
-// 	mpFixStrMax:    "FixStrMax",
-// 	mpNil:          "Nil",
-// 	mpFalse:        "False",
-// 	mpTrue:         "True",
-// 	mpFloat:        "Float",
-// 	mpDouble:       "Double",
-// 	mpUint8:        "Uint8",
-// 	mpUint16:       "Uint16",
-// 	mpUint32:       "Uint32",
-// 	mpUint64:       "Uint64",
-// 	mpInt8:         "Int8",
-// 	mpInt16:        "Int16",
-// 	mpInt32:        "Int32",
-// 	mpInt64:        "Int64",
-// 	mpBin8:         "Bin8",
-// 	mpBin16:        "Bin16",
-// 	mpBin32:        "Bin32",
-// 	mpExt8:         "Ext8",
-// 	mpExt16:        "Ext16",
-// 	mpExt32:        "Ext32",
-// 	mpFixExt1:      "FixExt1",
-// 	mpFixExt2:      "FixExt2",
-// 	mpFixExt4:      "FixExt4",
-// 	mpFixExt8:      "FixExt8",
-// 	mpFixExt16:     "FixExt16",
-// 	mpStr8:         "Str8",
-// 	mpStr16:        "Str16",
-// 	mpStr32:        "Str32",
-// 	mpArray16:      "Array16",
-// 	mpArray32:      "Array32",
-// 	mpMap16:        "Map16",
-// 	mpMap32:        "Map32",
-// 	mpNegFixNumMin: "NegFixNumMin",
-// 	mpNegFixNumMax: "NegFixNumMax",
-// }
-
-func mpdesc(bd byte) string {
-	switch bd {
-	case mpNil:
-		return "nil"
-	case mpFalse:
-		return "false"
-	case mpTrue:
-		return "true"
-	case mpFloat, mpDouble:
-		return "float"
-	case mpUint8, mpUint16, mpUint32, mpUint64:
-		return "uint"
-	case mpInt8, mpInt16, mpInt32, mpInt64:
-		return "int"
-	default:
-		switch {
-		case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax:
-			return "int"
-		case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax:
-			return "int"
-		case bd == mpStr8, bd == mpStr16, bd == mpStr32, bd >= mpFixStrMin && bd <= mpFixStrMax:
-			return "string|bytes"
-		case bd == mpBin8, bd == mpBin16, bd == mpBin32:
-			return "bytes"
-		case bd == mpArray16, bd == mpArray32, bd >= mpFixArrayMin && bd <= mpFixArrayMax:
-			return "array"
-		case bd == mpMap16, bd == mpMap32, bd >= mpFixMapMin && bd <= mpFixMapMax:
-			return "map"
-		case bd >= mpFixExt1 && bd <= mpFixExt16, bd >= mpExt8 && bd <= mpExt32:
-			return "ext"
-		default:
-			return "unknown"
-		}
-	}
-}
-
-// MsgpackSpecRpcMultiArgs is a special type which signifies to the MsgpackSpecRpcCodec
-// that the backend RPC service takes multiple arguments, which have been arranged
-// in sequence in the slice.
-//
-// The Codec then passes it AS-IS to the rpc service (without wrapping it in an
-// array of 1 element).
-type MsgpackSpecRpcMultiArgs []interface{}
-
-// A MsgpackContainer type specifies the different types of msgpackContainers.
-type msgpackContainerType struct {
-	fixCutoff                   int
-	bFixMin, b8, b16, b32       byte
-	hasFixMin, has8, has8Always bool
-}
-
-var (
-	msgpackContainerStr = msgpackContainerType{
-		32, mpFixStrMin, mpStr8, mpStr16, mpStr32, true, true, false,
-	}
-	msgpackContainerBin = msgpackContainerType{
-		0, 0, mpBin8, mpBin16, mpBin32, false, true, true,
-	}
-	msgpackContainerList = msgpackContainerType{
-		16, mpFixArrayMin, 0, mpArray16, mpArray32, true, false, false,
-	}
-	msgpackContainerMap = msgpackContainerType{
-		16, mpFixMapMin, 0, mpMap16, mpMap32, true, false, false,
-	}
-)
-
-//---------------------------------------------
-
-type msgpackEncDriver struct {
-	noBuiltInTypes
-	encDriverNoopContainerWriter
-	// encNoSeparator
-	e *Encoder
-	w encWriter
-	h *MsgpackHandle
-	x [8]byte
-	_ [3]uint64 // padding
-}
-
-func (e *msgpackEncDriver) EncodeNil() {
-	e.w.writen1(mpNil)
-}
-
-func (e *msgpackEncDriver) EncodeInt(i int64) {
-	// if i >= 0 {
-	// 	e.EncodeUint(uint64(i))
-	// } else if false &&
-	if i > math.MaxInt8 {
-		if i <= math.MaxInt16 {
-			e.w.writen1(mpInt16)
-			bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i))
-		} else if i <= math.MaxInt32 {
-			e.w.writen1(mpInt32)
-			bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i))
-		} else {
-			e.w.writen1(mpInt64)
-			bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i))
-		}
-	} else if i >= -32 {
-		if e.h.NoFixedNum {
-			e.w.writen2(mpInt8, byte(i))
-		} else {
-			e.w.writen1(byte(i))
-		}
-	} else if i >= math.MinInt8 {
-		e.w.writen2(mpInt8, byte(i))
-	} else if i >= math.MinInt16 {
-		e.w.writen1(mpInt16)
-		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i))
-	} else if i >= math.MinInt32 {
-		e.w.writen1(mpInt32)
-		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i))
-	} else {
-		e.w.writen1(mpInt64)
-		bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i))
-	}
-}
-
-func (e *msgpackEncDriver) EncodeUint(i uint64) {
-	if i <= math.MaxInt8 {
-		if e.h.NoFixedNum {
-			e.w.writen2(mpUint8, byte(i))
-		} else {
-			e.w.writen1(byte(i))
-		}
-	} else if i <= math.MaxUint8 {
-		e.w.writen2(mpUint8, byte(i))
-	} else if i <= math.MaxUint16 {
-		e.w.writen1(mpUint16)
-		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i))
-	} else if i <= math.MaxUint32 {
-		e.w.writen1(mpUint32)
-		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i))
-	} else {
-		e.w.writen1(mpUint64)
-		bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i))
-	}
-}
-
-func (e *msgpackEncDriver) EncodeBool(b bool) {
-	if b {
-		e.w.writen1(mpTrue)
-	} else {
-		e.w.writen1(mpFalse)
-	}
-}
-
-func (e *msgpackEncDriver) EncodeFloat32(f float32) {
-	e.w.writen1(mpFloat)
-	bigenHelper{e.x[:4], e.w}.writeUint32(math.Float32bits(f))
-}
-
-func (e *msgpackEncDriver) EncodeFloat64(f float64) {
-	e.w.writen1(mpDouble)
-	bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
-}
-
-func (e *msgpackEncDriver) EncodeTime(t time.Time) {
-	if t.IsZero() {
-		e.EncodeNil()
-		return
-	}
-	t = t.UTC()
-	sec, nsec := t.Unix(), uint64(t.Nanosecond())
-	var data64 uint64
-	var l = 4
-	if sec >= 0 && sec>>34 == 0 {
-		data64 = (nsec << 34) | uint64(sec)
-		if data64&0xffffffff00000000 != 0 {
-			l = 8
-		}
-	} else {
-		l = 12
-	}
-	if e.h.WriteExt {
-		e.encodeExtPreamble(mpTimeExtTagU, l)
-	} else {
-		e.writeContainerLen(msgpackContainerStr, l)
-	}
-	switch l {
-	case 4:
-		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(data64))
-	case 8:
-		bigenHelper{e.x[:8], e.w}.writeUint64(data64)
-	case 12:
-		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(nsec))
-		bigenHelper{e.x[:8], e.w}.writeUint64(uint64(sec))
-	}
-}
-
-func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Encoder) {
-	bs := ext.WriteExt(v)
-	if bs == nil {
-		e.EncodeNil()
-		return
-	}
-	if e.h.WriteExt {
-		e.encodeExtPreamble(uint8(xtag), len(bs))
-		e.w.writeb(bs)
-	} else {
-		e.EncodeStringBytes(cRAW, bs)
-	}
-}
-
-func (e *msgpackEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) {
-	e.encodeExtPreamble(uint8(re.Tag), len(re.Data))
-	e.w.writeb(re.Data)
-}
-
-func (e *msgpackEncDriver) encodeExtPreamble(xtag byte, l int) {
-	if l == 1 {
-		e.w.writen2(mpFixExt1, xtag)
-	} else if l == 2 {
-		e.w.writen2(mpFixExt2, xtag)
-	} else if l == 4 {
-		e.w.writen2(mpFixExt4, xtag)
-	} else if l == 8 {
-		e.w.writen2(mpFixExt8, xtag)
-	} else if l == 16 {
-		e.w.writen2(mpFixExt16, xtag)
-	} else if l < 256 {
-		e.w.writen2(mpExt8, byte(l))
-		e.w.writen1(xtag)
-	} else if l < 65536 {
-		e.w.writen1(mpExt16)
-		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(l))
-		e.w.writen1(xtag)
-	} else {
-		e.w.writen1(mpExt32)
-		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(l))
-		e.w.writen1(xtag)
-	}
-}
-
-func (e *msgpackEncDriver) WriteArrayStart(length int) {
-	e.writeContainerLen(msgpackContainerList, length)
-}
-
-func (e *msgpackEncDriver) WriteMapStart(length int) {
-	e.writeContainerLen(msgpackContainerMap, length)
-}
-
-func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) {
-	slen := len(s)
-	if c == cRAW && e.h.WriteExt {
-		e.writeContainerLen(msgpackContainerBin, slen)
-	} else {
-		e.writeContainerLen(msgpackContainerStr, slen)
-	}
-	if slen > 0 {
-		e.w.writestr(s)
-	}
-}
-
-func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) {
-	if bs == nil {
-		e.EncodeNil()
-		return
-	}
-	slen := len(bs)
-	if c == cRAW && e.h.WriteExt {
-		e.writeContainerLen(msgpackContainerBin, slen)
-	} else {
-		e.writeContainerLen(msgpackContainerStr, slen)
-	}
-	if slen > 0 {
-		e.w.writeb(bs)
-	}
-}
-
-func (e *msgpackEncDriver) writeContainerLen(ct msgpackContainerType, l int) {
-	if ct.hasFixMin && l < ct.fixCutoff {
-		e.w.writen1(ct.bFixMin | byte(l))
-	} else if ct.has8 && l < 256 && (ct.has8Always || e.h.WriteExt) {
-		e.w.writen2(ct.b8, uint8(l))
-	} else if l < 65536 {
-		e.w.writen1(ct.b16)
-		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(l))
-	} else {
-		e.w.writen1(ct.b32)
-		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(l))
-	}
-}
-
-//---------------------------------------------
-
-type msgpackDecDriver struct {
-	d *Decoder
-	r decReader // *Decoder decReader decReaderT
-	h *MsgpackHandle
-	// b      [scratchByteArrayLen]byte
-	bd     byte
-	bdRead bool
-	br     bool // bytes reader
-	noBuiltInTypes
-	// noStreamingCodec
-	// decNoSeparator
-	decDriverNoopContainerReader
-	_ [3]uint64 // padding
-}
-
-// Note: This returns either a primitive (int, bool, etc) for non-containers,
-// or a containerType, or a specific type denoting nil or extension.
-// It is called when a nil interface{} is passed, leaving it up to the DecDriver
-// to introspect the stream and decide how best to decode.
-// It deciphers the value by looking at the stream first.
-func (d *msgpackDecDriver) DecodeNaked() {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	bd := d.bd
-	n := d.d.n
-	var decodeFurther bool
-
-	switch bd {
-	case mpNil:
-		n.v = valueTypeNil
-		d.bdRead = false
-	case mpFalse:
-		n.v = valueTypeBool
-		n.b = false
-	case mpTrue:
-		n.v = valueTypeBool
-		n.b = true
-
-	case mpFloat:
-		n.v = valueTypeFloat
-		n.f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
-	case mpDouble:
-		n.v = valueTypeFloat
-		n.f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
-
-	case mpUint8:
-		n.v = valueTypeUint
-		n.u = uint64(d.r.readn1())
-	case mpUint16:
-		n.v = valueTypeUint
-		n.u = uint64(bigen.Uint16(d.r.readx(2)))
-	case mpUint32:
-		n.v = valueTypeUint
-		n.u = uint64(bigen.Uint32(d.r.readx(4)))
-	case mpUint64:
-		n.v = valueTypeUint
-		n.u = uint64(bigen.Uint64(d.r.readx(8)))
-
-	case mpInt8:
-		n.v = valueTypeInt
-		n.i = int64(int8(d.r.readn1()))
-	case mpInt16:
-		n.v = valueTypeInt
-		n.i = int64(int16(bigen.Uint16(d.r.readx(2))))
-	case mpInt32:
-		n.v = valueTypeInt
-		n.i = int64(int32(bigen.Uint32(d.r.readx(4))))
-	case mpInt64:
-		n.v = valueTypeInt
-		n.i = int64(int64(bigen.Uint64(d.r.readx(8))))
-
-	default:
-		switch {
-		case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax:
-			// positive fixnum (always signed)
-			n.v = valueTypeInt
-			n.i = int64(int8(bd))
-		case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax:
-			// negative fixnum
-			n.v = valueTypeInt
-			n.i = int64(int8(bd))
-		case bd == mpStr8, bd == mpStr16, bd == mpStr32, bd >= mpFixStrMin && bd <= mpFixStrMax:
-			if d.h.RawToString {
-				n.v = valueTypeString
-				n.s = d.DecodeString()
-			} else {
-				n.v = valueTypeBytes
-				n.l = d.DecodeBytes(nil, false)
-			}
-		case bd == mpBin8, bd == mpBin16, bd == mpBin32:
-			n.v = valueTypeBytes
-			n.l = d.DecodeBytes(nil, false)
-		case bd == mpArray16, bd == mpArray32, bd >= mpFixArrayMin && bd <= mpFixArrayMax:
-			n.v = valueTypeArray
-			decodeFurther = true
-		case bd == mpMap16, bd == mpMap32, bd >= mpFixMapMin && bd <= mpFixMapMax:
-			n.v = valueTypeMap
-			decodeFurther = true
-		case bd >= mpFixExt1 && bd <= mpFixExt16, bd >= mpExt8 && bd <= mpExt32:
-			n.v = valueTypeExt
-			clen := d.readExtLen()
-			n.u = uint64(d.r.readn1())
-			if n.u == uint64(mpTimeExtTagU) {
-				n.v = valueTypeTime
-				n.t = d.decodeTime(clen)
-			} else {
-				n.l = d.r.readx(clen)
-			}
-		default:
-			d.d.errorf("cannot infer value: %s: Ox%x/%d/%s", msgBadDesc, bd, bd, mpdesc(bd))
-		}
-	}
-	if !decodeFurther {
-		d.bdRead = false
-	}
-	if n.v == valueTypeUint && d.h.SignedInteger {
-		n.v = valueTypeInt
-		n.i = int64(n.u)
-	}
-	return
-}
-
-// int can be decoded from msgpack type: intXXX or uintXXX
-func (d *msgpackDecDriver) DecodeInt64() (i int64) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	switch d.bd {
-	case mpUint8:
-		i = int64(uint64(d.r.readn1()))
-	case mpUint16:
-		i = int64(uint64(bigen.Uint16(d.r.readx(2))))
-	case mpUint32:
-		i = int64(uint64(bigen.Uint32(d.r.readx(4))))
-	case mpUint64:
-		i = int64(bigen.Uint64(d.r.readx(8)))
-	case mpInt8:
-		i = int64(int8(d.r.readn1()))
-	case mpInt16:
-		i = int64(int16(bigen.Uint16(d.r.readx(2))))
-	case mpInt32:
-		i = int64(int32(bigen.Uint32(d.r.readx(4))))
-	case mpInt64:
-		i = int64(bigen.Uint64(d.r.readx(8)))
-	default:
-		switch {
-		case d.bd >= mpPosFixNumMin && d.bd <= mpPosFixNumMax:
-			i = int64(int8(d.bd))
-		case d.bd >= mpNegFixNumMin && d.bd <= mpNegFixNumMax:
-			i = int64(int8(d.bd))
-		default:
-			d.d.errorf("cannot decode signed integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd))
-			return
-		}
-	}
-	d.bdRead = false
-	return
-}
-
-// uint can be decoded from msgpack type: intXXX or uintXXX
-func (d *msgpackDecDriver) DecodeUint64() (ui uint64) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	switch d.bd {
-	case mpUint8:
-		ui = uint64(d.r.readn1())
-	case mpUint16:
-		ui = uint64(bigen.Uint16(d.r.readx(2)))
-	case mpUint32:
-		ui = uint64(bigen.Uint32(d.r.readx(4)))
-	case mpUint64:
-		ui = bigen.Uint64(d.r.readx(8))
-	case mpInt8:
-		if i := int64(int8(d.r.readn1())); i >= 0 {
-			ui = uint64(i)
-		} else {
-			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
-			return
-		}
-	case mpInt16:
-		if i := int64(int16(bigen.Uint16(d.r.readx(2)))); i >= 0 {
-			ui = uint64(i)
-		} else {
-			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
-			return
-		}
-	case mpInt32:
-		if i := int64(int32(bigen.Uint32(d.r.readx(4)))); i >= 0 {
-			ui = uint64(i)
-		} else {
-			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
-			return
-		}
-	case mpInt64:
-		if i := int64(bigen.Uint64(d.r.readx(8))); i >= 0 {
-			ui = uint64(i)
-		} else {
-			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
-			return
-		}
-	default:
-		switch {
-		case d.bd >= mpPosFixNumMin && d.bd <= mpPosFixNumMax:
-			ui = uint64(d.bd)
-		case d.bd >= mpNegFixNumMin && d.bd <= mpNegFixNumMax:
-			d.d.errorf("assigning negative signed value: %v, to unsigned type", int(d.bd))
-			return
-		default:
-			d.d.errorf("cannot decode unsigned integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd))
-			return
-		}
-	}
-	d.bdRead = false
-	return
-}
-
-// float can either be decoded from msgpack type: float, double or intX
-func (d *msgpackDecDriver) DecodeFloat64() (f float64) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == mpFloat {
-		f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
-	} else if d.bd == mpDouble {
-		f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
-	} else {
-		f = float64(d.DecodeInt64())
-	}
-	d.bdRead = false
-	return
-}
-
-// bool can be decoded from bool, fixnum 0 or 1.
-func (d *msgpackDecDriver) DecodeBool() (b bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == mpFalse || d.bd == 0 {
-		// b = false
-	} else if d.bd == mpTrue || d.bd == 1 {
-		b = true
-	} else {
-		d.d.errorf("cannot decode bool: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd))
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	bd := d.bd
-	// DecodeBytes could be from: bin str fixstr fixarray array ...
-	var clen int
-	vt := d.ContainerType()
-	switch vt {
-	case valueTypeBytes:
-		// valueTypeBytes may be a mpBin or an mpStr container
-		if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 {
-			clen = d.readContainerLen(msgpackContainerBin)
-		} else {
-			clen = d.readContainerLen(msgpackContainerStr)
-		}
-	case valueTypeString:
-		clen = d.readContainerLen(msgpackContainerStr)
-	case valueTypeArray:
-		if zerocopy && len(bs) == 0 {
-			bs = d.d.b[:]
-		}
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	default:
-		d.d.errorf("invalid container type: expecting bin|str|array, got: 0x%x", uint8(vt))
-		return
-	}
-
-	// these are (bin|str)(8|16|32)
-	d.bdRead = false
-	// bytes may be nil, so handle it. if nil, clen=-1.
-	if clen < 0 {
-		return nil
-	}
-	if zerocopy {
-		if d.br {
-			return d.r.readx(clen)
-		} else if len(bs) == 0 {
-			bs = d.d.b[:]
-		}
-	}
-	return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
-}
-
-func (d *msgpackDecDriver) DecodeString() (s string) {
-	return string(d.DecodeBytes(d.d.b[:], true))
-}
-
-func (d *msgpackDecDriver) DecodeStringAsBytes() (s []byte) {
-	return d.DecodeBytes(d.d.b[:], true)
-}
-
-func (d *msgpackDecDriver) readNextBd() {
-	d.bd = d.r.readn1()
-	d.bdRead = true
-}
-
-func (d *msgpackDecDriver) uncacheRead() {
-	if d.bdRead {
-		d.r.unreadn1()
-		d.bdRead = false
-	}
-}
-
-func (d *msgpackDecDriver) ContainerType() (vt valueType) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	bd := d.bd
-	if bd == mpNil {
-		return valueTypeNil
-	} else if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 ||
-		(!d.h.RawToString &&
-			(bd == mpStr8 || bd == mpStr16 || bd == mpStr32 || (bd >= mpFixStrMin && bd <= mpFixStrMax))) {
-		return valueTypeBytes
-	} else if d.h.RawToString &&
-		(bd == mpStr8 || bd == mpStr16 || bd == mpStr32 || (bd >= mpFixStrMin && bd <= mpFixStrMax)) {
-		return valueTypeString
-	} else if bd == mpArray16 || bd == mpArray32 || (bd >= mpFixArrayMin && bd <= mpFixArrayMax) {
-		return valueTypeArray
-	} else if bd == mpMap16 || bd == mpMap32 || (bd >= mpFixMapMin && bd <= mpFixMapMax) {
-		return valueTypeMap
-	}
-	// else {
-	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
-	// }
-	return valueTypeUnset
-}
-
-func (d *msgpackDecDriver) TryDecodeAsNil() (v bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == mpNil {
-		d.bdRead = false
-		return true
-	}
-	return
-}
-
-func (d *msgpackDecDriver) readContainerLen(ct msgpackContainerType) (clen int) {
-	bd := d.bd
-	if bd == mpNil {
-		clen = -1 // to represent nil
-	} else if bd == ct.b8 {
-		clen = int(d.r.readn1())
-	} else if bd == ct.b16 {
-		clen = int(bigen.Uint16(d.r.readx(2)))
-	} else if bd == ct.b32 {
-		clen = int(bigen.Uint32(d.r.readx(4)))
-	} else if (ct.bFixMin & bd) == ct.bFixMin {
-		clen = int(ct.bFixMin ^ bd)
-	} else {
-		d.d.errorf("cannot read container length: %s: hex: %x, decimal: %d", msgBadDesc, bd, bd)
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *msgpackDecDriver) ReadMapStart() int {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	return d.readContainerLen(msgpackContainerMap)
-}
-
-func (d *msgpackDecDriver) ReadArrayStart() int {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	return d.readContainerLen(msgpackContainerList)
-}
-
-func (d *msgpackDecDriver) readExtLen() (clen int) {
-	switch d.bd {
-	case mpNil:
-		clen = -1 // to represent nil
-	case mpFixExt1:
-		clen = 1
-	case mpFixExt2:
-		clen = 2
-	case mpFixExt4:
-		clen = 4
-	case mpFixExt8:
-		clen = 8
-	case mpFixExt16:
-		clen = 16
-	case mpExt8:
-		clen = int(d.r.readn1())
-	case mpExt16:
-		clen = int(bigen.Uint16(d.r.readx(2)))
-	case mpExt32:
-		clen = int(bigen.Uint32(d.r.readx(4)))
-	default:
-		d.d.errorf("decoding ext bytes: found unexpected byte: %x", d.bd)
-		return
-	}
-	return
-}
-
-func (d *msgpackDecDriver) DecodeTime() (t time.Time) {
-	// decode time from string bytes or ext
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == mpNil {
-		d.bdRead = false
-		return
-	}
-	var clen int
-	switch d.ContainerType() {
-	case valueTypeBytes, valueTypeString:
-		clen = d.readContainerLen(msgpackContainerStr)
-	default:
-		// expect to see mpFixExt4,-1 OR mpFixExt8,-1 OR mpExt8,12,-1
-		d.bdRead = false
-		b2 := d.r.readn1()
-		if d.bd == mpFixExt4 && b2 == mpTimeExtTagU {
-			clen = 4
-		} else if d.bd == mpFixExt8 && b2 == mpTimeExtTagU {
-			clen = 8
-		} else if d.bd == mpExt8 && b2 == 12 && d.r.readn1() == mpTimeExtTagU {
-			clen = 12
-		} else {
-			d.d.errorf("invalid bytes for decoding time as extension: got 0x%x, 0x%x", d.bd, b2)
-			return
-		}
-	}
-	return d.decodeTime(clen)
-}
-
-func (d *msgpackDecDriver) decodeTime(clen int) (t time.Time) {
-	// bs = d.r.readx(clen)
-	d.bdRead = false
-	switch clen {
-	case 4:
-		t = time.Unix(int64(bigen.Uint32(d.r.readx(4))), 0).UTC()
-	case 8:
-		tv := bigen.Uint64(d.r.readx(8))
-		t = time.Unix(int64(tv&0x00000003ffffffff), int64(tv>>34)).UTC()
-	case 12:
-		nsec := bigen.Uint32(d.r.readx(4))
-		sec := bigen.Uint64(d.r.readx(8))
-		t = time.Unix(int64(sec), int64(nsec)).UTC()
-	default:
-		d.d.errorf("invalid length of bytes for decoding time - expecting 4 or 8 or 12, got %d", clen)
-		return
-	}
-	return
-}
-
-func (d *msgpackDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
-	if xtag > 0xff {
-		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
-		return
-	}
-	realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
-	realxtag = uint64(realxtag1)
-	if ext == nil {
-		re := rv.(*RawExt)
-		re.Tag = realxtag
-		re.Data = detachZeroCopyBytes(d.br, re.Data, xbs)
-	} else {
-		ext.ReadExt(rv, xbs)
-	}
-	return
-}
-
-func (d *msgpackDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	xbd := d.bd
-	if xbd == mpBin8 || xbd == mpBin16 || xbd == mpBin32 {
-		xbs = d.DecodeBytes(nil, true)
-	} else if xbd == mpStr8 || xbd == mpStr16 || xbd == mpStr32 ||
-		(xbd >= mpFixStrMin && xbd <= mpFixStrMax) {
-		xbs = d.DecodeStringAsBytes()
-	} else {
-		clen := d.readExtLen()
-		xtag = d.r.readn1()
-		if verifyTag && xtag != tag {
-			d.d.errorf("wrong extension tag - got %b, expecting %v", xtag, tag)
-			return
-		}
-		xbs = d.r.readx(clen)
-	}
-	d.bdRead = false
-	return
-}
-
-//--------------------------------------------------
-
-//MsgpackHandle is a Handle for the Msgpack Schema-Free Encoding Format.
-type MsgpackHandle struct {
-	BasicHandle
-
-	// RawToString controls how raw bytes are decoded into a nil interface{}.
-	RawToString bool
-
-	// NoFixedNum says to output all signed integers as 2-bytes, never as 1-byte fixednum.
-	NoFixedNum bool
-
-	// WriteExt flag supports encoding configured extensions with extension tags.
-	// It also controls whether other elements of the new spec are encoded (ie Str8).
-	//
-	// With WriteExt=false, configured extensions are serialized as raw bytes
-	// and Str8 is not encoded.
-	//
-	// A stream can still be decoded into a typed value, provided an appropriate value
-	// is provided, but the type cannot be inferred from the stream. If no appropriate
-	// type is provided (e.g. decoding into a nil interface{}), you get back
-	// a []byte or string based on the setting of RawToString.
-	WriteExt bool
-
-	binaryEncodingType
-	noElemSeparators
-
-	// _ [1]uint64 // padding
-}
-
-// Name returns the name of the handle: msgpack
-func (h *MsgpackHandle) Name() string { return "msgpack" }
-
-// SetBytesExt sets an extension
-func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
-}
-
-func (h *MsgpackHandle) newEncDriver(e *Encoder) encDriver {
-	return &msgpackEncDriver{e: e, w: e.w, h: h}
-}
-
-func (h *MsgpackHandle) newDecDriver(d *Decoder) decDriver {
-	return &msgpackDecDriver{d: d, h: h, r: d.r, br: d.bytes}
-}
-
-func (e *msgpackEncDriver) reset() {
-	e.w = e.e.w
-}
-
-func (d *msgpackDecDriver) reset() {
-	d.r, d.br = d.d.r, d.d.bytes
-	d.bd, d.bdRead = 0, false
-}
-
-//--------------------------------------------------
-
-type msgpackSpecRpcCodec struct {
-	rpcCodec
-}
-
-// /////////////// Spec RPC Codec ///////////////////
-func (c *msgpackSpecRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
-	// WriteRequest can write to both a Go service, and other services that do
-	// not abide by the 1 argument rule of a Go service.
-	// We discriminate based on if the body is a MsgpackSpecRpcMultiArgs
-	var bodyArr []interface{}
-	if m, ok := body.(MsgpackSpecRpcMultiArgs); ok {
-		bodyArr = ([]interface{})(m)
-	} else {
-		bodyArr = []interface{}{body}
-	}
-	r2 := []interface{}{0, uint32(r.Seq), r.ServiceMethod, bodyArr}
-	return c.write(r2, nil, false)
-}
-
-func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
-	var moe interface{}
-	if r.Error != "" {
-		moe = r.Error
-	}
-	if moe != nil && body != nil {
-		body = nil
-	}
-	r2 := []interface{}{1, uint32(r.Seq), moe, body}
-	return c.write(r2, nil, false)
-}
-
-func (c *msgpackSpecRpcCodec) ReadResponseHeader(r *rpc.Response) error {
-	return c.parseCustomHeader(1, &r.Seq, &r.Error)
-}
-
-func (c *msgpackSpecRpcCodec) ReadRequestHeader(r *rpc.Request) error {
-	return c.parseCustomHeader(0, &r.Seq, &r.ServiceMethod)
-}
-
-func (c *msgpackSpecRpcCodec) ReadRequestBody(body interface{}) error {
-	if body == nil { // read and discard
-		return c.read(nil)
-	}
-	bodyArr := []interface{}{body}
-	return c.read(&bodyArr)
-}
-
-func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) {
-	if c.isClosed() {
-		return io.EOF
-	}
-
-	// We read the response header by hand
-	// so that the body can be decoded on its own from the stream at a later time.
-
-	const fia byte = 0x94 //four item array descriptor value
-	// Not sure why the panic of EOF is swallowed above.
-	// if bs1 := c.dec.r.readn1(); bs1 != fia {
-	// 	err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, bs1)
-	// 	return
-	// }
-	var ba [1]byte
-	var n int
-	for {
-		n, err = c.r.Read(ba[:])
-		if err != nil {
-			return
-		}
-		if n == 1 {
-			break
-		}
-	}
-
-	var b = ba[0]
-	if b != fia {
-		err = fmt.Errorf("not array - %s %x/%s", msgBadDesc, b, mpdesc(b))
-	} else {
-		err = c.read(&b)
-		if err == nil {
-			if b != expectTypeByte {
-				err = fmt.Errorf("%s - expecting %v but got %x/%s",
-					msgBadDesc, expectTypeByte, b, mpdesc(b))
-			} else {
-				err = c.read(msgid)
-				if err == nil {
-					err = c.read(methodOrError)
-				}
-			}
-		}
-	}
-	return
-}
-
-//--------------------------------------------------
-
-// msgpackSpecRpc is the implementation of Rpc that uses custom communication protocol
-// as defined in the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
-type msgpackSpecRpc struct{}
-
-// MsgpackSpecRpc implements Rpc using the communication protocol defined in
-// the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md .
-//
-// See GoRpc documentation, for information on buffering for better performance.
-var MsgpackSpecRpc msgpackSpecRpc
-
-func (x msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
-	return &msgpackSpecRpcCodec{newRPCCodec(conn, h)}
-}
-
-func (x msgpackSpecRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
-	return &msgpackSpecRpcCodec{newRPCCodec(conn, h)}
-}
-
-var _ decDriver = (*msgpackDecDriver)(nil)
-var _ encDriver = (*msgpackEncDriver)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/rpc.go b/vendor/github.com/ugorji/go/codec/rpc.go
deleted file mode 100644
index 9fb3c01..0000000
--- a/vendor/github.com/ugorji/go/codec/rpc.go
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"bufio"
-	"errors"
-	"io"
-	"net/rpc"
-	"sync"
-)
-
-// Rpc provides a rpc Server or Client Codec for rpc communication.
-type Rpc interface {
-	ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec
-	ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec
-}
-
-// RPCOptions holds options specific to rpc functionality
-type RPCOptions struct {
-	// RPCNoBuffer configures whether we attempt to buffer reads and writes during RPC calls.
-	//
-	// Set RPCNoBuffer=true to turn buffering off.
-	// Buffering can still be done if buffered connections are passed in, or
-	// buffering is configured on the handle.
-	RPCNoBuffer bool
-}
-
-// rpcCodec defines the struct members and common methods.
-type rpcCodec struct {
-	c io.Closer
-	r io.Reader
-	w io.Writer
-	f ioFlusher
-
-	dec *Decoder
-	enc *Encoder
-	// bw  *bufio.Writer
-	// br  *bufio.Reader
-	mu sync.Mutex
-	h  Handle
-
-	cls    bool
-	clsmu  sync.RWMutex
-	clsErr error
-}
-
-func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
-	// return newRPCCodec2(bufio.NewReader(conn), bufio.NewWriter(conn), conn, h)
-	return newRPCCodec2(conn, conn, conn, h)
-}
-
-func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
-	// defensive: ensure that jsonH has TermWhitespace turned on.
-	if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace {
-		panic(errors.New("rpc requires a JsonHandle with TermWhitespace set to true"))
-	}
-	// always ensure that we use a flusher, and always flush what was written to the connection.
-	// we lose nothing by using a buffered writer internally.
-	f, ok := w.(ioFlusher)
-	bh := h.getBasicHandle()
-	if !bh.RPCNoBuffer {
-		if bh.WriterBufferSize <= 0 {
-			if !ok {
-				bw := bufio.NewWriter(w)
-				f, w = bw, bw
-			}
-		}
-		if bh.ReaderBufferSize <= 0 {
-			if _, ok = w.(ioPeeker); !ok {
-				if _, ok = w.(ioBuffered); !ok {
-					br := bufio.NewReader(r)
-					r = br
-				}
-			}
-		}
-	}
-	return rpcCodec{
-		c:   c,
-		w:   w,
-		r:   r,
-		f:   f,
-		h:   h,
-		enc: NewEncoder(w, h),
-		dec: NewDecoder(r, h),
-	}
-}
-
-func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2 bool) (err error) {
-	if c.isClosed() {
-		return c.clsErr
-	}
-	err = c.enc.Encode(obj1)
-	if err == nil {
-		if writeObj2 {
-			err = c.enc.Encode(obj2)
-		}
-		// if err == nil && c.f != nil {
-		// 	err = c.f.Flush()
-		// }
-	}
-	if c.f != nil {
-		if err == nil {
-			err = c.f.Flush()
-		} else {
-			_ = c.f.Flush() // swallow flush error, so we maintain prior error on write
-		}
-	}
-	return
-}
-
-func (c *rpcCodec) swallow(err *error) {
-	defer panicToErr(c.dec, err)
-	c.dec.swallow()
-}
-
-func (c *rpcCodec) read(obj interface{}) (err error) {
-	if c.isClosed() {
-		return c.clsErr
-	}
-	//If nil is passed in, we should read and discard
-	if obj == nil {
-		// var obj2 interface{}
-		// return c.dec.Decode(&obj2)
-		c.swallow(&err)
-		return
-	}
-	return c.dec.Decode(obj)
-}
-
-func (c *rpcCodec) isClosed() (b bool) {
-	if c.c != nil {
-		c.clsmu.RLock()
-		b = c.cls
-		c.clsmu.RUnlock()
-	}
-	return
-}
-
-func (c *rpcCodec) Close() error {
-	if c.c == nil || c.isClosed() {
-		return c.clsErr
-	}
-	c.clsmu.Lock()
-	c.cls = true
-	c.clsErr = c.c.Close()
-	c.clsmu.Unlock()
-	return c.clsErr
-}
-
-func (c *rpcCodec) ReadResponseBody(body interface{}) error {
-	return c.read(body)
-}
-
-// -------------------------------------
-
-type goRpcCodec struct {
-	rpcCodec
-}
-
-func (c *goRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
-	// Must protect for concurrent access as per API
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	return c.write(r, body, true)
-}
-
-func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	return c.write(r, body, true)
-}
-
-func (c *goRpcCodec) ReadResponseHeader(r *rpc.Response) error {
-	return c.read(r)
-}
-
-func (c *goRpcCodec) ReadRequestHeader(r *rpc.Request) error {
-	return c.read(r)
-}
-
-func (c *goRpcCodec) ReadRequestBody(body interface{}) error {
-	return c.read(body)
-}
-
-// -------------------------------------
-
-// goRpc is the implementation of Rpc that uses the communication protocol
-// as defined in net/rpc package.
-type goRpc struct{}
-
-// GoRpc implements Rpc using the communication protocol defined in net/rpc package.
-//
-// Note: network connection (from net.Dial, of type io.ReadWriteCloser) is not buffered.
-//
-// For performance, you should configure WriterBufferSize and ReaderBufferSize on the handle.
-// This ensures we use an adequate buffer during reading and writing.
-// If not configured, we will internally initialize and use a buffer during reads and writes.
-// This can be turned off via the RPCNoBuffer option on the Handle.
-//   var handle codec.JsonHandle
-//   handle.RPCNoBuffer = true // turns off attempt by rpc module to initialize a buffer
-//
-// Example 1: one way of configuring buffering explicitly:
-//   var handle codec.JsonHandle // codec handle
-//   handle.ReaderBufferSize = 1024
-//   handle.WriterBufferSize = 1024
-//   var conn io.ReadWriteCloser // connection got from a socket
-//   var serverCodec = GoRpc.ServerCodec(conn, handle)
-//   var clientCodec = GoRpc.ClientCodec(conn, handle)
-//
-// Example 2: you can also explicitly create a buffered connection yourself,
-// and not worry about configuring the buffer sizes in the Handle.
-//   var handle codec.Handle     // codec handle
-//   var conn io.ReadWriteCloser // connection got from a socket
-//   var bufconn = struct {      // bufconn here is a buffered io.ReadWriteCloser
-//       io.Closer
-//       *bufio.Reader
-//       *bufio.Writer
-//   }{conn, bufio.NewReader(conn), bufio.NewWriter(conn)}
-//   var serverCodec = GoRpc.ServerCodec(bufconn, handle)
-//   var clientCodec = GoRpc.ClientCodec(bufconn, handle)
-//
-var GoRpc goRpc
-
-func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
-	return &goRpcCodec{newRPCCodec(conn, h)}
-}
-
-func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
-	return &goRpcCodec{newRPCCodec(conn, h)}
-}
diff --git a/vendor/github.com/ugorji/go/codec/simple.go b/vendor/github.com/ugorji/go/codec/simple.go
deleted file mode 100644
index f1e181e..0000000
--- a/vendor/github.com/ugorji/go/codec/simple.go
+++ /dev/null
@@ -1,652 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-package codec
-
-import (
-	"math"
-	"reflect"
-	"time"
-)
-
-const (
-	_               uint8 = iota
-	simpleVdNil           = 1
-	simpleVdFalse         = 2
-	simpleVdTrue          = 3
-	simpleVdFloat32       = 4
-	simpleVdFloat64       = 5
-
-	// each lasts for 4 (ie n, n+1, n+2, n+3)
-	simpleVdPosInt = 8
-	simpleVdNegInt = 12
-
-	simpleVdTime = 24
-
-	// containers: each lasts for 4 (ie n, n+1, n+2, ... n+7)
-	simpleVdString    = 216
-	simpleVdByteArray = 224
-	simpleVdArray     = 232
-	simpleVdMap       = 240
-	simpleVdExt       = 248
-)
-
-type simpleEncDriver struct {
-	noBuiltInTypes
-	// encNoSeparator
-	e *Encoder
-	h *SimpleHandle
-	w encWriter
-	b [8]byte
-	// c containerState
-	encDriverTrackContainerWriter
-	// encDriverNoopContainerWriter
-	_ [2]uint64 // padding
-}
-
-func (e *simpleEncDriver) EncodeNil() {
-	e.w.writen1(simpleVdNil)
-}
-
-func (e *simpleEncDriver) EncodeBool(b bool) {
-	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && !b {
-		e.EncodeNil()
-		return
-	}
-	if b {
-		e.w.writen1(simpleVdTrue)
-	} else {
-		e.w.writen1(simpleVdFalse)
-	}
-}
-
-func (e *simpleEncDriver) EncodeFloat32(f float32) {
-	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
-		e.EncodeNil()
-		return
-	}
-	e.w.writen1(simpleVdFloat32)
-	bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f))
-}
-
-func (e *simpleEncDriver) EncodeFloat64(f float64) {
-	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
-		e.EncodeNil()
-		return
-	}
-	e.w.writen1(simpleVdFloat64)
-	bigenHelper{e.b[:8], e.w}.writeUint64(math.Float64bits(f))
-}
-
-func (e *simpleEncDriver) EncodeInt(v int64) {
-	if v < 0 {
-		e.encUint(uint64(-v), simpleVdNegInt)
-	} else {
-		e.encUint(uint64(v), simpleVdPosInt)
-	}
-}
-
-func (e *simpleEncDriver) EncodeUint(v uint64) {
-	e.encUint(v, simpleVdPosInt)
-}
-
-func (e *simpleEncDriver) encUint(v uint64, bd uint8) {
-	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == 0 {
-		e.EncodeNil()
-		return
-	}
-	if v <= math.MaxUint8 {
-		e.w.writen2(bd, uint8(v))
-	} else if v <= math.MaxUint16 {
-		e.w.writen1(bd + 1)
-		bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v))
-	} else if v <= math.MaxUint32 {
-		e.w.writen1(bd + 2)
-		bigenHelper{e.b[:4], e.w}.writeUint32(uint32(v))
-	} else { // if v <= math.MaxUint64 {
-		e.w.writen1(bd + 3)
-		bigenHelper{e.b[:8], e.w}.writeUint64(v)
-	}
-}
-
-func (e *simpleEncDriver) encLen(bd byte, length int) {
-	if length == 0 {
-		e.w.writen1(bd)
-	} else if length <= math.MaxUint8 {
-		e.w.writen1(bd + 1)
-		e.w.writen1(uint8(length))
-	} else if length <= math.MaxUint16 {
-		e.w.writen1(bd + 2)
-		bigenHelper{e.b[:2], e.w}.writeUint16(uint16(length))
-	} else if int64(length) <= math.MaxUint32 {
-		e.w.writen1(bd + 3)
-		bigenHelper{e.b[:4], e.w}.writeUint32(uint32(length))
-	} else {
-		e.w.writen1(bd + 4)
-		bigenHelper{e.b[:8], e.w}.writeUint64(uint64(length))
-	}
-}
-
-func (e *simpleEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, _ *Encoder) {
-	bs := ext.WriteExt(rv)
-	if bs == nil {
-		e.EncodeNil()
-		return
-	}
-	e.encodeExtPreamble(uint8(xtag), len(bs))
-	e.w.writeb(bs)
-}
-
-func (e *simpleEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) {
-	e.encodeExtPreamble(uint8(re.Tag), len(re.Data))
-	e.w.writeb(re.Data)
-}
-
-func (e *simpleEncDriver) encodeExtPreamble(xtag byte, length int) {
-	e.encLen(simpleVdExt, length)
-	e.w.writen1(xtag)
-}
-
-func (e *simpleEncDriver) WriteArrayStart(length int) {
-	e.c = containerArrayStart
-	e.encLen(simpleVdArray, length)
-}
-
-func (e *simpleEncDriver) WriteMapStart(length int) {
-	e.c = containerMapStart
-	e.encLen(simpleVdMap, length)
-}
-
-func (e *simpleEncDriver) EncodeString(c charEncoding, v string) {
-	if false && e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == "" {
-		e.EncodeNil()
-		return
-	}
-	e.encLen(simpleVdString, len(v))
-	e.w.writestr(v)
-}
-
-// func (e *simpleEncDriver) EncodeSymbol(v string) {
-// 	e.EncodeString(cUTF8, v)
-// }
-
-func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
-	// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == nil {
-	if v == nil {
-		e.EncodeNil()
-		return
-	}
-	e.encLen(simpleVdByteArray, len(v))
-	e.w.writeb(v)
-}
-
-func (e *simpleEncDriver) EncodeTime(t time.Time) {
-	// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && t.IsZero() {
-	if t.IsZero() {
-		e.EncodeNil()
-		return
-	}
-	v, err := t.MarshalBinary()
-	if err != nil {
-		e.e.errorv(err)
-		return
-	}
-	// time.Time marshalbinary takes about 14 bytes.
-	e.w.writen2(simpleVdTime, uint8(len(v)))
-	e.w.writeb(v)
-}
-
-//------------------------------------
-
-type simpleDecDriver struct {
-	d      *Decoder
-	h      *SimpleHandle
-	r      decReader
-	bdRead bool
-	bd     byte
-	br     bool // a bytes reader?
-	c      containerState
-	// b      [scratchByteArrayLen]byte
-	noBuiltInTypes
-	// noStreamingCodec
-	decDriverNoopContainerReader
-	_ [3]uint64 // padding
-}
-
-func (d *simpleDecDriver) readNextBd() {
-	d.bd = d.r.readn1()
-	d.bdRead = true
-}
-
-func (d *simpleDecDriver) uncacheRead() {
-	if d.bdRead {
-		d.r.unreadn1()
-		d.bdRead = false
-	}
-}
-
-func (d *simpleDecDriver) ContainerType() (vt valueType) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	switch d.bd {
-	case simpleVdNil:
-		return valueTypeNil
-	case simpleVdByteArray, simpleVdByteArray + 1,
-		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
-		return valueTypeBytes
-	case simpleVdString, simpleVdString + 1,
-		simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
-		return valueTypeString
-	case simpleVdArray, simpleVdArray + 1,
-		simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4:
-		return valueTypeArray
-	case simpleVdMap, simpleVdMap + 1,
-		simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
-		return valueTypeMap
-		// case simpleVdTime:
-		// 	return valueTypeTime
-	}
-	// else {
-	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
-	// }
-	return valueTypeUnset
-}
-
-func (d *simpleDecDriver) TryDecodeAsNil() bool {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == simpleVdNil {
-		d.bdRead = false
-		return true
-	}
-	return false
-}
-
-func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	switch d.bd {
-	case simpleVdPosInt:
-		ui = uint64(d.r.readn1())
-	case simpleVdPosInt + 1:
-		ui = uint64(bigen.Uint16(d.r.readx(2)))
-	case simpleVdPosInt + 2:
-		ui = uint64(bigen.Uint32(d.r.readx(4)))
-	case simpleVdPosInt + 3:
-		ui = uint64(bigen.Uint64(d.r.readx(8)))
-	case simpleVdNegInt:
-		ui = uint64(d.r.readn1())
-		neg = true
-	case simpleVdNegInt + 1:
-		ui = uint64(bigen.Uint16(d.r.readx(2)))
-		neg = true
-	case simpleVdNegInt + 2:
-		ui = uint64(bigen.Uint32(d.r.readx(4)))
-		neg = true
-	case simpleVdNegInt + 3:
-		ui = uint64(bigen.Uint64(d.r.readx(8)))
-		neg = true
-	default:
-		d.d.errorf("integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd)
-		return
-	}
-	// don't do this check, because callers may only want the unsigned value.
-	// if ui > math.MaxInt64 {
-	// 	d.d.errorf("decIntAny: Integer out of range for signed int64: %v", ui)
-	//		return
-	// }
-	return
-}
-
-func (d *simpleDecDriver) DecodeInt64() (i int64) {
-	ui, neg := d.decCheckInteger()
-	i = chkOvf.SignedIntV(ui)
-	if neg {
-		i = -i
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *simpleDecDriver) DecodeUint64() (ui uint64) {
-	ui, neg := d.decCheckInteger()
-	if neg {
-		d.d.errorf("assigning negative signed value to unsigned type")
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *simpleDecDriver) DecodeFloat64() (f float64) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == simpleVdFloat32 {
-		f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
-	} else if d.bd == simpleVdFloat64 {
-		f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
-	} else {
-		if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 {
-			f = float64(d.DecodeInt64())
-		} else {
-			d.d.errorf("float only valid from float32/64: Invalid descriptor: %v", d.bd)
-			return
-		}
-	}
-	d.bdRead = false
-	return
-}
-
-// bool can be decoded from bool only (single byte).
-func (d *simpleDecDriver) DecodeBool() (b bool) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == simpleVdTrue {
-		b = true
-	} else if d.bd == simpleVdFalse {
-	} else {
-		d.d.errorf("cannot decode bool - %s: %x", msgBadDesc, d.bd)
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *simpleDecDriver) ReadMapStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	d.bdRead = false
-	d.c = containerMapStart
-	return d.decLen()
-}
-
-func (d *simpleDecDriver) ReadArrayStart() (length int) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	d.bdRead = false
-	d.c = containerArrayStart
-	return d.decLen()
-}
-
-func (d *simpleDecDriver) ReadArrayElem() {
-	d.c = containerArrayElem
-}
-
-func (d *simpleDecDriver) ReadArrayEnd() {
-	d.c = containerArrayEnd
-}
-
-func (d *simpleDecDriver) ReadMapElemKey() {
-	d.c = containerMapKey
-}
-
-func (d *simpleDecDriver) ReadMapElemValue() {
-	d.c = containerMapValue
-}
-
-func (d *simpleDecDriver) ReadMapEnd() {
-	d.c = containerMapEnd
-}
-
-func (d *simpleDecDriver) decLen() int {
-	switch d.bd % 8 {
-	case 0:
-		return 0
-	case 1:
-		return int(d.r.readn1())
-	case 2:
-		return int(bigen.Uint16(d.r.readx(2)))
-	case 3:
-		ui := uint64(bigen.Uint32(d.r.readx(4)))
-		if chkOvf.Uint(ui, intBitsize) {
-			d.d.errorf("overflow integer: %v", ui)
-			return 0
-		}
-		return int(ui)
-	case 4:
-		ui := bigen.Uint64(d.r.readx(8))
-		if chkOvf.Uint(ui, intBitsize) {
-			d.d.errorf("overflow integer: %v", ui)
-			return 0
-		}
-		return int(ui)
-	}
-	d.d.errorf("cannot read length: bd%%8 must be in range 0..4. Got: %d", d.bd%8)
-	return -1
-}
-
-func (d *simpleDecDriver) DecodeString() (s string) {
-	return string(d.DecodeBytes(d.d.b[:], true))
-}
-
-func (d *simpleDecDriver) DecodeStringAsBytes() (s []byte) {
-	return d.DecodeBytes(d.d.b[:], true)
-}
-
-func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == simpleVdNil {
-		d.bdRead = false
-		return
-	}
-	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
-	if d.bd >= simpleVdArray && d.bd <= simpleVdMap+4 {
-		if len(bs) == 0 && zerocopy {
-			bs = d.d.b[:]
-		}
-		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
-		return
-	}
-
-	clen := d.decLen()
-	d.bdRead = false
-	if zerocopy {
-		if d.br {
-			return d.r.readx(clen)
-		} else if len(bs) == 0 {
-			bs = d.d.b[:]
-		}
-	}
-	return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
-}
-
-func (d *simpleDecDriver) DecodeTime() (t time.Time) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	if d.bd == simpleVdNil {
-		d.bdRead = false
-		return
-	}
-	if d.bd != simpleVdTime {
-		d.d.errorf("invalid descriptor for time.Time - expect 0x%x, received 0x%x", simpleVdTime, d.bd)
-		return
-	}
-	d.bdRead = false
-	clen := int(d.r.readn1())
-	b := d.r.readx(clen)
-	if err := (&t).UnmarshalBinary(b); err != nil {
-		d.d.errorv(err)
-	}
-	return
-}
-
-func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
-	if xtag > 0xff {
-		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
-		return
-	}
-	realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
-	realxtag = uint64(realxtag1)
-	if ext == nil {
-		re := rv.(*RawExt)
-		re.Tag = realxtag
-		re.Data = detachZeroCopyBytes(d.br, re.Data, xbs)
-	} else {
-		ext.ReadExt(rv, xbs)
-	}
-	return
-}
-
-func (d *simpleDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-	switch d.bd {
-	case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
-		l := d.decLen()
-		xtag = d.r.readn1()
-		if verifyTag && xtag != tag {
-			d.d.errorf("wrong extension tag. Got %b. Expecting: %v", xtag, tag)
-			return
-		}
-		xbs = d.r.readx(l)
-	case simpleVdByteArray, simpleVdByteArray + 1,
-		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
-		xbs = d.DecodeBytes(nil, true)
-	default:
-		d.d.errorf("ext - %s - expecting extensions/bytearray, got: 0x%x", msgBadDesc, d.bd)
-		return
-	}
-	d.bdRead = false
-	return
-}
-
-func (d *simpleDecDriver) DecodeNaked() {
-	if !d.bdRead {
-		d.readNextBd()
-	}
-
-	n := d.d.n
-	var decodeFurther bool
-
-	switch d.bd {
-	case simpleVdNil:
-		n.v = valueTypeNil
-	case simpleVdFalse:
-		n.v = valueTypeBool
-		n.b = false
-	case simpleVdTrue:
-		n.v = valueTypeBool
-		n.b = true
-	case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3:
-		if d.h.SignedInteger {
-			n.v = valueTypeInt
-			n.i = d.DecodeInt64()
-		} else {
-			n.v = valueTypeUint
-			n.u = d.DecodeUint64()
-		}
-	case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3:
-		n.v = valueTypeInt
-		n.i = d.DecodeInt64()
-	case simpleVdFloat32:
-		n.v = valueTypeFloat
-		n.f = d.DecodeFloat64()
-	case simpleVdFloat64:
-		n.v = valueTypeFloat
-		n.f = d.DecodeFloat64()
-	case simpleVdTime:
-		n.v = valueTypeTime
-		n.t = d.DecodeTime()
-	case simpleVdString, simpleVdString + 1,
-		simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
-		n.v = valueTypeString
-		n.s = d.DecodeString()
-	case simpleVdByteArray, simpleVdByteArray + 1,
-		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
-		n.v = valueTypeBytes
-		n.l = d.DecodeBytes(nil, false)
-	case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
-		n.v = valueTypeExt
-		l := d.decLen()
-		n.u = uint64(d.r.readn1())
-		n.l = d.r.readx(l)
-	case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2,
-		simpleVdArray + 3, simpleVdArray + 4:
-		n.v = valueTypeArray
-		decodeFurther = true
-	case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
-		n.v = valueTypeMap
-		decodeFurther = true
-	default:
-		d.d.errorf("cannot infer value - %s 0x%x", msgBadDesc, d.bd)
-	}
-
-	if !decodeFurther {
-		d.bdRead = false
-	}
-	return
-}
-
-//------------------------------------
-
-// SimpleHandle is a Handle for a very simple encoding format.
-//
-// simple is a simplistic codec similar to binc, but not as compact.
-//   - Encoding of a value is always preceded by the descriptor byte (bd)
-//   - True, false, nil are encoded fully in 1 byte (the descriptor)
-//   - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte).
-//     There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers.
-//   - Floats are encoded in 4 or 8 bytes (plus a descriptor byte)
-//   - Length of containers (strings, bytes, array, map, extensions)
-//     are encoded in 0, 1, 2, 4 or 8 bytes.
-//     Zero-length containers have no length encoded.
-//     For others, the number of bytes is given by pow(2, bd%3)
-//   - maps are encoded as [bd] [length] [[key][value]]...
-//   - arrays are encoded as [bd] [length] [value]...
-//   - extensions are encoded as [bd] [length] [tag] [byte]...
-//   - strings/bytearrays are encoded as [bd] [length] [byte]...
-//   - time.Time are encoded as [bd] [length] [byte]...
-//
-// The full spec will be published soon.
-type SimpleHandle struct {
-	BasicHandle
-	binaryEncodingType
-	noElemSeparators
-	// EncZeroValuesAsNil says to encode zero values for numbers, bool, string, etc as nil
-	EncZeroValuesAsNil bool
-
-	// _ [1]uint64 // padding
-}
-
-// Name returns the name of the handle: simple
-func (h *SimpleHandle) Name() string { return "simple" }
-
-// SetBytesExt sets an extension
-func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
-}
-
-func (h *SimpleHandle) hasElemSeparators() bool { return true } // as it implements Write(Map|Array)XXX
-
-func (h *SimpleHandle) newEncDriver(e *Encoder) encDriver {
-	return &simpleEncDriver{e: e, w: e.w, h: h}
-}
-
-func (h *SimpleHandle) newDecDriver(d *Decoder) decDriver {
-	return &simpleDecDriver{d: d, h: h, r: d.r, br: d.bytes}
-}
-
-func (e *simpleEncDriver) reset() {
-	e.c = 0
-	e.w = e.e.w
-}
-
-func (d *simpleDecDriver) reset() {
-	d.c = 0
-	d.r, d.br = d.d.r, d.d.bytes
-	d.bd, d.bdRead = 0, false
-}
-
-var _ decDriver = (*simpleDecDriver)(nil)
-var _ encDriver = (*simpleEncDriver)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/test-cbor-goldens.json b/vendor/github.com/ugorji/go/codec/test-cbor-goldens.json
deleted file mode 100644
index 9028586..0000000
--- a/vendor/github.com/ugorji/go/codec/test-cbor-goldens.json
+++ /dev/null
@@ -1,639 +0,0 @@
-[
-  {
-    "cbor": "AA==",
-    "hex": "00",
-    "roundtrip": true,
-    "decoded": 0
-  },
-  {
-    "cbor": "AQ==",
-    "hex": "01",
-    "roundtrip": true,
-    "decoded": 1
-  },
-  {
-    "cbor": "Cg==",
-    "hex": "0a",
-    "roundtrip": true,
-    "decoded": 10
-  },
-  {
-    "cbor": "Fw==",
-    "hex": "17",
-    "roundtrip": true,
-    "decoded": 23
-  },
-  {
-    "cbor": "GBg=",
-    "hex": "1818",
-    "roundtrip": true,
-    "decoded": 24
-  },
-  {
-    "cbor": "GBk=",
-    "hex": "1819",
-    "roundtrip": true,
-    "decoded": 25
-  },
-  {
-    "cbor": "GGQ=",
-    "hex": "1864",
-    "roundtrip": true,
-    "decoded": 100
-  },
-  {
-    "cbor": "GQPo",
-    "hex": "1903e8",
-    "roundtrip": true,
-    "decoded": 1000
-  },
-  {
-    "cbor": "GgAPQkA=",
-    "hex": "1a000f4240",
-    "roundtrip": true,
-    "decoded": 1000000
-  },
-  {
-    "cbor": "GwAAAOjUpRAA",
-    "hex": "1b000000e8d4a51000",
-    "roundtrip": true,
-    "decoded": 1000000000000
-  },
-  {
-    "cbor": "G///////////",
-    "hex": "1bffffffffffffffff",
-    "roundtrip": true,
-    "decoded": 18446744073709551615
-  },
-  {
-    "cbor": "wkkBAAAAAAAAAAA=",
-    "hex": "c249010000000000000000",
-    "roundtrip": true,
-    "decoded": 18446744073709551616
-  },
-  {
-    "cbor": "O///////////",
-    "hex": "3bffffffffffffffff",
-    "roundtrip": true,
-    "decoded": -18446744073709551616,
-    "skip": true
-  },
-  {
-    "cbor": "w0kBAAAAAAAAAAA=",
-    "hex": "c349010000000000000000",
-    "roundtrip": true,
-    "decoded": -18446744073709551617
-  },
-  {
-    "cbor": "IA==",
-    "hex": "20",
-    "roundtrip": true,
-    "decoded": -1
-  },
-  {
-    "cbor": "KQ==",
-    "hex": "29",
-    "roundtrip": true,
-    "decoded": -10
-  },
-  {
-    "cbor": "OGM=",
-    "hex": "3863",
-    "roundtrip": true,
-    "decoded": -100
-  },
-  {
-    "cbor": "OQPn",
-    "hex": "3903e7",
-    "roundtrip": true,
-    "decoded": -1000
-  },
-  {
-    "cbor": "+QAA",
-    "hex": "f90000",
-    "roundtrip": true,
-    "decoded": 0.0
-  },
-  {
-    "cbor": "+YAA",
-    "hex": "f98000",
-    "roundtrip": true,
-    "decoded": -0.0
-  },
-  {
-    "cbor": "+TwA",
-    "hex": "f93c00",
-    "roundtrip": true,
-    "decoded": 1.0
-  },
-  {
-    "cbor": "+z/xmZmZmZma",
-    "hex": "fb3ff199999999999a",
-    "roundtrip": true,
-    "decoded": 1.1
-  },
-  {
-    "cbor": "+T4A",
-    "hex": "f93e00",
-    "roundtrip": true,
-    "decoded": 1.5
-  },
-  {
-    "cbor": "+Xv/",
-    "hex": "f97bff",
-    "roundtrip": true,
-    "decoded": 65504.0
-  },
-  {
-    "cbor": "+kfDUAA=",
-    "hex": "fa47c35000",
-    "roundtrip": true,
-    "decoded": 100000.0
-  },
-  {
-    "cbor": "+n9///8=",
-    "hex": "fa7f7fffff",
-    "roundtrip": true,
-    "decoded": 3.4028234663852886e+38
-  },
-  {
-    "cbor": "+3435DyIAHWc",
-    "hex": "fb7e37e43c8800759c",
-    "roundtrip": true,
-    "decoded": 1.0e+300
-  },
-  {
-    "cbor": "+QAB",
-    "hex": "f90001",
-    "roundtrip": true,
-    "decoded": 5.960464477539063e-08
-  },
-  {
-    "cbor": "+QQA",
-    "hex": "f90400",
-    "roundtrip": true,
-    "decoded": 6.103515625e-05
-  },
-  {
-    "cbor": "+cQA",
-    "hex": "f9c400",
-    "roundtrip": true,
-    "decoded": -4.0
-  },
-  {
-    "cbor": "+8AQZmZmZmZm",
-    "hex": "fbc010666666666666",
-    "roundtrip": true,
-    "decoded": -4.1
-  },
-  {
-    "cbor": "+XwA",
-    "hex": "f97c00",
-    "roundtrip": true,
-    "diagnostic": "Infinity"
-  },
-  {
-    "cbor": "+X4A",
-    "hex": "f97e00",
-    "roundtrip": true,
-    "diagnostic": "NaN"
-  },
-  {
-    "cbor": "+fwA",
-    "hex": "f9fc00",
-    "roundtrip": true,
-    "diagnostic": "-Infinity"
-  },
-  {
-    "cbor": "+n+AAAA=",
-    "hex": "fa7f800000",
-    "roundtrip": false,
-    "diagnostic": "Infinity"
-  },
-  {
-    "cbor": "+n/AAAA=",
-    "hex": "fa7fc00000",
-    "roundtrip": false,
-    "diagnostic": "NaN"
-  },
-  {
-    "cbor": "+v+AAAA=",
-    "hex": "faff800000",
-    "roundtrip": false,
-    "diagnostic": "-Infinity"
-  },
-  {
-    "cbor": "+3/wAAAAAAAA",
-    "hex": "fb7ff0000000000000",
-    "roundtrip": false,
-    "diagnostic": "Infinity"
-  },
-  {
-    "cbor": "+3/4AAAAAAAA",
-    "hex": "fb7ff8000000000000",
-    "roundtrip": false,
-    "diagnostic": "NaN"
-  },
-  {
-    "cbor": "+//wAAAAAAAA",
-    "hex": "fbfff0000000000000",
-    "roundtrip": false,
-    "diagnostic": "-Infinity"
-  },
-  {
-    "cbor": "9A==",
-    "hex": "f4",
-    "roundtrip": true,
-    "decoded": false
-  },
-  {
-    "cbor": "9Q==",
-    "hex": "f5",
-    "roundtrip": true,
-    "decoded": true
-  },
-  {
-    "cbor": "9g==",
-    "hex": "f6",
-    "roundtrip": true,
-    "decoded": null
-  },
-  {
-    "cbor": "9w==",
-    "hex": "f7",
-    "roundtrip": true,
-    "diagnostic": "undefined"
-  },
-  {
-    "cbor": "8A==",
-    "hex": "f0",
-    "roundtrip": true,
-    "diagnostic": "simple(16)"
-  },
-  {
-    "cbor": "+Bg=",
-    "hex": "f818",
-    "roundtrip": true,
-    "diagnostic": "simple(24)"
-  },
-  {
-    "cbor": "+P8=",
-    "hex": "f8ff",
-    "roundtrip": true,
-    "diagnostic": "simple(255)"
-  },
-  {
-    "cbor": "wHQyMDEzLTAzLTIxVDIwOjA0OjAwWg==",
-    "hex": "c074323031332d30332d32315432303a30343a30305a",
-    "roundtrip": true,
-    "diagnostic": "0(\"2013-03-21T20:04:00Z\")"
-  },
-  {
-    "cbor": "wRpRS2ew",
-    "hex": "c11a514b67b0",
-    "roundtrip": true,
-    "diagnostic": "1(1363896240)"
-  },
-  {
-    "cbor": "wftB1FLZ7CAAAA==",
-    "hex": "c1fb41d452d9ec200000",
-    "roundtrip": true,
-    "diagnostic": "1(1363896240.5)"
-  },
-  {
-    "cbor": "10QBAgME",
-    "hex": "d74401020304",
-    "roundtrip": true,
-    "diagnostic": "23(h'01020304')"
-  },
-  {
-    "cbor": "2BhFZElFVEY=",
-    "hex": "d818456449455446",
-    "roundtrip": true,
-    "diagnostic": "24(h'6449455446')"
-  },
-  {
-    "cbor": "2CB2aHR0cDovL3d3dy5leGFtcGxlLmNvbQ==",
-    "hex": "d82076687474703a2f2f7777772e6578616d706c652e636f6d",
-    "roundtrip": true,
-    "diagnostic": "32(\"http://www.example.com\")"
-  },
-  {
-    "cbor": "QA==",
-    "hex": "40",
-    "roundtrip": true,
-    "diagnostic": "h''"
-  },
-  {
-    "cbor": "RAECAwQ=",
-    "hex": "4401020304",
-    "roundtrip": true,
-    "diagnostic": "h'01020304'"
-  },
-  {
-    "cbor": "YA==",
-    "hex": "60",
-    "roundtrip": true,
-    "decoded": ""
-  },
-  {
-    "cbor": "YWE=",
-    "hex": "6161",
-    "roundtrip": true,
-    "decoded": "a"
-  },
-  {
-    "cbor": "ZElFVEY=",
-    "hex": "6449455446",
-    "roundtrip": true,
-    "decoded": "IETF"
-  },
-  {
-    "cbor": "YiJc",
-    "hex": "62225c",
-    "roundtrip": true,
-    "decoded": "\"\\"
-  },
-  {
-    "cbor": "YsO8",
-    "hex": "62c3bc",
-    "roundtrip": true,
-    "decoded": "ü"
-  },
-  {
-    "cbor": "Y+awtA==",
-    "hex": "63e6b0b4",
-    "roundtrip": true,
-    "decoded": "水"
-  },
-  {
-    "cbor": "ZPCQhZE=",
-    "hex": "64f0908591",
-    "roundtrip": true,
-    "decoded": "𐅑"
-  },
-  {
-    "cbor": "gA==",
-    "hex": "80",
-    "roundtrip": true,
-    "decoded": [
-
-    ]
-  },
-  {
-    "cbor": "gwECAw==",
-    "hex": "83010203",
-    "roundtrip": true,
-    "decoded": [
-      1,
-      2,
-      3
-    ]
-  },
-  {
-    "cbor": "gwGCAgOCBAU=",
-    "hex": "8301820203820405",
-    "roundtrip": true,
-    "decoded": [
-      1,
-      [
-        2,
-        3
-      ],
-      [
-        4,
-        5
-      ]
-    ]
-  },
-  {
-    "cbor": "mBkBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgYGBk=",
-    "hex": "98190102030405060708090a0b0c0d0e0f101112131415161718181819",
-    "roundtrip": true,
-    "decoded": [
-      1,
-      2,
-      3,
-      4,
-      5,
-      6,
-      7,
-      8,
-      9,
-      10,
-      11,
-      12,
-      13,
-      14,
-      15,
-      16,
-      17,
-      18,
-      19,
-      20,
-      21,
-      22,
-      23,
-      24,
-      25
-    ]
-  },
-  {
-    "cbor": "oA==",
-    "hex": "a0",
-    "roundtrip": true,
-    "decoded": {
-    }
-  },
-  {
-    "cbor": "ogECAwQ=",
-    "hex": "a201020304",
-    "roundtrip": true,
-    "skip": true,
-    "diagnostic": "{1: 2, 3: 4}"
-  },
-  {
-    "cbor": "omFhAWFiggID",
-    "hex": "a26161016162820203",
-    "roundtrip": true,
-    "decoded": {
-      "a": 1,
-      "b": [
-        2,
-        3
-      ]
-    }
-  },
-  {
-    "cbor": "gmFhoWFiYWM=",
-    "hex": "826161a161626163",
-    "roundtrip": true,
-    "decoded": [
-      "a",
-      {
-        "b": "c"
-      }
-    ]
-  },
-  {
-    "cbor": "pWFhYUFhYmFCYWNhQ2FkYURhZWFF",
-    "hex": "a56161614161626142616361436164614461656145",
-    "roundtrip": true,
-    "decoded": {
-      "a": "A",
-      "b": "B",
-      "c": "C",
-      "d": "D",
-      "e": "E"
-    }
-  },
-  {
-    "cbor": "X0IBAkMDBAX/",
-    "hex": "5f42010243030405ff",
-    "roundtrip": false,
-    "skip": true,
-    "diagnostic": "(_ h'0102', h'030405')"
-  },
-  {
-    "cbor": "f2VzdHJlYWRtaW5n/w==",
-    "hex": "7f657374726561646d696e67ff",
-    "roundtrip": false,
-    "decoded": "streaming"
-  },
-  {
-    "cbor": "n/8=",
-    "hex": "9fff",
-    "roundtrip": false,
-    "decoded": [
-
-    ]
-  },
-  {
-    "cbor": "nwGCAgOfBAX//w==",
-    "hex": "9f018202039f0405ffff",
-    "roundtrip": false,
-    "decoded": [
-      1,
-      [
-        2,
-        3
-      ],
-      [
-        4,
-        5
-      ]
-    ]
-  },
-  {
-    "cbor": "nwGCAgOCBAX/",
-    "hex": "9f01820203820405ff",
-    "roundtrip": false,
-    "decoded": [
-      1,
-      [
-        2,
-        3
-      ],
-      [
-        4,
-        5
-      ]
-    ]
-  },
-  {
-    "cbor": "gwGCAgOfBAX/",
-    "hex": "83018202039f0405ff",
-    "roundtrip": false,
-    "decoded": [
-      1,
-      [
-        2,
-        3
-      ],
-      [
-        4,
-        5
-      ]
-    ]
-  },
-  {
-    "cbor": "gwGfAgP/ggQF",
-    "hex": "83019f0203ff820405",
-    "roundtrip": false,
-    "decoded": [
-      1,
-      [
-        2,
-        3
-      ],
-      [
-        4,
-        5
-      ]
-    ]
-  },
-  {
-    "cbor": "nwECAwQFBgcICQoLDA0ODxAREhMUFRYXGBgYGf8=",
-    "hex": "9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff",
-    "roundtrip": false,
-    "decoded": [
-      1,
-      2,
-      3,
-      4,
-      5,
-      6,
-      7,
-      8,
-      9,
-      10,
-      11,
-      12,
-      13,
-      14,
-      15,
-      16,
-      17,
-      18,
-      19,
-      20,
-      21,
-      22,
-      23,
-      24,
-      25
-    ]
-  },
-  {
-    "cbor": "v2FhAWFinwID//8=",
-    "hex": "bf61610161629f0203ffff",
-    "roundtrip": false,
-    "decoded": {
-      "a": 1,
-      "b": [
-        2,
-        3
-      ]
-    }
-  },
-  {
-    "cbor": "gmFhv2FiYWP/",
-    "hex": "826161bf61626163ff",
-    "roundtrip": false,
-    "decoded": [
-      "a",
-      {
-        "b": "c"
-      }
-    ]
-  },
-  {
-    "cbor": "v2NGdW71Y0FtdCH/",
-    "hex": "bf6346756ef563416d7421ff",
-    "roundtrip": false,
-    "decoded": {
-      "Fun": true,
-      "Amt": -2
-    }
-  }
-]
diff --git a/vendor/github.com/ugorji/go/codec/test.py b/vendor/github.com/ugorji/go/codec/test.py
deleted file mode 100755
index 800376f..0000000
--- a/vendor/github.com/ugorji/go/codec/test.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env python
-
-# This will create golden files in a directory passed to it.
-# A Test calls this internally to create the golden files
-# So it can process them (so we don't have to checkin the files).
-
-# Ensure msgpack-python and cbor are installed first, using:
-#   sudo apt-get install python-dev
-#   sudo apt-get install python-pip
-#   pip install --user msgpack-python msgpack-rpc-python cbor
-
-# Ensure all "string" keys are utf strings (else encoded as bytes)
-
-import cbor, msgpack, msgpackrpc, sys, os, threading
-
-def get_test_data_list():
-    # get list with all primitive types, and a combo type
-    l0 = [ 
-        -8,
-         -1616,
-         -32323232,
-         -6464646464646464,
-         192,
-         1616,
-         32323232,
-         6464646464646464,
-         192,
-         -3232.0,
-         -6464646464.0,
-         3232.0,
-         6464.0,
-         6464646464.0,
-         False,
-         True,
-         u"null",
-         None,
-         u"some&day>some<day",
-         1328176922000002000,
-         u"",
-         -2206187877999998000,
-         u"bytestring",
-         270,
-         u"none",
-        -2013855847999995777,
-         #-6795364578871345152,
-         ]
-    l1 = [
-        { "true": True,
-          "false": False },
-        { "true": u"True",
-          "false": False,
-          "uint16(1616)": 1616 },
-        { "list": [1616, 32323232, True, -3232.0, {"TRUE":True, "FALSE":False}, [True, False] ],
-          "int32":32323232, "bool": True, 
-          "LONG STRING": u"123456789012345678901234567890123456789012345678901234567890",
-          "SHORT STRING": u"1234567890" },
-        { True: "true", 138: False, "false": 200 }
-        ]
-    
-    l = []
-    l.extend(l0)
-    l.append(l0)
-    l.append(1)
-    l.extend(l1)
-    return l
-
-def build_test_data(destdir):
-    l = get_test_data_list()
-    for i in range(len(l)):
-        # packer = msgpack.Packer()
-        serialized = msgpack.dumps(l[i])
-        f = open(os.path.join(destdir, str(i) + '.msgpack.golden'), 'wb')
-        f.write(serialized)
-        f.close()
-        serialized = cbor.dumps(l[i])
-        f = open(os.path.join(destdir, str(i) + '.cbor.golden'), 'wb')
-        f.write(serialized)
-        f.close()
-
-def doRpcServer(port, stopTimeSec):
-    class EchoHandler(object):
-        def Echo123(self, msg1, msg2, msg3):
-            return ("1:%s 2:%s 3:%s" % (msg1, msg2, msg3))
-        def EchoStruct(self, msg):
-            return ("%s" % msg)
-    
-    addr = msgpackrpc.Address('127.0.0.1', port)
-    server = msgpackrpc.Server(EchoHandler())
-    server.listen(addr)
-    # run thread to stop it after stopTimeSec seconds if > 0
-    if stopTimeSec > 0:
-        def myStopRpcServer():
-            server.stop()
-        t = threading.Timer(stopTimeSec, myStopRpcServer)
-        t.start()
-    server.start()
-
-def doRpcClientToPythonSvc(port):
-    address = msgpackrpc.Address('127.0.0.1', port)
-    client = msgpackrpc.Client(address, unpack_encoding='utf-8')
-    print client.call("Echo123", "A1", "B2", "C3")
-    print client.call("EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"})
-   
-def doRpcClientToGoSvc(port):
-    # print ">>>> port: ", port, " <<<<<"
-    address = msgpackrpc.Address('127.0.0.1', port)
-    client = msgpackrpc.Client(address, unpack_encoding='utf-8')
-    print client.call("TestRpcInt.Echo123", ["A1", "B2", "C3"])
-    print client.call("TestRpcInt.EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"})
-
-def doMain(args):
-    if len(args) == 2 and args[0] == "testdata":
-        build_test_data(args[1])
-    elif len(args) == 3 and args[0] == "rpc-server":
-        doRpcServer(int(args[1]), int(args[2]))
-    elif len(args) == 2 and args[0] == "rpc-client-python-service":
-        doRpcClientToPythonSvc(int(args[1]))
-    elif len(args) == 2 and args[0] == "rpc-client-go-service":
-        doRpcClientToGoSvc(int(args[1]))
-    else:
-        print("Usage: test.py " + 
-              "[testdata|rpc-server|rpc-client-python-service|rpc-client-go-service] ...")
-    
-if __name__ == "__main__":
-    doMain(sys.argv[1:])
-
diff --git a/vendor/github.com/ugorji/go/codec/xml.go b/vendor/github.com/ugorji/go/codec/xml.go
deleted file mode 100644
index 19fc36c..0000000
--- a/vendor/github.com/ugorji/go/codec/xml.go
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
-// Use of this source code is governed by a MIT license found in the LICENSE file.
-
-// +build ignore
-
-package codec
-
-import "reflect"
-
-/*
-
-A strict Non-validating namespace-aware XML 1.0 parser and (en|de)coder.
-
-We are attempting this due to perceived issues with encoding/xml:
-  - Complicated. It tried to do too much, and is not as simple to use as json.
-  - Due to over-engineering, reflection is over-used AND performance suffers:
-    java is 6X faster:http://fabsk.eu/blog/category/informatique/dev/golang/
-    even PYTHON performs better: http://outgoing.typepad.com/outgoing/2014/07/exploring-golang.html
-
-codec framework will offer the following benefits
-  - VASTLY improved performance (when using reflection-mode or codecgen)
-  - simplicity and consistency: with the rest of the supported formats
-  - all other benefits of codec framework (streaming, codegeneration, etc)
-
-codec is not a drop-in replacement for encoding/xml.
-It is a replacement, based on the simplicity and performance of codec.
-Look at it like JAXB for Go.
-
-Challenges:
-  - Need to output XML preamble, with all namespaces at the right location in the output.
-  - Each "end" block is dynamic, so we need to maintain a context-aware stack
-  - How to decide when to use an attribute VS an element
-  - How to handle chardata, attr, comment EXPLICITLY.
-  - Should it output fragments?
-    e.g. encoding a bool should just output true OR false, which is not well-formed XML.
-
-Extend the struct tag. See representative example:
-  type X struct {
-    ID uint8 `codec:"http://ugorji.net/x-namespace xid id,omitempty,toarray,attr,cdata"`
-    // format: [namespace-uri ][namespace-prefix ]local-name, ...
-  }
-
-Based on this, we encode
-  - fields as elements, BUT
-    encode as attributes if struct tag contains ",attr" and is a scalar (bool, number or string)
-  - text as entity-escaped text, BUT encode as CDATA if struct tag contains ",cdata".
-
-To handle namespaces:
-  - XMLHandle is denoted as being namespace-aware.
-    Consequently, we WILL use the ns:name pair to encode and decode if defined, else use the plain name.
-  - *Encoder and *Decoder know whether the Handle "prefers" namespaces.
-  - add *Encoder.getEncName(*structFieldInfo).
-    No one calls *structFieldInfo.indexForEncName directly anymore
-  - OR better yet: indexForEncName is namespace-aware, and helper.go is all namespace-aware
-    indexForEncName takes a parameter of the form namespace:local-name OR local-name
-  - add *Decoder.getStructFieldInfo(encName string) // encName here is either like abc, or h1:nsabc
-    by being a method on *Decoder, or maybe a method on the Handle itself.
-    No one accesses .encName anymore
-  - let encode.go and decode.go use these (for consistency)
-  - only problem exists for gen.go, where we create a big switch on encName.
-    Now, we also have to add a switch on strings.endsWith(kName, encNsName)
-    - gen.go will need to have many more methods, and then double-on the 2 switch loops like:
-      switch k {
-        case "abc" : x.abc()
-        case "def" : x.def()
-        default {
-          switch {
-            case !nsAware: panic(...)
-            case strings.endsWith(":abc"): x.abc()
-            case strings.endsWith(":def"): x.def()
-            default: panic(...)
-          }
-        }
-     }
-
-The structure below accommodates this:
-
-  type typeInfo struct {
-    sfi []*structFieldInfo // sorted by encName
-    sfins // sorted by namespace
-    sfia  // sorted, to have those with attributes at the top. Needed to write XML appropriately.
-    sfip  // unsorted
-  }
-  type structFieldInfo struct {
-    encName
-    nsEncName
-    ns string
-    attr bool
-    cdata bool
-  }
-
-indexForEncName is now an internal helper function that takes a sorted array
-(one of ti.sfins or ti.sfi). It is only used by *Encoder.getStructFieldInfo(...)
-
-There will be a separate parser from the builder.
-The parser will have a method: next() xmlToken method. It has lookahead support,
-so you can pop multiple tokens, make a determination, and push them back in the order popped.
-This will be needed to determine whether we are "nakedly" decoding a container or not.
-The stack will be implemented using a slice and push/pop happens at the [0] element.
-
-xmlToken has fields:
-  - type uint8: 0 | ElementStart | ElementEnd | AttrKey | AttrVal | Text
-  - value string
-  - ns string
-
-SEE: http://www.xml.com/pub/a/98/10/guide0.html?page=3#ENTDECL
-
-The following are skipped when parsing:
-  - External Entities (from external file)
-  - Notation Declaration e.g. <!NOTATION GIF87A SYSTEM "GIF">
-  - Entity Declarations & References
-  - XML Declaration (assume UTF-8)
-  - XML Directive i.e. <! ... >
-  - Other Declarations: Notation, etc.
-  - Comment
-  - Processing Instruction
-  - schema / DTD for validation:
-    We are not a VALIDATING parser. Validation is done elsewhere.
-    However, some parts of the DTD internal subset are used (SEE BELOW).
-    For Attribute List Declarations e.g.
-    <!ATTLIST foo:oldjoke name ID #REQUIRED label CDATA #IMPLIED status ( funny | notfunny ) 'funny' >
-    We considered using the ATTLIST to get "default" value, but not to validate the contents. (VETOED)
-
-The following XML features are supported
-  - Namespace
-  - Element
-  - Attribute
-  - cdata
-  - Unicode escape
-
-The following DTD (when as an internal sub-set) features are supported:
-  - Internal Entities e.g.
-    <!ELEMENT burns "ugorji is cool" > AND entities for the set: [<>&"']
-  - Parameter entities e.g.
-    <!ENTITY % personcontent "ugorji is cool"> <!ELEMENT burns (%personcontent;)*>
-
-At decode time, a structure containing the following is kept
-  - namespace mapping
-  - default attribute values
-  - all internal entities (<>&"' and others written in the document)
-
-When decode starts, it parses XML namespace declarations and creates a map in the
-xmlDecDriver. While parsing, that map continuously gets updated.
-The only problem happens when a namespace declaration happens on the node that it defines.
-e.g. <hn:name xmlns:hn="http://www.ugorji.net" >
-To handle this, each Element must be fully parsed at a time,
-even if it amounts to multiple tokens which are returned one at a time on request.
-
-xmlns is a special attribute name.
-  - It is used to define namespaces, including the default
-  - It is never returned as an AttrKey or AttrVal.
-  *We may decide later to allow user to use it e.g. you want to parse the xmlns mappings into a field.*
-
-Number, bool, null, mapKey, etc can all be decoded from any xmlToken.
-This accommodates map[int]string for example.
-
-It should be possible to create a schema from the types,
-or vice versa (generate types from schema with appropriate tags).
-This is however out-of-scope from this parsing project.
-
-We should write all namespace information at the first point that it is referenced in the tree,
-and use the mapping for all child nodes and attributes. This means that state is maintained
-at a point in the tree. This also means that calls to Decode or MustDecode will reset some state.
-
-When decoding, it is important to keep track of entity references and default attribute values.
-It seems these can only be stored in the DTD components. We should honor them when decoding.
-
-Configuration for XMLHandle will look like this:
-
-  XMLHandle
-    DefaultNS string
-    // Encoding:
-    NS map[string]string // ns URI to key, used for encoding
-    // Decoding: in case ENTITY declared in external schema or dtd, store info needed here
-    Entities map[string]string // map of entity rep to character
-
-
-During encode, if a namespace mapping is not defined for a namespace found on a struct,
-then we create a mapping for it using nsN (where N is 1..1000000, and doesn't conflict
-with any other namespace mapping).
-
-Note that different fields in a struct can have different namespaces.
-However, all fields will default to the namespace on the _struct field (if defined).
-
-An XML document is a name, a map of attributes and a list of children.
-Consequently, we cannot "DecodeNaked" into a map[string]interface{} (for example).
-We have to "DecodeNaked" into something that resembles XML data.
-
-To support DecodeNaked (decode into nil interface{}), we have to define some "supporting" types:
-    type Name struct { // Preferred. Less allocations due to conversions.
-      Local string
-      Space string
-    }
-    type Element struct {
-      Name Name
-      Attrs map[Name]string
-      Children []interface{} // each child is either *Element or string
-    }
-Only two "supporting" types are exposed for XML: Name and Element.
-
-// ------------------
-
-We considered 'type Name string' where Name is like "Space Local" (space-separated).
-We decided against it, because each creation of a name would lead to
-double allocation (first convert []byte to string, then concatenate them into a string).
-The benefit is that it is faster to read Attrs from a map. But given that Element is a value
-object, we want to eschew methods and have public exposed variables.
-
-We also considered the following, where xml types were not value objects, and we used
-intelligent accessor methods to extract information and for performance.
-*** WE DECIDED AGAINST THIS. ***
-    type Attr struct {
-      Name Name
-      Value string
-    }
-    // Element is a ValueObject: There are no accessor methods.
-    // Make element self-contained.
-    type Element struct {
-      Name Name
-      attrsMap map[string]string // where key is "Space Local"
-      attrs []Attr
-      childrenT []string
-      childrenE []Element
-      childrenI []int // each child is a index into T or E.
-    }
-    func (x *Element) child(i) interface{} // returns string or *Element
-
-// ------------------
-
-Per XML spec and our default handling, white space is always treated as
-insignificant between elements, except in a text node. The xml:space='preserve'
-attribute is ignored.
-
-**Note: there is no xml: namespace. The xml: attributes were defined before namespaces.**
-**So treat them as just "directives" that should be interpreted to mean something**.
-
-On encoding, we support indenting aka prettifying markup in the same way we support it for json.
-
-A document or element can only be encoded/decoded from/to a struct. In this mode:
-  - struct name maps to element name (or tag-info from _struct field)
-  - fields are mapped to child elements or attributes
-
-A map is either encoded as attributes on current element, or as a set of child elements.
-Maps are encoded as attributes iff their keys and values are primitives (number, bool, string).
-
-A list is encoded as a set of child elements.
-
-Primitives (number, bool, string) are encoded as an element, attribute or text
-depending on the context.
-
-Extensions must encode themselves as a text string.
-
-Encoding is tough, specifically when encoding mappings, because we need to encode
-as either attribute or element. To do this, we need to default to encoding as attributes,
-and then let Encoder inform the Handle when to start encoding as nodes.
-i.e. Encoder does something like:
-
-    h.EncodeMapStart()
-    h.Encode(), h.Encode(), ...
-    h.EncodeMapNotAttrSignal() // this is not a bool, because it's a signal
-    h.Encode(), h.Encode(), ...
-    h.EncodeEnd()
-
-Only XMLHandle understands this, and will set itself to start encoding as elements.
-
-This support extends to maps. For example, if a struct field is a map, and it has
-the struct tag signifying it should be attr, then all its fields are encoded as attributes.
-e.g.
-
-    type X struct {
-       M map[string]int `codec:"m,attr"` // encode keys as attributes named
-    }
-
-Question:
-  - if encoding a map, what if map keys have spaces in them???
-    Then they cannot be attributes or child elements. Error.
-
-Options to consider adding later:
-  - For attribute values, normalize by trimming beginning and ending white space,
-    and converting every white space sequence to a single space.
-  - ATTLIST restrictions are enforced.
-    e.g. default value of xml:space, skipping xml:XYZ style attributes, etc.
-  - Consider supporting NON-STRICT mode (e.g. to handle HTML parsing).
-    Some elements e.g. br, hr, etc need not close and should be auto-closed
-    ... (see http://www.w3.org/TR/html4/loose.dtd)
-    An expansive set of entities are pre-defined.
-  - Have easy way to create a HTML parser:
-    add a HTML() method to XMLHandle, that will set Strict=false, specify AutoClose,
-    and add HTML Entities to the list.
-  - Support validating element/attribute XMLName before writing it.
-    Keep this behind a flag, which is set to false by default (for performance).
-    type XMLHandle struct {
-      CheckName bool
-    }
-
-Misc:
-
-ROADMAP (1 weeks):
-  - build encoder (1 day)
-  - build decoder (based off xmlParser) (1 day)
-  - implement xmlParser (2 days).
-    Look at encoding/xml for inspiration.
-  - integrate and TEST (1 days)
-  - write article and post it (1 day)
-
-// ---------- MORE NOTES FROM 2017-11-30 ------------
-
-when parsing
-- parse the attributes first
-- then parse the nodes
-
-basically:
-- if encoding a field: we use the field name for the wrapper
-- if encoding a non-field, then just use the element type name
-
-  map[string]string ==> <map><key>abc</key><value>val</value></map>... or
-                        <map key="abc">val</map>... OR
-                        <key1>val1</key1><key2>val2</key2>...                <- PREFERED
-  []string  ==> <string>v1</string><string>v2</string>...
-  string v1 ==> <string>v1</string>
-  bool true ==> <bool>true</bool>
-  float 1.0 ==> <float>1.0</float>
-  ...
-
-  F1 map[string]string ==> <F1><key>abc</key><value>val</value></F1>... OR
-                           <F1 key="abc">val</F1>... OR
-                           <F1><abc>val</abc>...</F1>                        <- PREFERED
-  F2 []string          ==> <F2>v1</F2><F2>v2</F2>...
-  F3 bool              ==> <F3>true</F3>
-  ...
-
-- a scalar is encoded as:
-  (value) of type T  ==> <T><value/></T>
-  (value) of field F ==> <F><value/></F>
-- A kv-pair is encoded as:
-  (key,value) ==> <map><key><value/></key></map> OR <map key="value">
-  (key,value) of field F ==> <F><key><value/></key></F> OR <F key="value">
-- A map or struct is just a list of kv-pairs
-- A list is encoded as sequences of same node e.g.
-  <F1 key1="value11">
-  <F1 key2="value12">
-  <F2>value21</F2>
-  <F2>value22</F2>
-- we may have to singularize the field name, when entering into xml,
-  and pluralize them when encoding.
-- bi-directional encode->decode->encode is not a MUST.
-  even encoding/xml cannot decode correctly what was encoded:
-
-  see https://play.golang.org/p/224V_nyhMS
-  func main() {
-	fmt.Println("Hello, playground")
-	v := []interface{}{"hello", 1, true, nil, time.Now()}
-	s, err := xml.Marshal(v)
-	fmt.Printf("err: %v, \ns: %s\n", err, s)
-	var v2 []interface{}
-	err = xml.Unmarshal(s, &v2)
-	fmt.Printf("err: %v, \nv2: %v\n", err, v2)
-	type T struct {
-	    V []interface{}
-	}
-	v3 := T{V: v}
-	s, err = xml.Marshal(v3)
-	fmt.Printf("err: %v, \ns: %s\n", err, s)
-	var v4 T
-	err = xml.Unmarshal(s, &v4)
-	fmt.Printf("err: %v, \nv4: %v\n", err, v4)
-  }
-  Output:
-    err: <nil>,
-    s: <string>hello</string><int>1</int><bool>true</bool><Time>2009-11-10T23:00:00Z</Time>
-    err: <nil>,
-    v2: [<nil>]
-    err: <nil>,
-    s: <T><V>hello</V><V>1</V><V>true</V><V>2009-11-10T23:00:00Z</V></T>
-    err: <nil>,
-    v4: {[<nil> <nil> <nil> <nil>]}
--
-*/
-
-// ----------- PARSER  -------------------
-
-type xmlTokenType uint8
-
-const (
-	_ xmlTokenType = iota << 1
-	xmlTokenElemStart
-	xmlTokenElemEnd
-	xmlTokenAttrKey
-	xmlTokenAttrVal
-	xmlTokenText
-)
-
-type xmlToken struct {
-	Type      xmlTokenType
-	Value     string
-	Namespace string // blank for AttrVal and Text
-}
-
-type xmlParser struct {
-	r    decReader
-	toks []xmlToken // list of tokens.
-	ptr  int        // ptr into the toks slice
-	done bool       // nothing else to parse. r now returns EOF.
-}
-
-func (x *xmlParser) next() (t *xmlToken) {
-	// once x.done, or x.ptr == len(x.toks) == 0, then return nil (to signify finish)
-	if !x.done && len(x.toks) == 0 {
-		x.nextTag()
-	}
-	// parses one element at a time (into possible many tokens)
-	if x.ptr < len(x.toks) {
-		t = &(x.toks[x.ptr])
-		x.ptr++
-		if x.ptr == len(x.toks) {
-			x.ptr = 0
-			x.toks = x.toks[:0]
-		}
-	}
-	return
-}
-
-// nextTag will parses the next element and fill up toks.
-// It set done flag if/once EOF is reached.
-func (x *xmlParser) nextTag() {
-	// TODO: implement.
-}
-
-// ----------- ENCODER -------------------
-
-type xmlEncDriver struct {
-	e  *Encoder
-	w  encWriter
-	h  *XMLHandle
-	b  [64]byte // scratch
-	bs []byte   // scratch
-	// s  jsonStack
-	noBuiltInTypes
-}
-
-// ----------- DECODER -------------------
-
-type xmlDecDriver struct {
-	d    *Decoder
-	h    *XMLHandle
-	r    decReader // *bytesDecReader decReader
-	ct   valueType // container type. one of unset, array or map.
-	bstr [8]byte   // scratch used for string \UXXX parsing
-	b    [64]byte  // scratch
-
-	// wsSkipped bool // whitespace skipped
-
-	// s jsonStack
-
-	noBuiltInTypes
-}
-
-// DecodeNaked will decode into an XMLNode
-
-// XMLName is a value object representing a namespace-aware NAME
-type XMLName struct {
-	Local string
-	Space string
-}
-
-// XMLNode represents a "union" of the different types of XML Nodes.
-// Only one of fields (Text or *Element) is set.
-type XMLNode struct {
-	Element *Element
-	Text    string
-}
-
-// XMLElement is a value object representing an fully-parsed XML element.
-type XMLElement struct {
-	Name  Name
-	Attrs map[XMLName]string
-	// Children is a list of child nodes, each being a *XMLElement or string
-	Children []XMLNode
-}
-
-// ----------- HANDLE  -------------------
-
-type XMLHandle struct {
-	BasicHandle
-	textEncodingType
-
-	DefaultNS string
-	NS        map[string]string // ns URI to key, for encoding
-	Entities  map[string]string // entity representation to string, for encoding.
-}
-
-func (h *XMLHandle) newEncDriver(e *Encoder) encDriver {
-	return &xmlEncDriver{e: e, w: e.w, h: h}
-}
-
-func (h *XMLHandle) newDecDriver(d *Decoder) decDriver {
-	// d := xmlDecDriver{r: r.(*bytesDecReader), h: h}
-	hd := xmlDecDriver{d: d, r: d.r, h: h}
-	hd.n.bytes = d.b[:]
-	return &hd
-}
-
-func (h *XMLHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
-	return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
-}
-
-var _ decDriver = (*xmlDecDriver)(nil)
-var _ encDriver = (*xmlEncDriver)(nil)
diff --git a/vendor/github.com/xiang90/probing/.gitignore b/vendor/github.com/xiang90/probing/.gitignore
deleted file mode 100644
index daf913b..0000000
--- a/vendor/github.com/xiang90/probing/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
-*.prof
diff --git a/vendor/github.com/xiang90/probing/LICENSE b/vendor/github.com/xiang90/probing/LICENSE
deleted file mode 100644
index cde8b8b..0000000
--- a/vendor/github.com/xiang90/probing/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Xiang Li
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
diff --git a/vendor/github.com/xiang90/probing/README.md b/vendor/github.com/xiang90/probing/README.md
deleted file mode 100644
index 2ff6820..0000000
--- a/vendor/github.com/xiang90/probing/README.md
+++ /dev/null
@@ -1,39 +0,0 @@
-## Getting Started
-
-### Install the handler
-
-We first need to serve the probing HTTP handler.
-
-```go
-    http.HandleFunc("/health", probing.NewHandler())
-    err := http.ListenAndServe(":12345", nil)
-	if err != nil {
-		log.Fatal("ListenAndServe: ", err)
-	}
-```
-
-### Start to probe
-
-Now we can start to probe the endpoint.
-
-``` go
-    id := "example"
-    probingInterval = 5 * time.Second
-    url := "http://example.com:12345/health"
-    p.AddHTTP(id, probingInterval, url)
-
-	time.Sleep(13 * time.Second)
-	status, err := p.Status(id)
- 	fmt.Printf("Total Probing: %d, Total Loss: %d, Estimated RTT: %v, Estimated Clock Difference: %v\n",
-		status.Total(), status.Loss(), status.SRTT(), status.ClockDiff())
-	// Total Probing: 2, Total Loss: 0, Estimated RTT: 320.771µs, Estimated Clock Difference: -35.869µs
-```
-
-### TODOs:
-
-- TCP probing
-- UDP probing
-- Gossip based probing
-- More accurate RTT estimation
-- More accurate Clock difference estimation
-- Use a clock interface rather than the real clock
diff --git a/vendor/github.com/xiang90/probing/prober.go b/vendor/github.com/xiang90/probing/prober.go
deleted file mode 100644
index c917cfd..0000000
--- a/vendor/github.com/xiang90/probing/prober.go
+++ /dev/null
@@ -1,134 +0,0 @@
-package probing
-
-import (
-	"encoding/json"
-	"errors"
-	"net/http"
-	"sync"
-	"time"
-)
-
-var (
-	ErrNotFound = errors.New("probing: id not found")
-	ErrExist    = errors.New("probing: id exists")
-)
-
-type Prober interface {
-	AddHTTP(id string, probingInterval time.Duration, endpoints []string) error
-	Remove(id string) error
-	RemoveAll()
-	Reset(id string) error
-	Status(id string) (Status, error)
-}
-
-type prober struct {
-	mu      sync.Mutex
-	targets map[string]*status
-	tr      http.RoundTripper
-}
-
-func NewProber(tr http.RoundTripper) Prober {
-	p := &prober{targets: make(map[string]*status)}
-	if tr == nil {
-		p.tr = http.DefaultTransport
-	} else {
-		p.tr = tr
-	}
-	return p
-}
-
-func (p *prober) AddHTTP(id string, probingInterval time.Duration, endpoints []string) error {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	if _, ok := p.targets[id]; ok {
-		return ErrExist
-	}
-
-	s := &status{stopC: make(chan struct{})}
-	p.targets[id] = s
-
-	ticker := time.NewTicker(probingInterval)
-
-	go func() {
-		pinned := 0
-		for {
-			select {
-			case <-ticker.C:
-				start := time.Now()
-				req, err := http.NewRequest("GET", endpoints[pinned], nil)
-				if err != nil {
-					panic(err)
-				}
-				resp, err := p.tr.RoundTrip(req)
-				if err != nil {
-					s.recordFailure(err)
-					pinned = (pinned + 1) % len(endpoints)
-					continue
-				}
-
-				var hh Health
-				d := json.NewDecoder(resp.Body)
-				err = d.Decode(&hh)
-				resp.Body.Close()
-				if err != nil || !hh.OK {
-					s.recordFailure(err)
-					pinned = (pinned + 1) % len(endpoints)
-					continue
-				}
-
-				s.record(time.Since(start), hh.Now)
-			case <-s.stopC:
-				ticker.Stop()
-				return
-			}
-		}
-	}()
-
-	return nil
-}
-
-func (p *prober) Remove(id string) error {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-
-	s, ok := p.targets[id]
-	if !ok {
-		return ErrNotFound
-	}
-	close(s.stopC)
-	delete(p.targets, id)
-	return nil
-}
-
-func (p *prober) RemoveAll() {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-
-	for _, s := range p.targets {
-		close(s.stopC)
-	}
-	p.targets = make(map[string]*status)
-}
-
-func (p *prober) Reset(id string) error {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-
-	s, ok := p.targets[id]
-	if !ok {
-		return ErrNotFound
-	}
-	s.reset()
-	return nil
-}
-
-func (p *prober) Status(id string) (Status, error) {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-
-	s, ok := p.targets[id]
-	if !ok {
-		return nil, ErrNotFound
-	}
-	return s, nil
-}
diff --git a/vendor/github.com/xiang90/probing/server.go b/vendor/github.com/xiang90/probing/server.go
deleted file mode 100644
index 0e7b797..0000000
--- a/vendor/github.com/xiang90/probing/server.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package probing
-
-import (
-	"encoding/json"
-	"net/http"
-	"time"
-)
-
-func NewHandler() http.Handler {
-	return &httpHealth{}
-}
-
-type httpHealth struct {
-}
-
-type Health struct {
-	OK  bool
-	Now time.Time
-}
-
-func (h *httpHealth) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	health := Health{OK: true, Now: time.Now()}
-	e := json.NewEncoder(w)
-	e.Encode(health)
-}
diff --git a/vendor/github.com/xiang90/probing/status.go b/vendor/github.com/xiang90/probing/status.go
deleted file mode 100644
index bb5f659..0000000
--- a/vendor/github.com/xiang90/probing/status.go
+++ /dev/null
@@ -1,108 +0,0 @@
-package probing
-
-import (
-	"sync"
-	"time"
-)
-
-var (
-	// weight factor
-	α = 0.125
-)
-
-type Status interface {
-	Total() int64
-	Loss() int64
-	Health() bool
-	Err() error
-	// Estimated smoothed round trip time
-	SRTT() time.Duration
-	// Estimated clock difference
-	ClockDiff() time.Duration
-	StopNotify() <-chan struct{}
-}
-
-type status struct {
-	mu        sync.Mutex
-	srtt      time.Duration
-	total     int64
-	loss      int64
-	health    bool
-	err       error
-	clockdiff time.Duration
-	stopC     chan struct{}
-}
-
-// SRTT = (1-α) * SRTT + α * RTT
-func (s *status) SRTT() time.Duration {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.srtt
-}
-
-func (s *status) Total() int64 {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.total
-}
-
-func (s *status) Loss() int64 {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.loss
-}
-
-func (s *status) Health() bool {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.health
-}
-
-func (s *status) Err() error {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.err
-}
-
-func (s *status) ClockDiff() time.Duration {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.clockdiff
-}
-
-func (s *status) StopNotify() <-chan struct{} {
-	return s.stopC
-}
-
-func (s *status) record(rtt time.Duration, when time.Time) {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	s.total += 1
-	s.health = true
-	s.srtt = time.Duration((1-α)*float64(s.srtt) + α*float64(rtt))
-	s.clockdiff = time.Now().Sub(when) - s.srtt/2
-	s.err = nil
-}
-
-func (s *status) recordFailure(err error) {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	s.total++
-	s.health = false
-	s.loss += 1
-	s.err = err
-}
-
-func (s *status) reset() {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	s.srtt = 0
-	s.total = 0
-	s.loss = 0
-	s.health = false
-	s.clockdiff = 0
-	s.err = nil
-}
diff --git a/vendor/golang.org/x/crypto/bcrypt/base64.go b/vendor/golang.org/x/crypto/bcrypt/base64.go
deleted file mode 100644
index fc31160..0000000
--- a/vendor/golang.org/x/crypto/bcrypt/base64.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bcrypt
-
-import "encoding/base64"
-
-const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
-
-var bcEncoding = base64.NewEncoding(alphabet)
-
-func base64Encode(src []byte) []byte {
-	n := bcEncoding.EncodedLen(len(src))
-	dst := make([]byte, n)
-	bcEncoding.Encode(dst, src)
-	for dst[n-1] == '=' {
-		n--
-	}
-	return dst[:n]
-}
-
-func base64Decode(src []byte) ([]byte, error) {
-	numOfEquals := 4 - (len(src) % 4)
-	for i := 0; i < numOfEquals; i++ {
-		src = append(src, '=')
-	}
-
-	dst := make([]byte, bcEncoding.DecodedLen(len(src)))
-	n, err := bcEncoding.Decode(dst, src)
-	if err != nil {
-		return nil, err
-	}
-	return dst[:n], nil
-}
diff --git a/vendor/golang.org/x/crypto/bcrypt/bcrypt.go b/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
deleted file mode 100644
index aeb73f8..0000000
--- a/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
-// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
-package bcrypt // import "golang.org/x/crypto/bcrypt"
-
-// The code is a port of Provos and Mazières's C implementation.
-import (
-	"crypto/rand"
-	"crypto/subtle"
-	"errors"
-	"fmt"
-	"io"
-	"strconv"
-
-	"golang.org/x/crypto/blowfish"
-)
-
-const (
-	MinCost     int = 4  // the minimum allowable cost as passed in to GenerateFromPassword
-	MaxCost     int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
-	DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
-)
-
-// The error returned from CompareHashAndPassword when a password and hash do
-// not match.
-var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
-
-// The error returned from CompareHashAndPassword when a hash is too short to
-// be a bcrypt hash.
-var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
-
-// The error returned from CompareHashAndPassword when a hash was created with
-// a bcrypt algorithm newer than this implementation.
-type HashVersionTooNewError byte
-
-func (hv HashVersionTooNewError) Error() string {
-	return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
-}
-
-// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
-type InvalidHashPrefixError byte
-
-func (ih InvalidHashPrefixError) Error() string {
-	return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
-}
-
-type InvalidCostError int
-
-func (ic InvalidCostError) Error() string {
-	return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
-}
-
-const (
-	majorVersion       = '2'
-	minorVersion       = 'a'
-	maxSaltSize        = 16
-	maxCryptedHashSize = 23
-	encodedSaltSize    = 22
-	encodedHashSize    = 31
-	minHashSize        = 59
-)
-
-// magicCipherData is an IV for the 64 Blowfish encryption calls in
-// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
-var magicCipherData = []byte{
-	0x4f, 0x72, 0x70, 0x68,
-	0x65, 0x61, 0x6e, 0x42,
-	0x65, 0x68, 0x6f, 0x6c,
-	0x64, 0x65, 0x72, 0x53,
-	0x63, 0x72, 0x79, 0x44,
-	0x6f, 0x75, 0x62, 0x74,
-}
-
-type hashed struct {
-	hash  []byte
-	salt  []byte
-	cost  int // allowed range is MinCost to MaxCost
-	major byte
-	minor byte
-}
-
-// GenerateFromPassword returns the bcrypt hash of the password at the given
-// cost. If the cost given is less than MinCost, the cost will be set to
-// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
-// to compare the returned hashed password with its cleartext version.
-func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
-	p, err := newFromPassword(password, cost)
-	if err != nil {
-		return nil, err
-	}
-	return p.Hash(), nil
-}
-
-// CompareHashAndPassword compares a bcrypt hashed password with its possible
-// plaintext equivalent. Returns nil on success, or an error on failure.
-func CompareHashAndPassword(hashedPassword, password []byte) error {
-	p, err := newFromHash(hashedPassword)
-	if err != nil {
-		return err
-	}
-
-	otherHash, err := bcrypt(password, p.cost, p.salt)
-	if err != nil {
-		return err
-	}
-
-	otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
-	if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
-		return nil
-	}
-
-	return ErrMismatchedHashAndPassword
-}
-
-// Cost returns the hashing cost used to create the given hashed
-// password. When, in the future, the hashing cost of a password system needs
-// to be increased in order to adjust for greater computational power, this
-// function allows one to establish which passwords need to be updated.
-func Cost(hashedPassword []byte) (int, error) {
-	p, err := newFromHash(hashedPassword)
-	if err != nil {
-		return 0, err
-	}
-	return p.cost, nil
-}
-
-func newFromPassword(password []byte, cost int) (*hashed, error) {
-	if cost < MinCost {
-		cost = DefaultCost
-	}
-	p := new(hashed)
-	p.major = majorVersion
-	p.minor = minorVersion
-
-	err := checkCost(cost)
-	if err != nil {
-		return nil, err
-	}
-	p.cost = cost
-
-	unencodedSalt := make([]byte, maxSaltSize)
-	_, err = io.ReadFull(rand.Reader, unencodedSalt)
-	if err != nil {
-		return nil, err
-	}
-
-	p.salt = base64Encode(unencodedSalt)
-	hash, err := bcrypt(password, p.cost, p.salt)
-	if err != nil {
-		return nil, err
-	}
-	p.hash = hash
-	return p, err
-}
-
-func newFromHash(hashedSecret []byte) (*hashed, error) {
-	if len(hashedSecret) < minHashSize {
-		return nil, ErrHashTooShort
-	}
-	p := new(hashed)
-	n, err := p.decodeVersion(hashedSecret)
-	if err != nil {
-		return nil, err
-	}
-	hashedSecret = hashedSecret[n:]
-	n, err = p.decodeCost(hashedSecret)
-	if err != nil {
-		return nil, err
-	}
-	hashedSecret = hashedSecret[n:]
-
-	// The "+2" is here because we'll have to append at most 2 '=' to the salt
-	// when base64 decoding it in expensiveBlowfishSetup().
-	p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
-	copy(p.salt, hashedSecret[:encodedSaltSize])
-
-	hashedSecret = hashedSecret[encodedSaltSize:]
-	p.hash = make([]byte, len(hashedSecret))
-	copy(p.hash, hashedSecret)
-
-	return p, nil
-}
-
-func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
-	cipherData := make([]byte, len(magicCipherData))
-	copy(cipherData, magicCipherData)
-
-	c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
-	if err != nil {
-		return nil, err
-	}
-
-	for i := 0; i < 24; i += 8 {
-		for j := 0; j < 64; j++ {
-			c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
-		}
-	}
-
-	// Bug compatibility with C bcrypt implementations. We only encode 23 of
-	// the 24 bytes encrypted.
-	hsh := base64Encode(cipherData[:maxCryptedHashSize])
-	return hsh, nil
-}
-
-func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
-	csalt, err := base64Decode(salt)
-	if err != nil {
-		return nil, err
-	}
-
-	// Bug compatibility with C bcrypt implementations. They use the trailing
-	// NULL in the key string during expansion.
-	// We copy the key to prevent changing the underlying array.
-	ckey := append(key[:len(key):len(key)], 0)
-
-	c, err := blowfish.NewSaltedCipher(ckey, csalt)
-	if err != nil {
-		return nil, err
-	}
-
-	var i, rounds uint64
-	rounds = 1 << cost
-	for i = 0; i < rounds; i++ {
-		blowfish.ExpandKey(ckey, c)
-		blowfish.ExpandKey(csalt, c)
-	}
-
-	return c, nil
-}
-
-func (p *hashed) Hash() []byte {
-	arr := make([]byte, 60)
-	arr[0] = '$'
-	arr[1] = p.major
-	n := 2
-	if p.minor != 0 {
-		arr[2] = p.minor
-		n = 3
-	}
-	arr[n] = '$'
-	n++
-	copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
-	n += 2
-	arr[n] = '$'
-	n++
-	copy(arr[n:], p.salt)
-	n += encodedSaltSize
-	copy(arr[n:], p.hash)
-	n += encodedHashSize
-	return arr[:n]
-}
-
-func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
-	if sbytes[0] != '$' {
-		return -1, InvalidHashPrefixError(sbytes[0])
-	}
-	if sbytes[1] > majorVersion {
-		return -1, HashVersionTooNewError(sbytes[1])
-	}
-	p.major = sbytes[1]
-	n := 3
-	if sbytes[2] != '$' {
-		p.minor = sbytes[2]
-		n++
-	}
-	return n, nil
-}
-
-// sbytes should begin where decodeVersion left off.
-func (p *hashed) decodeCost(sbytes []byte) (int, error) {
-	cost, err := strconv.Atoi(string(sbytes[0:2]))
-	if err != nil {
-		return -1, err
-	}
-	err = checkCost(cost)
-	if err != nil {
-		return -1, err
-	}
-	p.cost = cost
-	return 3, nil
-}
-
-func (p *hashed) String() string {
-	return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
-}
-
-func checkCost(cost int) error {
-	if cost < MinCost || cost > MaxCost {
-		return InvalidCostError(cost)
-	}
-	return nil
-}
diff --git a/vendor/golang.org/x/crypto/blowfish/block.go b/vendor/golang.org/x/crypto/blowfish/block.go
deleted file mode 100644
index 9d80f19..0000000
--- a/vendor/golang.org/x/crypto/blowfish/block.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package blowfish
-
-// getNextWord returns the next big-endian uint32 value from the byte slice
-// at the given position in a circular manner, updating the position.
-func getNextWord(b []byte, pos *int) uint32 {
-	var w uint32
-	j := *pos
-	for i := 0; i < 4; i++ {
-		w = w<<8 | uint32(b[j])
-		j++
-		if j >= len(b) {
-			j = 0
-		}
-	}
-	*pos = j
-	return w
-}
-
-// ExpandKey performs a key expansion on the given *Cipher. Specifically, it
-// performs the Blowfish algorithm's key schedule which sets up the *Cipher's
-// pi and substitution tables for calls to Encrypt. This is used, primarily,
-// by the bcrypt package to reuse the Blowfish key schedule during its
-// set up. It's unlikely that you need to use this directly.
-func ExpandKey(key []byte, c *Cipher) {
-	j := 0
-	for i := 0; i < 18; i++ {
-		// Using inlined getNextWord for performance.
-		var d uint32
-		for k := 0; k < 4; k++ {
-			d = d<<8 | uint32(key[j])
-			j++
-			if j >= len(key) {
-				j = 0
-			}
-		}
-		c.p[i] ^= d
-	}
-
-	var l, r uint32
-	for i := 0; i < 18; i += 2 {
-		l, r = encryptBlock(l, r, c)
-		c.p[i], c.p[i+1] = l, r
-	}
-
-	for i := 0; i < 256; i += 2 {
-		l, r = encryptBlock(l, r, c)
-		c.s0[i], c.s0[i+1] = l, r
-	}
-	for i := 0; i < 256; i += 2 {
-		l, r = encryptBlock(l, r, c)
-		c.s1[i], c.s1[i+1] = l, r
-	}
-	for i := 0; i < 256; i += 2 {
-		l, r = encryptBlock(l, r, c)
-		c.s2[i], c.s2[i+1] = l, r
-	}
-	for i := 0; i < 256; i += 2 {
-		l, r = encryptBlock(l, r, c)
-		c.s3[i], c.s3[i+1] = l, r
-	}
-}
-
-// This is similar to ExpandKey, but folds the salt during the key
-// schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero
-// salt passed in, reusing ExpandKey turns out to be a place of inefficiency
-// and specializing it here is useful.
-func expandKeyWithSalt(key []byte, salt []byte, c *Cipher) {
-	j := 0
-	for i := 0; i < 18; i++ {
-		c.p[i] ^= getNextWord(key, &j)
-	}
-
-	j = 0
-	var l, r uint32
-	for i := 0; i < 18; i += 2 {
-		l ^= getNextWord(salt, &j)
-		r ^= getNextWord(salt, &j)
-		l, r = encryptBlock(l, r, c)
-		c.p[i], c.p[i+1] = l, r
-	}
-
-	for i := 0; i < 256; i += 2 {
-		l ^= getNextWord(salt, &j)
-		r ^= getNextWord(salt, &j)
-		l, r = encryptBlock(l, r, c)
-		c.s0[i], c.s0[i+1] = l, r
-	}
-
-	for i := 0; i < 256; i += 2 {
-		l ^= getNextWord(salt, &j)
-		r ^= getNextWord(salt, &j)
-		l, r = encryptBlock(l, r, c)
-		c.s1[i], c.s1[i+1] = l, r
-	}
-
-	for i := 0; i < 256; i += 2 {
-		l ^= getNextWord(salt, &j)
-		r ^= getNextWord(salt, &j)
-		l, r = encryptBlock(l, r, c)
-		c.s2[i], c.s2[i+1] = l, r
-	}
-
-	for i := 0; i < 256; i += 2 {
-		l ^= getNextWord(salt, &j)
-		r ^= getNextWord(salt, &j)
-		l, r = encryptBlock(l, r, c)
-		c.s3[i], c.s3[i+1] = l, r
-	}
-}
-
-func encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
-	xl, xr := l, r
-	xl ^= c.p[0]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[1]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[2]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[3]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[4]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[5]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[6]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[7]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[8]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[9]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[10]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[11]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[12]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[13]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[14]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[15]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[16]
-	xr ^= c.p[17]
-	return xr, xl
-}
-
-func decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
-	xl, xr := l, r
-	xl ^= c.p[17]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[16]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[15]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[14]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[13]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[12]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[11]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[10]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[9]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[8]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[7]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[6]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[5]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[4]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[3]
-	xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[2]
-	xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[1]
-	xr ^= c.p[0]
-	return xr, xl
-}
diff --git a/vendor/golang.org/x/crypto/blowfish/cipher.go b/vendor/golang.org/x/crypto/blowfish/cipher.go
deleted file mode 100644
index 2641dad..0000000
--- a/vendor/golang.org/x/crypto/blowfish/cipher.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm.
-package blowfish // import "golang.org/x/crypto/blowfish"
-
-// The code is a port of Bruce Schneier's C implementation.
-// See https://www.schneier.com/blowfish.html.
-
-import "strconv"
-
-// The Blowfish block size in bytes.
-const BlockSize = 8
-
-// A Cipher is an instance of Blowfish encryption using a particular key.
-type Cipher struct {
-	p              [18]uint32
-	s0, s1, s2, s3 [256]uint32
-}
-
-type KeySizeError int
-
-func (k KeySizeError) Error() string {
-	return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k))
-}
-
-// NewCipher creates and returns a Cipher.
-// The key argument should be the Blowfish key, from 1 to 56 bytes.
-func NewCipher(key []byte) (*Cipher, error) {
-	var result Cipher
-	if k := len(key); k < 1 || k > 56 {
-		return nil, KeySizeError(k)
-	}
-	initCipher(&result)
-	ExpandKey(key, &result)
-	return &result, nil
-}
-
-// NewSaltedCipher creates a returns a Cipher that folds a salt into its key
-// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is
-// sufficient and desirable. For bcrypt compatibility, the key can be over 56
-// bytes.
-func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
-	if len(salt) == 0 {
-		return NewCipher(key)
-	}
-	var result Cipher
-	if k := len(key); k < 1 {
-		return nil, KeySizeError(k)
-	}
-	initCipher(&result)
-	expandKeyWithSalt(key, salt, &result)
-	return &result, nil
-}
-
-// BlockSize returns the Blowfish block size, 8 bytes.
-// It is necessary to satisfy the Block interface in the
-// package "crypto/cipher".
-func (c *Cipher) BlockSize() int { return BlockSize }
-
-// Encrypt encrypts the 8-byte buffer src using the key k
-// and stores the result in dst.
-// Note that for amounts of data larger than a block,
-// it is not safe to just call Encrypt on successive blocks;
-// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
-func (c *Cipher) Encrypt(dst, src []byte) {
-	l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
-	r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
-	l, r = encryptBlock(l, r, c)
-	dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
-	dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
-}
-
-// Decrypt decrypts the 8-byte buffer src using the key k
-// and stores the result in dst.
-func (c *Cipher) Decrypt(dst, src []byte) {
-	l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
-	r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
-	l, r = decryptBlock(l, r, c)
-	dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
-	dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
-}
-
-func initCipher(c *Cipher) {
-	copy(c.p[0:], p[0:])
-	copy(c.s0[0:], s0[0:])
-	copy(c.s1[0:], s1[0:])
-	copy(c.s2[0:], s2[0:])
-	copy(c.s3[0:], s3[0:])
-}
diff --git a/vendor/golang.org/x/crypto/blowfish/const.go b/vendor/golang.org/x/crypto/blowfish/const.go
deleted file mode 100644
index d040775..0000000
--- a/vendor/golang.org/x/crypto/blowfish/const.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The startup permutation array and substitution boxes.
-// They are the hexadecimal digits of PI; see:
-// https://www.schneier.com/code/constants.txt.
-
-package blowfish
-
-var s0 = [256]uint32{
-	0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
-	0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
-	0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
-	0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
-	0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
-	0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
-	0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
-	0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
-	0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
-	0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
-	0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
-	0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
-	0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
-	0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
-	0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
-	0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
-	0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
-	0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
-	0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
-	0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
-	0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
-	0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
-	0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
-	0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
-	0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
-	0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
-	0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
-	0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
-	0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
-	0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
-	0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
-	0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
-	0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
-	0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
-	0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
-	0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
-	0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
-	0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
-	0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
-	0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
-	0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
-	0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
-	0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
-}
-
-var s1 = [256]uint32{
-	0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
-	0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
-	0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
-	0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
-	0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
-	0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
-	0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
-	0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
-	0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
-	0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
-	0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
-	0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
-	0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
-	0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
-	0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
-	0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
-	0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
-	0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
-	0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
-	0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
-	0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
-	0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
-	0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
-	0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
-	0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
-	0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
-	0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
-	0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
-	0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
-	0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
-	0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
-	0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
-	0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
-	0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
-	0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
-	0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
-	0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
-	0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
-	0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
-	0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
-	0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
-	0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
-	0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
-}
-
-var s2 = [256]uint32{
-	0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
-	0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
-	0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
-	0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
-	0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
-	0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
-	0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
-	0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
-	0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
-	0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
-	0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
-	0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
-	0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
-	0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
-	0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
-	0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
-	0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
-	0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
-	0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
-	0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
-	0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
-	0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
-	0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
-	0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
-	0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
-	0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
-	0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
-	0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
-	0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
-	0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
-	0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
-	0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
-	0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
-	0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
-	0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
-	0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
-	0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
-	0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
-	0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
-	0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
-	0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
-	0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
-	0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
-}
-
-var s3 = [256]uint32{
-	0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
-	0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
-	0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
-	0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
-	0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
-	0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
-	0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
-	0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
-	0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
-	0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
-	0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
-	0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
-	0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
-	0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
-	0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
-	0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
-	0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
-	0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
-	0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
-	0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
-	0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
-	0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
-	0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
-	0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
-	0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
-	0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
-	0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
-	0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
-	0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
-	0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
-	0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
-	0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
-	0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
-	0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
-	0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
-	0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
-	0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
-	0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
-	0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
-	0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
-	0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
-	0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
-	0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
-}
-
-var p = [18]uint32{
-	0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
-	0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
-	0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b,
-}
diff --git a/vendor/google.golang.org/grpc/health/client.go b/vendor/google.golang.org/grpc/health/client.go
deleted file mode 100644
index e15f04c..0000000
--- a/vendor/google.golang.org/grpc/health/client.go
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *
- * Copyright 2018 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package health
-
-import (
-	"context"
-	"fmt"
-	"io"
-	"time"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	healthpb "google.golang.org/grpc/health/grpc_health_v1"
-	"google.golang.org/grpc/internal"
-	"google.golang.org/grpc/internal/backoff"
-	"google.golang.org/grpc/status"
-)
-
-const maxDelay = 120 * time.Second
-
-var backoffStrategy = backoff.Exponential{MaxDelay: maxDelay}
-var backoffFunc = func(ctx context.Context, retries int) bool {
-	d := backoffStrategy.Backoff(retries)
-	timer := time.NewTimer(d)
-	select {
-	case <-timer.C:
-		return true
-	case <-ctx.Done():
-		timer.Stop()
-		return false
-	}
-}
-
-func init() {
-	internal.HealthCheckFunc = clientHealthCheck
-}
-
-func clientHealthCheck(ctx context.Context, newStream func() (interface{}, error), reportHealth func(bool), service string) error {
-	tryCnt := 0
-
-retryConnection:
-	for {
-		// Backs off if the connection has failed in some way without receiving a message in the previous retry.
-		if tryCnt > 0 && !backoffFunc(ctx, tryCnt-1) {
-			return nil
-		}
-		tryCnt++
-
-		if ctx.Err() != nil {
-			return nil
-		}
-		rawS, err := newStream()
-		if err != nil {
-			continue retryConnection
-		}
-
-		s, ok := rawS.(grpc.ClientStream)
-		// Ideally, this should never happen. But if it happens, the server is marked as healthy for LBing purposes.
-		if !ok {
-			reportHealth(true)
-			return fmt.Errorf("newStream returned %v (type %T); want grpc.ClientStream", rawS, rawS)
-		}
-
-		if err = s.SendMsg(&healthpb.HealthCheckRequest{Service: service}); err != nil && err != io.EOF {
-			// Stream should have been closed, so we can safely continue to create a new stream.
-			continue retryConnection
-		}
-		s.CloseSend()
-
-		resp := new(healthpb.HealthCheckResponse)
-		for {
-			err = s.RecvMsg(resp)
-
-			// Reports healthy for the LBing purposes if health check is not implemented in the server.
-			if status.Code(err) == codes.Unimplemented {
-				reportHealth(true)
-				return err
-			}
-
-			// Reports unhealthy if server's Watch method gives an error other than UNIMPLEMENTED.
-			if err != nil {
-				reportHealth(false)
-				continue retryConnection
-			}
-
-			// As a message has been received, removes the need for backoff for the next retry by reseting the try count.
-			tryCnt = 0
-			reportHealth(resp.Status == healthpb.HealthCheckResponse_SERVING)
-		}
-	}
-}
diff --git a/vendor/google.golang.org/grpc/health/regenerate.sh b/vendor/google.golang.org/grpc/health/regenerate.sh
deleted file mode 100755
index b11eccb..0000000
--- a/vendor/google.golang.org/grpc/health/regenerate.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-# Copyright 2018 gRPC authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -eux -o pipefail
-
-TMP=$(mktemp -d)
-
-function finish {
-  rm -rf "$TMP"
-}
-trap finish EXIT
-
-pushd "$TMP"
-mkdir -p grpc/health/v1
-curl https://raw.githubusercontent.com/grpc/grpc-proto/master/grpc/health/v1/health.proto > grpc/health/v1/health.proto
-
-protoc --go_out=plugins=grpc,paths=source_relative:. -I. grpc/health/v1/*.proto
-popd
-rm -f grpc_health_v1/*.pb.go
-cp "$TMP"/grpc/health/v1/*.pb.go grpc_health_v1/
-
diff --git a/vendor/google.golang.org/grpc/health/server.go b/vendor/google.golang.org/grpc/health/server.go
deleted file mode 100644
index c86e499..0000000
--- a/vendor/google.golang.org/grpc/health/server.go
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-//go:generate ./regenerate.sh
-
-// Package health provides a service that exposes server's health and it must be
-// imported to enable support for client-side health checks.
-package health
-
-import (
-	"context"
-	"sync"
-
-	"google.golang.org/grpc/codes"
-	healthgrpc "google.golang.org/grpc/health/grpc_health_v1"
-	healthpb "google.golang.org/grpc/health/grpc_health_v1"
-	"google.golang.org/grpc/status"
-)
-
-// Server implements `service Health`.
-type Server struct {
-	mu sync.Mutex
-	// statusMap stores the serving status of the services this Server monitors.
-	statusMap map[string]healthpb.HealthCheckResponse_ServingStatus
-	updates   map[string]map[healthgrpc.Health_WatchServer]chan healthpb.HealthCheckResponse_ServingStatus
-}
-
-// NewServer returns a new Server.
-func NewServer() *Server {
-	return &Server{
-		statusMap: map[string]healthpb.HealthCheckResponse_ServingStatus{"": healthpb.HealthCheckResponse_SERVING},
-		updates:   make(map[string]map[healthgrpc.Health_WatchServer]chan healthpb.HealthCheckResponse_ServingStatus),
-	}
-}
-
-// Check implements `service Health`.
-func (s *Server) Check(ctx context.Context, in *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	if servingStatus, ok := s.statusMap[in.Service]; ok {
-		return &healthpb.HealthCheckResponse{
-			Status: servingStatus,
-		}, nil
-	}
-	return nil, status.Error(codes.NotFound, "unknown service")
-}
-
-// Watch implements `service Health`.
-func (s *Server) Watch(in *healthpb.HealthCheckRequest, stream healthgrpc.Health_WatchServer) error {
-	service := in.Service
-	// update channel is used for getting service status updates.
-	update := make(chan healthpb.HealthCheckResponse_ServingStatus, 1)
-	s.mu.Lock()
-	// Puts the initial status to the channel.
-	if servingStatus, ok := s.statusMap[service]; ok {
-		update <- servingStatus
-	} else {
-		update <- healthpb.HealthCheckResponse_SERVICE_UNKNOWN
-	}
-
-	// Registers the update channel to the correct place in the updates map.
-	if _, ok := s.updates[service]; !ok {
-		s.updates[service] = make(map[healthgrpc.Health_WatchServer]chan healthpb.HealthCheckResponse_ServingStatus)
-	}
-	s.updates[service][stream] = update
-	defer func() {
-		s.mu.Lock()
-		delete(s.updates[service], stream)
-		s.mu.Unlock()
-	}()
-	s.mu.Unlock()
-
-	var lastSentStatus healthpb.HealthCheckResponse_ServingStatus = -1
-	for {
-		select {
-		// Status updated. Sends the up-to-date status to the client.
-		case servingStatus := <-update:
-			if lastSentStatus == servingStatus {
-				continue
-			}
-			lastSentStatus = servingStatus
-			err := stream.Send(&healthpb.HealthCheckResponse{Status: servingStatus})
-			if err != nil {
-				return status.Error(codes.Canceled, "Stream has ended.")
-			}
-		// Context done. Removes the update channel from the updates map.
-		case <-stream.Context().Done():
-			return status.Error(codes.Canceled, "Stream has ended.")
-		}
-	}
-}
-
-// SetServingStatus is called when need to reset the serving status of a service
-// or insert a new service entry into the statusMap.
-func (s *Server) SetServingStatus(service string, servingStatus healthpb.HealthCheckResponse_ServingStatus) {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	s.statusMap[service] = servingStatus
-	for _, update := range s.updates[service] {
-		// Clears previous updates, that are not sent to the client, from the channel.
-		// This can happen if the client is not reading and the server gets flow control limited.
-		select {
-		case <-update:
-		default:
-		}
-		// Puts the most recent update to the channel.
-		update <- servingStatus
-	}
-}
